diff --git a/Cargo.lock b/Cargo.lock index 78afda1..dd63a0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,27 +687,11 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.26.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "crossterm_winapi", "libc", "mio", @@ -1564,7 +1548,7 @@ name = "iamb" version = "0.0.9-alpha.1" dependencies = [ "arboard", - "bitflags 1.3.2", + "bitflags 2.4.0", "chrono", "clap", "comrak", @@ -1694,6 +1678,12 @@ dependencies = [ "hashbrown 0.14.1", ] +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + [[package]] name = "inout" version = "0.1.3" @@ -1762,6 +1752,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2187,13 +2186,12 @@ dependencies = [ [[package]] name = "modalkit" version = "0.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f38eef0b4f6377e73d1082d508cae1df4d99a94d25361538131d839f292aa49" +source = "git+https://github.com/ulyssa/modalkit?rev=f9f0517ed6a6152c1eab36d2e71b11f38831d5e6#f9f0517ed6a6152c1eab36d2e71b11f38831d5e6" dependencies = [ "anymap2", "arboard", "bitflags 1.3.2", - "crossterm 0.25.0", + "crossterm", "derive_more", "intervaltree", "libc", @@ -2452,6 +2450,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pathdiff" version = "0.2.1" @@ -2676,7 +2680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -2804,13 +2808,17 @@ dependencies = [ [[package]] name = "ratatui" -version = "0.20.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829" +checksum = "2e2e4cd95294a85c3b4446e63ef054eea43e0205b1fd60120c16b74ff7ff96ad" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cassowary", - "crossterm 0.26.1", + "crossterm", + "indoc", + "itertools 0.11.0", + "paste", + "strum", "unicode-segmentation", "unicode-width", ] @@ -3473,6 +3481,28 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 813d574..297d5ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ features = ["build", "git", "gitcl",] [dependencies] arboard = "3.2.0" -bitflags = "1.3.2" +bitflags = "^2.3" chrono = "0.4" clap = {version = "~4.3", features = ["derive"]} comrak = {version = "0.18.0", features = ["shortcodes"]} @@ -54,7 +54,9 @@ url = {version = "^2.2.2", features = ["serde"]} edit = "0.1.4" [dependencies.modalkit] -version = "0.0.16" +# version = "0.0.16" +git = "https://github.com/ulyssa/modalkit" +rev = "f9f0517ed6a6152c1eab36d2e71b11f38831d5e6" [dependencies.matrix-sdk] version = "^0.6.2" diff --git a/src/base.rs b/src/base.rs index 1c3a0d2..f4f9360 100644 --- a/src/base.rs +++ b/src/base.rs @@ -76,7 +76,7 @@ use modalkit::{ tui::{ buffer::Buffer, layout::{Alignment, Rect}, - text::{Span, Spans}, + text::{Line, Span}, widgets::{Paragraph, Widget}, }, }; @@ -174,6 +174,7 @@ pub enum CreateRoomType { bitflags::bitflags! { /// Available options for newly created rooms. + #[derive(Clone, Debug, Eq, PartialEq)] pub struct CreateRoomFlags: u32 { /// No flags specified. const NONE = 0b00000000; @@ -188,6 +189,7 @@ bitflags::bitflags! { bitflags::bitflags! { /// Available options when downloading files. + #[derive(Clone, Debug, Eq, PartialEq)] pub struct DownloadFlags: u32 { /// No flags specified. const NONE = 0b00000000; @@ -701,30 +703,30 @@ impl RoomInfo { } } - fn get_typing_spans<'a>(&'a self, settings: &'a ApplicationSettings) -> Spans<'a> { + fn get_typing_spans<'a>(&'a self, settings: &'a ApplicationSettings) -> Line<'a> { let typers = self.get_typers(); let n = typers.len(); match n { - 0 => Spans(vec![]), + 0 => Line::from(vec![]), 1 => { let user = settings.get_user_span(typers[0].as_ref(), self); - Spans(vec![user, Span::from(" is typing...")]) + Line::from(vec![user, Span::from(" is typing...")]) }, 2 => { let user1 = settings.get_user_span(typers[0].as_ref(), self); let user2 = settings.get_user_span(typers[1].as_ref(), self); - Spans(vec![ + Line::from(vec![ user1, Span::raw(" and "), user2, Span::from(" are typing..."), ]) }, - n if n < 5 => Spans::from("Several people are typing..."), - _ => Spans::from("Many people are typing..."), + n if n < 5 => Line::from("Several people are typing..."), + _ => Line::from("Many people are typing..."), } } @@ -1364,19 +1366,19 @@ pub mod tests { // Nothing set. assert_eq!(info.users_typing, None); - assert_eq!(info.get_typing_spans(&settings), Spans(vec![])); + assert_eq!(info.get_typing_spans(&settings), Line::from(vec![])); // Empty typing list. info.set_typing(users0); assert!(info.users_typing.is_some()); - assert_eq!(info.get_typing_spans(&settings), Spans(vec![])); + assert_eq!(info.get_typing_spans(&settings), Line::from(vec![])); // Single user typing. info.set_typing(users1); assert!(info.users_typing.is_some()); assert_eq!( info.get_typing_spans(&settings), - Spans(vec![ + Line::from(vec![ Span::styled("@user1:example.com", user_style("@user1:example.com")), Span::from(" is typing...") ]) @@ -1387,7 +1389,7 @@ pub mod tests { assert!(info.users_typing.is_some()); assert_eq!( info.get_typing_spans(&settings), - Spans(vec![ + Line::from(vec![ Span::styled("@user1:example.com", user_style("@user1:example.com")), Span::raw(" and "), Span::styled("@user2:example.com", user_style("@user2:example.com")), @@ -1398,19 +1400,19 @@ pub mod tests { // Four users typing. info.set_typing(users4); assert!(info.users_typing.is_some()); - assert_eq!(info.get_typing_spans(&settings), Spans::from("Several people are typing...")); + assert_eq!(info.get_typing_spans(&settings), Line::from("Several people are typing...")); // Five users typing. info.set_typing(users5); assert!(info.users_typing.is_some()); - assert_eq!(info.get_typing_spans(&settings), Spans::from("Many people are typing...")); + assert_eq!(info.get_typing_spans(&settings), Line::from("Many people are typing...")); // Test that USER5 gets rendered using the configured color and name. info.set_typing(vec![TEST_USER5.clone()]); assert!(info.users_typing.is_some()); assert_eq!( info.get_typing_spans(&settings), - Spans(vec![ + Line::from(vec![ Span::styled("USER 5", user_style_from_color(Color::Black)), Span::from(" is typing...") ]) diff --git a/src/message/html.rs b/src/message/html.rs index 9f1e82c..b6cb69e 100644 --- a/src/message/html.rs +++ b/src/message/html.rs @@ -29,7 +29,7 @@ use modalkit::tui::{ layout::Alignment, style::{Color, Modifier as StyleModifier, Style}, symbols::line, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, }; use crate::{ @@ -151,8 +151,8 @@ impl Table { caption.print(&mut printer, style); for mut line in printer.finish().lines { - line.0.insert(0, Span::styled(" ", style)); - line.0.push(Span::styled(" ", style)); + line.spans.insert(0, Span::styled(" ", style)); + line.spans.push(Span::styled(" ", style)); text.lines.push(line); } } @@ -182,7 +182,7 @@ impl Table { ruler.push_str(line::VERTICAL_LEFT); } - text.lines.push(Spans(vec![Span::styled(ruler, style)])); + text.lines.push(Line::from(vec![Span::styled(ruler, style)])); let cells = cell_widths .iter() @@ -228,7 +228,7 @@ impl Table { } ruler.push_str(line::BOTTOM_RIGHT); - text.lines.push(Spans(vec![Span::styled(ruler, style)])); + text.lines.push(Line::from(vec![Span::styled(ruler, style)])); } text @@ -269,7 +269,7 @@ impl StyleTreeNode { child.print(&mut subp, style); for mut line in subp.finish() { - line.0.insert(0, Span::styled(" ", style)); + line.spans.insert(0, Span::styled(" ", style)); printer.push_line(line); } }, @@ -309,7 +309,7 @@ impl StyleTreeNode { Span::styled(" ".repeat(liw), style) }; - line.0.insert(0, leading); + line.spans.insert(0, leading); printer.push_line(line); } } @@ -336,8 +336,8 @@ impl StyleTreeNode { ); for mut line in subp.finish() { - line.0.insert(0, Span::styled(line::VERTICAL, style)); - line.0.push(Span::styled(line::VERTICAL, style)); + line.spans.insert(0, Span::styled(line::VERTICAL, style)); + line.spans.push(Span::styled(line::VERTICAL, style)); printer.push_line(line); } @@ -683,7 +683,7 @@ pub mod tests { let s = "

Header 1

"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled(" ", bold), Span::styled("Header", bold), @@ -695,7 +695,7 @@ pub mod tests { let s = "

Header 2

"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled("#", bold), Span::styled(" ", bold), @@ -708,7 +708,7 @@ pub mod tests { let s = "

Header 3

"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled("#", bold), Span::styled("#", bold), @@ -722,7 +722,7 @@ pub mod tests { let s = "

Header 4

"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled("#", bold), Span::styled("#", bold), @@ -737,7 +737,7 @@ pub mod tests { let s = "
Header 5
"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled("#", bold), Span::styled("#", bold), @@ -753,7 +753,7 @@ pub mod tests { let s = "
Header 6
"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("#", bold), Span::styled("#", bold), Span::styled("#", bold), @@ -780,7 +780,7 @@ pub mod tests { let s = "Bold!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Bold", bold), Span::styled("!", bold), space_span(15, def) @@ -789,7 +789,7 @@ pub mod tests { let s = "Bold!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Bold", bold), Span::styled("!", bold), space_span(15, def) @@ -798,7 +798,7 @@ pub mod tests { let s = "Italic!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Italic", italic), Span::styled("!", italic), space_span(13, def) @@ -807,7 +807,7 @@ pub mod tests { let s = "Italic!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Italic", italic), Span::styled("!", italic), space_span(13, def) @@ -816,7 +816,7 @@ pub mod tests { let s = "Strikethrough!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Strikethrough", strike), Span::styled("!", strike), space_span(6, def) @@ -825,7 +825,7 @@ pub mod tests { let s = "Strikethrough!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Strikethrough", strike), Span::styled("!", strike), space_span(6, def) @@ -834,7 +834,7 @@ pub mod tests { let s = "Underline!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Underline", underl), Span::styled("!", underl), space_span(10, def) @@ -843,7 +843,7 @@ pub mod tests { let s = "Red!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Red", red), Span::styled("!", red), space_span(16, def) @@ -852,7 +852,7 @@ pub mod tests { let s = "Red!"; let tree = parse_matrix_html(s); let text = tree.to_text(20, Style::default(), false); - assert_eq!(text.lines, vec![Spans(vec![ + assert_eq!(text.lines, vec![Line::from(vec![ Span::styled("Red", red), Span::styled("!", red), space_span(16, def) @@ -867,22 +867,22 @@ pub mod tests { assert_eq!(text.lines.len(), 7); assert_eq!( text.lines[0], - Spans(vec![Span::raw("Hello"), Span::raw(" "), Span::raw(" ")]) + Line::from(vec![Span::raw("Hello"), Span::raw(" "), Span::raw(" ")]) ); assert_eq!( text.lines[1], - Spans(vec![Span::raw("world"), Span::raw("!"), Span::raw(" ")]) + Line::from(vec![Span::raw("world"), Span::raw("!"), Span::raw(" ")]) ); - assert_eq!(text.lines[2], Spans(vec![Span::raw(" ")])); - assert_eq!(text.lines[3], Spans(vec![Span::raw("Content"), Span::raw(" ")])); - assert_eq!(text.lines[4], Spans(vec![Span::raw(" ")])); + assert_eq!(text.lines[2], Line::from(vec![Span::raw(" ")])); + assert_eq!(text.lines[3], Line::from(vec![Span::raw("Content"), Span::raw(" ")])); + assert_eq!(text.lines[4], Line::from(vec![Span::raw(" ")])); assert_eq!( text.lines[5], - Spans(vec![Span::raw("Goodbye"), Span::raw(" "), Span::raw(" ")]) + Line::from(vec![Span::raw("Goodbye"), Span::raw(" "), Span::raw(" ")]) ); assert_eq!( text.lines[6], - Spans(vec![Span::raw("world"), Span::raw("!"), Span::raw(" ")]) + Line::from(vec![Span::raw("world"), Span::raw("!"), Span::raw(" ")]) ); } @@ -894,11 +894,11 @@ pub mod tests { assert_eq!(text.lines.len(), 2); assert_eq!( text.lines[0], - Spans(vec![Span::raw(" "), Span::raw("Hello"), Span::raw(" ")]) + Line::from(vec![Span::raw(" "), Span::raw("Hello"), Span::raw(" ")]) ); assert_eq!( text.lines[1], - Spans(vec![Span::raw(" "), Span::raw("world"), Span::raw("!")]) + Line::from(vec![Span::raw(" "), Span::raw("world"), Span::raw("!")]) ); } @@ -910,7 +910,7 @@ pub mod tests { assert_eq!(text.lines.len(), 6); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw("- "), Span::raw("List"), Span::raw(" "), @@ -919,7 +919,7 @@ pub mod tests { ); assert_eq!( text.lines[1], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -928,7 +928,7 @@ pub mod tests { ); assert_eq!( text.lines[2], - Spans(vec![ + Line::from(vec![ Span::raw("- "), Span::raw("List"), Span::raw(" "), @@ -937,7 +937,7 @@ pub mod tests { ); assert_eq!( text.lines[3], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -946,7 +946,7 @@ pub mod tests { ); assert_eq!( text.lines[4], - Spans(vec![ + Line::from(vec![ Span::raw("- "), Span::raw("List"), Span::raw(" "), @@ -955,7 +955,7 @@ pub mod tests { ); assert_eq!( text.lines[5], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -972,7 +972,7 @@ pub mod tests { assert_eq!(text.lines.len(), 6); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw("1. "), Span::raw("List"), Span::raw(" "), @@ -981,7 +981,7 @@ pub mod tests { ); assert_eq!( text.lines[1], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -990,7 +990,7 @@ pub mod tests { ); assert_eq!( text.lines[2], - Spans(vec![ + Line::from(vec![ Span::raw("2. "), Span::raw("List"), Span::raw(" "), @@ -999,7 +999,7 @@ pub mod tests { ); assert_eq!( text.lines[3], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -1008,7 +1008,7 @@ pub mod tests { ); assert_eq!( text.lines[4], - Spans(vec![ + Line::from(vec![ Span::raw("3. "), Span::raw("List"), Span::raw(" "), @@ -1017,7 +1017,7 @@ pub mod tests { ); assert_eq!( text.lines[5], - Spans(vec![ + Line::from(vec![ Span::raw(" "), Span::raw("Item"), Span::raw(" "), @@ -1043,8 +1043,8 @@ pub mod tests { assert_eq!(text.lines.len(), 11); // Table header - assert_eq!(text.lines[0].0, vec![Span::raw("┌────┬────┬───┐")]); - assert_eq!(text.lines[1].0, vec![ + assert_eq!(text.lines[0].spans, vec![Span::raw("┌────┬────┬───┐")]); + assert_eq!(text.lines[1].spans, vec![ Span::raw("│"), Span::styled("Colu", bold), Span::raw("│"), @@ -1053,7 +1053,7 @@ pub mod tests { Span::styled("Col", bold), Span::raw("│") ]); - assert_eq!(text.lines[2].0, vec![ + assert_eq!(text.lines[2].spans, vec![ Span::raw("│"), Span::styled("mn", bold), Span::styled(" ", bold), @@ -1066,7 +1066,7 @@ pub mod tests { Span::styled("umn", bold), Span::raw("│") ]); - assert_eq!(text.lines[3].0, vec![ + assert_eq!(text.lines[3].spans, vec![ Span::raw("│"), Span::raw(" "), Span::raw("│"), @@ -1078,8 +1078,8 @@ pub mod tests { ]); // First row - assert_eq!(text.lines[4].0, vec![Span::raw("├────┼────┼───┤")]); - assert_eq!(text.lines[5].0, vec![ + assert_eq!(text.lines[4].spans, vec![Span::raw("├────┼────┼───┤")]); + assert_eq!(text.lines[5].spans, vec![ Span::raw("│"), Span::raw("a"), Span::raw(" "), @@ -1093,8 +1093,8 @@ pub mod tests { ]); // Second row - assert_eq!(text.lines[6].0, vec![Span::raw("├────┼────┼───┤")]); - assert_eq!(text.lines[7].0, vec![ + assert_eq!(text.lines[6].spans, vec![Span::raw("├────┼────┼───┤")]); + assert_eq!(text.lines[7].spans, vec![ Span::raw("│"), Span::raw("a"), Span::raw(" "), @@ -1108,8 +1108,8 @@ pub mod tests { ]); // Third row - assert_eq!(text.lines[8].0, vec![Span::raw("├────┼────┼───┤")]); - assert_eq!(text.lines[9].0, vec![ + assert_eq!(text.lines[8].spans, vec![Span::raw("├────┼────┼───┤")]); + assert_eq!(text.lines[9].spans, vec![ Span::raw("│"), Span::raw("a"), Span::raw(" "), @@ -1123,7 +1123,7 @@ pub mod tests { ]); // Bottom ruler - assert_eq!(text.lines[10].0, vec![Span::raw("└────┴────┴───┘")]); + assert_eq!(text.lines[10].spans, vec![Span::raw("└────┴────┴───┘")]); } #[test] @@ -1135,7 +1135,7 @@ pub mod tests { assert_eq!(text.lines.len(), 4); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw("This"), Span::raw(" "), Span::raw("was"), @@ -1145,11 +1145,11 @@ pub mod tests { ); assert_eq!( text.lines[1], - Spans(vec![Span::raw("replied"), Span::raw(" "), Span::raw("to")]) + Line::from(vec![Span::raw("replied"), Span::raw(" "), Span::raw("to")]) ); assert_eq!( text.lines[2], - Spans(vec![ + Line::from(vec![ Span::raw("This"), Span::raw(" "), Span::raw("is"), @@ -1159,7 +1159,7 @@ pub mod tests { ); assert_eq!( text.lines[3], - Spans(vec![ + Line::from(vec![ Span::raw("the"), Span::raw(" "), Span::raw("reply"), @@ -1172,7 +1172,7 @@ pub mod tests { assert_eq!(text.lines.len(), 2); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw("This"), Span::raw(" "), Span::raw("is"), @@ -1182,7 +1182,7 @@ pub mod tests { ); assert_eq!( text.lines[1], - Spans(vec![ + Line::from(vec![ Span::raw("the"), Span::raw(" "), Span::raw("reply"), @@ -1197,9 +1197,9 @@ pub mod tests { let tree = parse_matrix_html(s); let text = tree.to_text(7, Style::default(), true); assert_eq!(text.lines.len(), 3); - assert_eq!(text.lines[0], Spans(vec![Span::raw("Hello"), Span::raw(" "),])); - assert_eq!(text.lines[1], Spans(vec![Span::raw("World"), Span::raw(" "),])); - assert_eq!(text.lines[2], Spans(vec![Span::raw("Goodbye")]),); + assert_eq!(text.lines[0], Line::from(vec![Span::raw("Hello"), Span::raw(" "),])); + assert_eq!(text.lines[1], Line::from(vec![Span::raw("World"), Span::raw(" "),])); + assert_eq!(text.lines[2], Line::from(vec![Span::raw("Goodbye")]),); } #[test] @@ -1210,7 +1210,7 @@ pub mod tests { assert_eq!(text.lines.len(), 1); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw("Hello"), Span::raw(" "), Span::raw("World"), @@ -1233,7 +1233,7 @@ pub mod tests { assert_eq!(text.lines.len(), 5); assert_eq!( text.lines[0], - Spans(vec![ + Line::from(vec![ Span::raw(line::TOP_LEFT), Span::raw(line::HORIZONTAL.repeat(23)), Span::raw(line::TOP_RIGHT) @@ -1241,7 +1241,7 @@ pub mod tests { ); assert_eq!( text.lines[1], - Spans(vec![ + Line::from(vec![ Span::raw(line::VERTICAL), Span::raw("fn"), Span::raw(" "), @@ -1261,7 +1261,7 @@ pub mod tests { ); assert_eq!( text.lines[2], - Spans(vec![ + Line::from(vec![ Span::raw(line::VERTICAL), Span::raw(" "), Span::raw("return"), @@ -1274,7 +1274,7 @@ pub mod tests { ); assert_eq!( text.lines[3], - Spans(vec![ + Line::from(vec![ Span::raw(line::VERTICAL), Span::raw("}"), Span::raw(" ".repeat(22)), @@ -1283,7 +1283,7 @@ pub mod tests { ); assert_eq!( text.lines[4], - Spans(vec![ + Line::from(vec![ Span::raw(line::BOTTOM_LEFT), Span::raw(line::HORIZONTAL.repeat(23)), Span::raw(line::BOTTOM_RIGHT) diff --git a/src/message/mod.rs b/src/message/mod.rs index 1aa4f66..de76bfa 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -47,7 +47,7 @@ use matrix_sdk::ruma::{ use modalkit::tui::{ style::{Modifier as StyleModifier, Style}, symbols::line::THICK_VERTICAL, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, }; use modalkit::editing::{base::ViewportContext, cursor::Cursor}; @@ -74,6 +74,7 @@ const fn span_static(s: &'static str) -> Span<'static> { bg: None, add_modifier: StyleModifier::empty(), sub_modifier: StyleModifier::empty(), + underline_color: None, }, } } @@ -83,6 +84,7 @@ const BOLD_STYLE: Style = Style { bg: None, add_modifier: StyleModifier::BOLD, sub_modifier: StyleModifier::empty(), + underline_color: None, }; const USER_GUTTER: usize = 30; @@ -508,14 +510,14 @@ impl<'a> MessageFormatter<'a> { } #[inline] - fn push_spans(&mut self, spans: Spans<'a>, style: Style, text: &mut Text<'a>) { + fn push_spans(&mut self, prev_line: Line<'a>, style: Style, text: &mut Text<'a>) { if let Some(date) = self.date.take() { let len = date.content.as_ref().len(); let padding = self.orig.saturating_sub(len); let leading = space_span(padding / 2, Style::default()); let trailing = space_span(padding.saturating_sub(padding / 2), Style::default()); - text.lines.push(Spans(vec![leading, date, trailing])); + text.lines.push(Line::from(vec![leading, date, trailing])); } match self.cols { @@ -525,7 +527,7 @@ impl<'a> MessageFormatter<'a> { let time = self.time.take().unwrap_or(TIME_GUTTER_EMPTY_SPAN); let mut line = vec![user]; - line.extend(spans.0); + line.extend(prev_line.spans); line.push(time); // Show read receipts. @@ -542,35 +544,35 @@ impl<'a> MessageFormatter<'a> { line.push(a); line.push(Span::raw(" ")); - text.lines.push(Spans(line)) + text.lines.push(Line::from(line)) }, MessageColumns::Three => { let user = self.user.take().unwrap_or(USER_GUTTER_EMPTY_SPAN); let time = self.time.take().unwrap_or_else(|| Span::from("")); let mut line = vec![user]; - line.extend(spans.0); + line.extend(prev_line.spans); line.push(time); - text.lines.push(Spans(line)) + text.lines.push(Line::from(line)) }, MessageColumns::Two => { let user = self.user.take().unwrap_or(USER_GUTTER_EMPTY_SPAN); let mut line = vec![user]; - line.extend(spans.0); + line.extend(prev_line.spans); - text.lines.push(Spans(line)); + text.lines.push(Line::from(line)); }, MessageColumns::One => { if let Some(user) = self.user.take() { - text.lines.push(Spans(vec![user])); + text.lines.push(Line::from(vec![user])); } let leading = space_span(2, style); let mut line = vec![leading]; - line.extend(spans.0); + line.extend(prev_line.spans); - text.lines.push(Spans(line)); + text.lines.push(Line::from(line)); }, } } @@ -709,7 +711,7 @@ impl Message { sender.style = sender.style.patch(style); fmt.push_spans( - Spans(vec![ + Line::from(vec![ Span::styled(" ", style), Span::styled(THICK_VERTICAL, style), sender, @@ -721,8 +723,8 @@ impl Message { ); for line in replied.lines.iter_mut() { - line.0.insert(0, Span::styled(THICK_VERTICAL, style)); - line.0.insert(0, Span::styled(" ", style)); + line.spans.insert(0, Span::styled(THICK_VERTICAL, style)); + line.spans.insert(0, Span::styled(" ", style)); } fmt.push_text(replied, style, &mut text); diff --git a/src/message/printer.rs b/src/message/printer.rs index f1d08de..2d2335a 100644 --- a/src/message/printer.rs +++ b/src/message/printer.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use modalkit::tui::layout::Alignment; use modalkit::tui::style::Style; -use modalkit::tui::text::{Span, Spans, Text}; +use modalkit::tui::text::{Line, Span, Text}; use unicode_segmentation::UnicodeSegmentation; use unicode_width::UnicodeWidthStr; @@ -92,7 +92,7 @@ impl<'a> TextPrinter<'a> { fn push(&mut self) { self.curr_width = 0; - self.text.lines.push(Spans(std::mem::take(&mut self.curr_spans))); + self.text.lines.push(Line::from(std::mem::take(&mut self.curr_spans))); } /// Start a new line. @@ -228,10 +228,10 @@ impl<'a> TextPrinter<'a> { } } - /// Push [Spans] into the printer. - pub fn push_line(&mut self, spans: Spans<'a>) { + /// Push a [Line] into the printer. + pub fn push_line(&mut self, line: Line<'a>) { self.commit(); - self.text.lines.push(spans); + self.text.lines.push(line); } /// Push multiline [Text] into the printer. diff --git a/src/util.rs b/src/util.rs index 55d47c2..af63d55 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,7 @@ use unicode_segmentation::UnicodeSegmentation; use unicode_width::UnicodeWidthStr; use modalkit::tui::style::Style; -use modalkit::tui::text::{Span, Spans, Text}; +use modalkit::tui::text::{Line, Span, Text}; pub fn split_cow(cow: Cow<'_, str>, idx: usize) -> (Cow<'_, str>, Cow<'_, str>) { match cow { @@ -106,7 +106,7 @@ where for (line, w) in wrap(s, width) { let space = space_span(width.saturating_sub(w), style); - let spans = Spans(vec![Span::styled(line, style), space]); + let spans = Line::from(vec![Span::styled(line, style), space]); text.lines.push(spans); } @@ -128,17 +128,19 @@ pub fn space_text(width: usize, style: Style) -> Text<'static> { pub fn join_cell_text<'a>(texts: Vec<(Text<'a>, usize)>, join: Span<'a>, style: Style) -> Text<'a> { let height = texts.iter().map(|t| t.0.height()).max().unwrap_or(0); - let mut text = Text { lines: vec![Spans(vec![join.clone()]); height] }; + let mut text = Text { + lines: vec![Line::from(vec![join.clone()]); height], + }; for (mut t, w) in texts.into_iter() { for i in 0..height { - if let Some(spans) = t.lines.get_mut(i) { - text.lines[i].0.append(&mut spans.0); + if let Some(line) = t.lines.get_mut(i) { + text.lines[i].spans.append(&mut line.spans); } else { - text.lines[i].0.push(space_span(w, style)); + text.lines[i].spans.push(space_span(w, style)); } - text.lines[i].0.push(join.clone()); + text.lines[i].spans.push(join.clone()); } } diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 09abf44..42146ae 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -26,7 +26,7 @@ use modalkit::tui::{ buffer::Buffer, layout::{Alignment, Rect}, style::{Modifier as StyleModifier, Style}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::StatefulWidget, }; @@ -102,7 +102,7 @@ fn bold_span(s: &str) -> Span { } #[inline] -fn bold_spans(s: &str) -> Spans { +fn bold_spans(s: &str) -> Line { bold_span(s).into() } @@ -537,7 +537,7 @@ impl Window for IambWindow { } } - fn get_tab_title(&self, store: &mut ProgramStore) -> Spans { + fn get_tab_title(&self, store: &mut ProgramStore) -> Line { match self { IambWindow::DirectList(_) => bold_spans("Direct Messages"), IambWindow::RoomList(_) => bold_spans("Rooms"), @@ -548,7 +548,7 @@ impl Window for IambWindow { IambWindow::Room(w) => { let title = store.application.get_room_title(w.id()); - Spans::from(title) + Line::from(title) }, IambWindow::MemberList(state, room_id, _) => { let title = store.application.get_room_title(room_id.as_ref()); @@ -558,12 +558,12 @@ impl Window for IambWindow { Span::styled(format!("({n}): "), bold_style()), title.into(), ]; - Spans(v) + Line::from(v) }, } } - fn get_win_title(&self, store: &mut ProgramStore) -> Spans { + fn get_win_title(&self, store: &mut ProgramStore) -> Line { match self { IambWindow::DirectList(_) => bold_spans("Direct Messages"), IambWindow::RoomList(_) => bold_spans("Rooms"), @@ -580,7 +580,7 @@ impl Window for IambWindow { Span::styled(format!("({n}): "), bold_style()), title.into(), ]; - Spans(v) + Line::from(v) }, } } @@ -730,7 +730,7 @@ impl ListItem for RoomItem { append_tags(tags, &mut spans, style); - Text::from(Spans(spans)) + Text::from(Line::from(spans)) } else { selected_text(self.name.as_str(), selected) } @@ -796,7 +796,7 @@ impl ListItem for DirectItem { append_tags(tags, &mut spans, style); - Text::from(Spans(spans)) + Text::from(Line::from(spans)) } else { selected_text(self.name.as_str(), selected) } @@ -1023,47 +1023,47 @@ impl ListItem for VerifyItem { let bold = Style::default().add_modifier(StyleModifier::BOLD); let item = Span::styled(self.show_item(), selected_style(selected)); - lines.push(Spans::from(item)); + lines.push(Line::from(item)); if self.sasv1.is_done() { // Print nothing. } else if self.sasv1.is_cancelled() { if let Some(info) = self.sasv1.cancel_info() { - lines.push(Spans::from(format!(" Cancelled: {}", info.reason()))); - lines.push(Spans::from("")); + lines.push(Line::from(format!(" Cancelled: {}", info.reason()))); + lines.push(Line::from("")); } - lines.push(Spans::from(" You can start a new verification request with:")); + lines.push(Line::from(" You can start a new verification request with:")); } else if let Some(emoji) = self.sasv1.emoji() { - lines.push(Spans::from( + lines.push(Line::from( " Both devices should see the following Emoji sequence:".to_string(), )); - lines.push(Spans::from("")); + lines.push(Line::from("")); for line in format_emojis(emoji).lines() { - lines.push(Spans::from(format!(" {line}"))); + lines.push(Line::from(format!(" {line}"))); } - lines.push(Spans::from("")); - lines.push(Spans::from(" If they don't match, run:")); - lines.push(Spans::from("")); - lines.push(Spans::from(Span::styled( + lines.push(Line::from("")); + lines.push(Line::from(" If they don't match, run:")); + lines.push(Line::from("")); + lines.push(Line::from(Span::styled( format!(":verify mismatch {}", self.user_dev), bold, ))); - lines.push(Spans::from("")); - lines.push(Spans::from(" If everything looks right, you can confirm with:")); + lines.push(Line::from("")); + lines.push(Line::from(" If everything looks right, you can confirm with:")); } else { - lines.push(Spans::from(" To accept this request, run:")); + lines.push(Line::from(" To accept this request, run:")); } let cmd = self.to_string(); if !cmd.is_empty() { - lines.push(Spans::from("")); - lines.push(Spans(vec![Span::from(" "), Span::styled(cmd, bold)])); - lines.push(Spans::from("")); - lines.push(Spans(vec![ + lines.push(Line::from("")); + lines.push(Line::from(vec![Span::from(" "), Span::styled(cmd, bold)])); + lines.push(Line::from("")); + lines.push(Line::from(vec![ Span::from("You can copy the above command with "), Span::styled("yy", bold), Span::from(" and then execute it with "), @@ -1167,7 +1167,7 @@ impl ListItem for MemberItem { spans.extend(state); - return Spans(spans).into(); + return Line::from(spans).into(); } fn get_word(&self) -> Option { diff --git a/src/windows/room/chat.rs b/src/windows/room/chat.rs index 610853e..ca2401d 100644 --- a/src/windows/room/chat.rs +++ b/src/windows/room/chat.rs @@ -35,7 +35,7 @@ use modalkit::{ tui::{ buffer::Buffer, layout::Rect, - text::{Span, Spans}, + text::{Line, Span}, widgets::{Paragraph, StatefulWidget, Widget}, }, widgets::textbox::{TextBox, TextBoxState}, @@ -812,7 +812,7 @@ impl<'a> StatefulWidget for Chat<'a> { // Determine whether we have a description to show for the message bar. let desc_spans = match (&state.editing, &state.reply_to) { (None, None) => None, - (Some(_), None) => Some(Spans::from("Editing message")), + (Some(_), None) => Some(Line::from("Editing message")), (editing, Some(_)) => { state.reply_to.as_ref().and_then(|k| { let room = self.store.application.rooms.get(state.id())?; @@ -824,7 +824,7 @@ impl<'a> StatefulWidget for Chat<'a> { } else { Span::from("Replying to ") }; - let spans = Spans(vec![prefix, user]); + let spans = Line::from(vec![prefix, user]); spans.into() }) diff --git a/src/windows/room/mod.rs b/src/windows/room/mod.rs index ec4483b..2b3927e 100644 --- a/src/windows/room/mod.rs +++ b/src/windows/room/mod.rs @@ -15,7 +15,7 @@ use modalkit::tui::{ buffer::Buffer, layout::{Alignment, Rect}, style::{Modifier as StyleModifier, Style}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::{Paragraph, StatefulWidget, Widget}, }; @@ -150,8 +150,8 @@ impl RoomState { invited.push(store.application.settings.get_user_span(inviter.user_id(), info)); } - let l1 = Spans(invited); - let l2 = Spans::from( + let l1 = Line::from(invited); + let l2 = Line::from( "You can run `:invite accept` or `:invite reject` to accept or reject this invitation.", ); let text = Text { lines: vec![l1, l2] }; @@ -305,7 +305,7 @@ impl RoomState { } } - pub fn get_title(&self, store: &mut ProgramStore) -> Spans { + pub fn get_title(&self, store: &mut ProgramStore) -> Line { let title = store.application.get_room_title(self.id()); let style = Style::default().add_modifier(StyleModifier::BOLD); let mut spans = vec![Span::styled(title, style)]; @@ -319,7 +319,7 @@ impl RoomState { _ => {}, } - Spans(spans) + Line::from(spans) } pub fn focus_toggle(&mut self) { diff --git a/src/windows/room/scrollback.rs b/src/windows/room/scrollback.rs index 590c785..d3e8549 100644 --- a/src/windows/room/scrollback.rs +++ b/src/windows/room/scrollback.rs @@ -9,7 +9,7 @@ use modalkit::tui::{ buffer::Buffer, layout::{Alignment, Rect}, style::{Modifier as StyleModifier, Style}, - text::{Span, Spans}, + text::{Line, Span}, widgets::{Paragraph, StatefulWidget, Widget}, }; use modalkit::widgets::{ScrollActions, TerminalCursor, WindowOps}; @@ -1226,7 +1226,7 @@ fn render_jump_to_recent(area: Rect, buf: &mut Buffer, focused: bool) -> Rect { Span::raw(" to jump to latest message"), ]; - Paragraph::new(Spans::from(msg)) + Paragraph::new(Line::from(msg)) .alignment(Alignment::Center) .render(bar, buf); @@ -1342,7 +1342,7 @@ impl<'a> StatefulWidget for Scrollback<'a> { let x = area.left(); for (_, _, txt) in lines.into_iter() { - let _ = buf.set_spans(x, y, &txt, area.width); + let _ = buf.set_line(x, y, &txt, area.width); y += 1; } diff --git a/src/windows/room/space.rs b/src/windows/room/space.rs index d3f49b7..11c4a51 100644 --- a/src/windows/room/space.rs +++ b/src/windows/room/space.rs @@ -11,7 +11,7 @@ use modalkit::tui::{ buffer::Buffer, layout::Rect, style::{Color, Style}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::StatefulWidget, }; @@ -140,7 +140,7 @@ impl<'a> StatefulWidget for Space<'a> { }, Err(e) => { let lines = vec![ - Spans::from("Unable to fetch space room hierarchy:"), + Line::from("Unable to fetch space room hierarchy:"), Span::styled(e.to_string(), Style::default().fg(Color::Red)).into(), ];