mirror of
https://github.com/youwen5/iamb.git
synced 2025-08-04 11:38:28 -07:00
Compare commits
7 commits
d2b06d16ee
...
3886fdde43
Author | SHA1 | Date | |
---|---|---|---|
3886fdde43 | |||
![]() |
fed19d7a4b | ||
![]() |
ed9ee26854 | ||
![]() |
2e6c711644 | ||
![]() |
d1b03880f3 | ||
![]() |
d961fe3f7b | ||
![]() |
9e40b49e5e |
9 changed files with 76 additions and 12 deletions
|
@ -114,8 +114,6 @@ Redact the selected message with the optional reason.
|
||||||
Reply to the selected message.
|
Reply to the selected message.
|
||||||
.It Sy ":cancel"
|
.It Sy ":cancel"
|
||||||
Cancel the currently drafted message including replies.
|
Cancel the currently drafted message including replies.
|
||||||
.It Sy ":unreads clear"
|
|
||||||
Mark all unread rooms as read.
|
|
||||||
.It Sy ":upload [path]"
|
.It Sy ":upload [path]"
|
||||||
Upload an attachment and send it to the currently selected room.
|
Upload an attachment and send it to the currently selected room.
|
||||||
.El
|
.El
|
||||||
|
|
|
@ -208,6 +208,9 @@ See
|
||||||
.Sx "SORTING LISTS"
|
.Sx "SORTING LISTS"
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
|
.It Sy state_event_display
|
||||||
|
Defines whether the state events like joined or left are shown.
|
||||||
|
|
||||||
.It Sy typing_notice_send
|
.It Sy typing_notice_send
|
||||||
Defines whether or not the typing state is sent.
|
Defines whether or not the typing state is sent.
|
||||||
|
|
||||||
|
@ -231,6 +234,10 @@ Possible values are
|
||||||
Specify the width of the column where usernames are displayed in a room.
|
Specify the width of the column where usernames are displayed in a room.
|
||||||
Usernames that are too long are truncated.
|
Usernames that are too long are truncated.
|
||||||
Defaults to 30.
|
Defaults to 30.
|
||||||
|
|
||||||
|
.It Sy tabstop
|
||||||
|
Number of spaces that a <Tab> counts for.
|
||||||
|
Defaults to 4.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Ss Example 1: Avoid showing Emojis (useful for terminals w/o support)
|
.Ss Example 1: Avoid showing Emojis (useful for terminals w/o support)
|
||||||
|
|
|
@ -1361,7 +1361,9 @@ impl RoomInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !settings.tunables.typing_notice_display {
|
if !settings.tunables.typing_notice_display {
|
||||||
return area;
|
// still keep one line blank, so `render_jump_to_recent` doesn't immediately hide the
|
||||||
|
// last line in scrollback
|
||||||
|
return Rect::new(area.x, area.y, area.width, area.height - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let top = Rect::new(area.x, area.y, area.width, area.height - 1);
|
let top = Rect::new(area.x, area.y, area.width, area.height - 1);
|
||||||
|
|
|
@ -578,6 +578,7 @@ pub struct TunableValues {
|
||||||
pub image_preview: Option<ImagePreviewValues>,
|
pub image_preview: Option<ImagePreviewValues>,
|
||||||
pub user_gutter_width: usize,
|
pub user_gutter_width: usize,
|
||||||
pub external_edit_file_suffix: String,
|
pub external_edit_file_suffix: String,
|
||||||
|
pub tabstop: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize)]
|
#[derive(Clone, Default, Deserialize)]
|
||||||
|
@ -605,6 +606,7 @@ pub struct Tunables {
|
||||||
pub image_preview: Option<ImagePreview>,
|
pub image_preview: Option<ImagePreview>,
|
||||||
pub user_gutter_width: Option<usize>,
|
pub user_gutter_width: Option<usize>,
|
||||||
pub external_edit_file_suffix: Option<String>,
|
pub external_edit_file_suffix: Option<String>,
|
||||||
|
pub tabstop: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tunables {
|
impl Tunables {
|
||||||
|
@ -638,6 +640,7 @@ impl Tunables {
|
||||||
external_edit_file_suffix: self
|
external_edit_file_suffix: self
|
||||||
.external_edit_file_suffix
|
.external_edit_file_suffix
|
||||||
.or(other.external_edit_file_suffix),
|
.or(other.external_edit_file_suffix),
|
||||||
|
tabstop: self.tabstop.or(other.tabstop),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,6 +670,7 @@ impl Tunables {
|
||||||
external_edit_file_suffix: self
|
external_edit_file_suffix: self
|
||||||
.external_edit_file_suffix
|
.external_edit_file_suffix
|
||||||
.unwrap_or_else(|| ".md".to_string()),
|
.unwrap_or_else(|| ".md".to_string()),
|
||||||
|
tabstop: self.tabstop.unwrap_or(4),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -748,7 +748,7 @@ fn h2t(hdl: &Handle, state: &mut TreeGenState) -> StyleTreeChildren {
|
||||||
|
|
||||||
StyleTreeNode::Style(c, s)
|
StyleTreeNode::Style(c, s)
|
||||||
},
|
},
|
||||||
"del" | "strike" => {
|
"del" | "s" | "strike" => {
|
||||||
let c = c2t(&node.children.borrow(), state);
|
let c = c2t(&node.children.borrow(), state);
|
||||||
let s = Style::default().add_modifier(StyleModifier::CROSSED_OUT);
|
let s = Style::default().add_modifier(StyleModifier::CROSSED_OUT);
|
||||||
|
|
||||||
|
@ -1415,13 +1415,14 @@ pub mod tests {
|
||||||
let s = concat!(
|
let s = concat!(
|
||||||
"<pre><code class=\"language-rust\">",
|
"<pre><code class=\"language-rust\">",
|
||||||
"fn hello() -> usize {\n",
|
"fn hello() -> usize {\n",
|
||||||
|
" \t// weired\n",
|
||||||
" return 5;\n",
|
" return 5;\n",
|
||||||
"}\n",
|
"}\n",
|
||||||
"</code></pre>\n"
|
"</code></pre>\n"
|
||||||
);
|
);
|
||||||
let tree = parse_matrix_html(s);
|
let tree = parse_matrix_html(s);
|
||||||
let text = tree.to_text(25, Style::default(), true, &settings);
|
let text = tree.to_text(25, Style::default(), true, &settings);
|
||||||
assert_eq!(text.lines.len(), 5);
|
assert_eq!(text.lines.len(), 6);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
text.lines[0],
|
text.lines[0],
|
||||||
Line::from(vec![
|
Line::from(vec![
|
||||||
|
@ -1452,6 +1453,20 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
text.lines[2],
|
text.lines[2],
|
||||||
|
Line::from(vec![
|
||||||
|
Span::raw(line::VERTICAL),
|
||||||
|
Span::raw(" "),
|
||||||
|
Span::raw(" "),
|
||||||
|
Span::raw("/"),
|
||||||
|
Span::raw("/"),
|
||||||
|
Span::raw(" "),
|
||||||
|
Span::raw("weired"),
|
||||||
|
Span::raw(" "),
|
||||||
|
Span::raw(line::VERTICAL)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
text.lines[3],
|
||||||
Line::from(vec![
|
Line::from(vec![
|
||||||
Span::raw(line::VERTICAL),
|
Span::raw(line::VERTICAL),
|
||||||
Span::raw(" "),
|
Span::raw(" "),
|
||||||
|
@ -1464,7 +1479,7 @@ pub mod tests {
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
text.lines[3],
|
text.lines[4],
|
||||||
Line::from(vec![
|
Line::from(vec![
|
||||||
Span::raw(line::VERTICAL),
|
Span::raw(line::VERTICAL),
|
||||||
Span::raw("}"),
|
Span::raw("}"),
|
||||||
|
@ -1473,7 +1488,7 @@ pub mod tests {
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
text.lines[4],
|
text.lines[5],
|
||||||
Line::from(vec![
|
Line::from(vec![
|
||||||
Span::raw(line::BOTTOM_LEFT),
|
Span::raw(line::BOTTOM_LEFT),
|
||||||
Span::raw(line::HORIZONTAL.repeat(23)),
|
Span::raw(line::HORIZONTAL.repeat(23)),
|
||||||
|
|
|
@ -176,7 +176,9 @@ fn placeholder_frame(
|
||||||
}
|
}
|
||||||
let mut placeholder = "\u{230c}".to_string();
|
let mut placeholder = "\u{230c}".to_string();
|
||||||
placeholder.push_str(&" ".repeat(width - 2));
|
placeholder.push_str(&" ".repeat(width - 2));
|
||||||
placeholder.push_str("\u{230d}\n");
|
placeholder.push('\u{230d}');
|
||||||
|
placeholder.push_str(&"\n".repeat((height - 1) / 2));
|
||||||
|
|
||||||
if *height > 2 {
|
if *height > 2 {
|
||||||
if let Some(text) = text {
|
if let Some(text) = text {
|
||||||
if text.width() <= width - 2 {
|
if text.width() <= width - 2 {
|
||||||
|
@ -186,7 +188,7 @@ fn placeholder_frame(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
placeholder.push_str(&"\n".repeat(height - 2));
|
placeholder.push_str(&"\n".repeat(height / 2));
|
||||||
placeholder.push('\u{230e}');
|
placeholder.push('\u{230e}');
|
||||||
placeholder.push_str(&" ".repeat(width - 2));
|
placeholder.push_str(&" ".repeat(width - 2));
|
||||||
placeholder.push_str("\u{230f}\n");
|
placeholder.push_str("\u{230f}\n");
|
||||||
|
@ -1087,7 +1089,7 @@ impl Message {
|
||||||
},
|
},
|
||||||
ImageStatus::Loaded(backend) => {
|
ImageStatus::Loaded(backend) => {
|
||||||
proto = Some(backend);
|
proto = Some(backend);
|
||||||
placeholder_frame(Some("Loading..."), width, &backend.area().into())
|
placeholder_frame(Some("Cut off..."), width, &backend.area().into())
|
||||||
},
|
},
|
||||||
ImageStatus::Error(err) => Some(format!("[Image error: {err}]\n")),
|
ImageStatus::Error(err) => Some(format!("[Image error: {err}]\n")),
|
||||||
};
|
};
|
||||||
|
@ -1358,6 +1360,33 @@ pub mod tests {
|
||||||
OK
|
OK
|
||||||
|
|
||||||
⌎ ⌏
|
⌎ ⌏
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
placeholder_frame(Some("OK"), 6, &ImagePreviewSize { width: 6, height: 6 }),
|
||||||
|
pretty_frame_test(
|
||||||
|
r#"
|
||||||
|
⌌ ⌍
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
⌎ ⌏
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
placeholder_frame(Some("OK"), 6, &ImagePreviewSize { width: 6, height: 7 }),
|
||||||
|
pretty_frame_test(
|
||||||
|
r#"
|
||||||
|
⌌ ⌍
|
||||||
|
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
⌎ ⌏
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -216,6 +216,8 @@ impl<'a> TextPrinter<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tabstop = self.settings().tunables.tabstop;
|
||||||
|
|
||||||
for mut word in UnicodeSegmentation::split_word_bounds(s) {
|
for mut word in UnicodeSegmentation::split_word_bounds(s) {
|
||||||
if let "\n" | "\r\n" = word {
|
if let "\n" | "\r\n" = word {
|
||||||
if self.literal {
|
if self.literal {
|
||||||
|
@ -232,11 +234,17 @@ impl<'a> TextPrinter<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cow = if self.emoji_shortcodes() {
|
let mut cow = if self.emoji_shortcodes() {
|
||||||
Cow::Owned(replace_emojis_in_str(word))
|
Cow::Owned(replace_emojis_in_str(word))
|
||||||
} else {
|
} else {
|
||||||
Cow::Borrowed(word)
|
Cow::Borrowed(word)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if cow == "\t" {
|
||||||
|
let tablen = tabstop - (self.curr_width % tabstop);
|
||||||
|
cow = Cow::Owned(" ".repeat(tablen));
|
||||||
|
}
|
||||||
|
|
||||||
let sw = UnicodeWidthStr::width(cow.as_ref());
|
let sw = UnicodeWidthStr::width(cow.as_ref());
|
||||||
|
|
||||||
if sw > self.width {
|
if sw > self.width {
|
||||||
|
|
|
@ -199,6 +199,7 @@ pub fn mock_tunables() -> TunableValues {
|
||||||
},
|
},
|
||||||
image_preview: None,
|
image_preview: None,
|
||||||
user_gutter_width: 30,
|
user_gutter_width: 30,
|
||||||
|
tabstop: 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1571,7 +1571,7 @@ mod tests {
|
||||||
// MSG1: | XXXday, Month NN 20XX |
|
// MSG1: | XXXday, Month NN 20XX |
|
||||||
// | @user1:example.com writhe |
|
// | @user1:example.com writhe |
|
||||||
// |------------------------------------------------------------|
|
// |------------------------------------------------------------|
|
||||||
let area = Rect::new(0, 0, 60, 4);
|
let area = Rect::new(0, 0, 60, 5);
|
||||||
let mut buffer = Buffer::empty(area);
|
let mut buffer = Buffer::empty(area);
|
||||||
scrollback.draw(area, &mut buffer, true, &mut store);
|
scrollback.draw(area, &mut buffer, true, &mut store);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue