From 9e40b49e5ee761825bd07fc64e02531d1a389e69 Mon Sep 17 00:00:00 2001 From: VAWVAW Date: Tue, 17 Jun 2025 01:30:07 +0000 Subject: [PATCH 1/6] Fix display of tabs in code blocks (#463) --- docs/iamb.5 | 4 ++++ src/config.rs | 4 ++++ src/message/html.rs | 21 ++++++++++++++++++--- src/message/printer.rs | 10 +++++++++- src/tests.rs | 1 + 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/docs/iamb.5 b/docs/iamb.5 index 26fc1b7..56b0b32 100644 --- a/docs/iamb.5 +++ b/docs/iamb.5 @@ -231,6 +231,10 @@ Possible values are Specify the width of the column where usernames are displayed in a room. Usernames that are too long are truncated. Defaults to 30. + +.It Sy tabstop +Number of spaces that a counts for. +Defaults to 4. .El .Ss Example 1: Avoid showing Emojis (useful for terminals w/o support) diff --git a/src/config.rs b/src/config.rs index b712c73..1438ed7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -574,6 +574,7 @@ pub struct TunableValues { pub image_preview: Option, pub user_gutter_width: usize, pub external_edit_file_suffix: String, + pub tabstop: usize, } #[derive(Clone, Default, Deserialize)] @@ -600,6 +601,7 @@ pub struct Tunables { pub image_preview: Option, pub user_gutter_width: Option, pub external_edit_file_suffix: Option, + pub tabstop: Option, } impl Tunables { @@ -632,6 +634,7 @@ impl Tunables { external_edit_file_suffix: self .external_edit_file_suffix .or(other.external_edit_file_suffix), + tabstop: self.tabstop.or(other.tabstop), } } @@ -660,6 +663,7 @@ impl Tunables { external_edit_file_suffix: self .external_edit_file_suffix .unwrap_or_else(|| ".md".to_string()), + tabstop: self.tabstop.unwrap_or(4), } } } diff --git a/src/message/html.rs b/src/message/html.rs index 82aac65..6d4c44e 100644 --- a/src/message/html.rs +++ b/src/message/html.rs @@ -1415,13 +1415,14 @@ pub mod tests { let s = concat!( "
",
             "fn hello() -> usize {\n",
+            " \t// weired\n",
             "    return 5;\n",
             "}\n",
             "
\n" ); let tree = parse_matrix_html(s); let text = tree.to_text(25, Style::default(), true, &settings); - assert_eq!(text.lines.len(), 5); + assert_eq!(text.lines.len(), 6); assert_eq!( text.lines[0], Line::from(vec![ @@ -1452,6 +1453,20 @@ pub mod tests { ); assert_eq!( 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![ Span::raw(line::VERTICAL), Span::raw(" "), @@ -1464,7 +1479,7 @@ pub mod tests { ]) ); assert_eq!( - text.lines[3], + text.lines[4], Line::from(vec![ Span::raw(line::VERTICAL), Span::raw("}"), @@ -1473,7 +1488,7 @@ pub mod tests { ]) ); assert_eq!( - text.lines[4], + text.lines[5], Line::from(vec![ Span::raw(line::BOTTOM_LEFT), Span::raw(line::HORIZONTAL.repeat(23)), diff --git a/src/message/printer.rs b/src/message/printer.rs index d2a2dd0..3418752 100644 --- a/src/message/printer.rs +++ b/src/message/printer.rs @@ -216,6 +216,8 @@ impl<'a> TextPrinter<'a> { return; } + let tabstop = self.settings().tunables.tabstop; + for mut word in UnicodeSegmentation::split_word_bounds(s) { if let "\n" | "\r\n" = word { if self.literal { @@ -232,11 +234,17 @@ impl<'a> TextPrinter<'a> { continue; } - let cow = if self.emoji_shortcodes() { + let mut cow = if self.emoji_shortcodes() { Cow::Owned(replace_emojis_in_str(word)) } else { 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()); if sw > self.width { diff --git a/src/tests.rs b/src/tests.rs index 52cb859..3e3f825 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -198,6 +198,7 @@ pub fn mock_tunables() -> TunableValues { }, image_preview: None, user_gutter_width: 30, + tabstop: 4, } } From d961fe3f7b01d16d1709459d45d1bf6104214651 Mon Sep 17 00:00:00 2001 From: Pavlo Rudy Date: Tue, 17 Jun 2025 04:31:01 +0300 Subject: [PATCH 2/6] Document `settings.state_event_display` in manual page (#455) --- docs/iamb.5 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/iamb.5 b/docs/iamb.5 index 56b0b32..0fdab5f 100644 --- a/docs/iamb.5 +++ b/docs/iamb.5 @@ -208,6 +208,9 @@ See .Sx "SORTING LISTS" for more details. +.It Sy state_event_display +Defines whether the state events like joined or left are shown. + .It Sy typing_notice_send Defines whether or not the typing state is sent. From d1b03880f3771d5c232b2cd8be1a29d3c7e30d9c Mon Sep 17 00:00:00 2001 From: VAWVAW Date: Tue, 17 Jun 2025 01:35:38 +0000 Subject: [PATCH 3/6] Remove duplicate documentation from manpage (#454) --- docs/iamb.1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/iamb.1 b/docs/iamb.1 index 62deb4c..2487b92 100644 --- a/docs/iamb.1 +++ b/docs/iamb.1 @@ -114,8 +114,6 @@ Redact the selected message with the optional reason. Reply to the selected message. .It Sy ":cancel" Cancel the currently drafted message including replies. -.It Sy ":unreads clear" -Mark all unread rooms as read. .It Sy ":upload [path]" Upload an attachment and send it to the currently selected room. .El From 2e6c711644cd000e0256ad56974e6c8b33e8771b Mon Sep 17 00:00:00 2001 From: VAWVAW Date: Sat, 21 Jun 2025 17:43:26 +0000 Subject: [PATCH 4/6] Make scrollback display stable with `typing_notice_display = false` (#469) --- src/base.rs | 4 +++- src/windows/room/scrollback.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index 1cd3071..fdb7875 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1361,7 +1361,9 @@ impl RoomInfo { } 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); diff --git a/src/windows/room/scrollback.rs b/src/windows/room/scrollback.rs index 3d8ec7f..53da0b7 100644 --- a/src/windows/room/scrollback.rs +++ b/src/windows/room/scrollback.rs @@ -1571,7 +1571,7 @@ mod tests { // MSG1: | XXXday, Month NN 20XX | // | @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); scrollback.draw(area, &mut buffer, true, &mut store); From ed9ee26854fff6ff65da7add17061fab37ec8ad5 Mon Sep 17 00:00:00 2001 From: VAWVAW Date: Sat, 21 Jun 2025 18:22:21 +0000 Subject: [PATCH 5/6] Add missing `` tag in HTML parsing (#465) --- src/message/html.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/message/html.rs b/src/message/html.rs index 6d4c44e..8c36df7 100644 --- a/src/message/html.rs +++ b/src/message/html.rs @@ -748,7 +748,7 @@ fn h2t(hdl: &Handle, state: &mut TreeGenState) -> StyleTreeChildren { StyleTreeNode::Style(c, s) }, - "del" | "strike" => { + "del" | "s" | "strike" => { let c = c2t(&node.children.borrow(), state); let s = Style::default().add_modifier(StyleModifier::CROSSED_OUT); From fed19d7a4becd8923d4082b905cd70f08fc9dce8 Mon Sep 17 00:00:00 2001 From: VAWVAW Date: Sat, 21 Jun 2025 18:25:46 +0000 Subject: [PATCH 6/6] Improve image preview placeholder (#453) --- src/message/mod.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/message/mod.rs b/src/message/mod.rs index 4608303..e1dbedc 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -176,7 +176,9 @@ fn placeholder_frame( } let mut placeholder = "\u{230c}".to_string(); 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 let Some(text) = text { 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_str(&" ".repeat(width - 2)); placeholder.push_str("\u{230f}\n"); @@ -1087,7 +1089,7 @@ impl Message { }, ImageStatus::Loaded(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")), }; @@ -1358,6 +1360,33 @@ pub mod tests { 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 + + +⌎ ⌏ "# ) );