From 0c8f3011ed930c58ce8c8b48ae9a2ae9c12bff51 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Mon, 14 Oct 2024 17:47:22 +0200 Subject: [PATCH] Upgrade avt to the latest version --- native/vt_nif/Cargo.lock | 37 ++++++-------------------- native/vt_nif/Cargo.toml | 2 +- native/vt_nif/src/lib.rs | 53 +++++++++++++++++++++----------------- test/asciinema/vt_test.exs | 9 ++++--- 4 files changed, 45 insertions(+), 56 deletions(-) diff --git a/native/vt_nif/Cargo.lock b/native/vt_nif/Cargo.lock index a2ad496f3..c52d83cbf 100644 --- a/native/vt_nif/Cargo.lock +++ b/native/vt_nif/Cargo.lock @@ -13,20 +13,19 @@ dependencies = [ [[package]] name = "avt" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c67dc0145986662262f8b0f0b791ec6de6b9fcd078f55fa2b31ac691516505" +checksum = "b485f400d02970694eed10e7080f994ad82eaf56a867d6671af5d5e184ed8ee6" dependencies = [ "rgb", - "serde", "unicode-width", ] [[package]] name = "bytemuck" -version = "1.13.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "heck" @@ -83,9 +82,9 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "rgb" -version = "0.8.35" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7495acf66551cdb696b7711408144bcd3194fc78e32f3a09e809bfe7dd4a7ce3" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ "bytemuck", ] @@ -123,26 +122,6 @@ dependencies = [ "unreachable", ] -[[package]] -name = "serde" -version = "1.0.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" version = "1.0.107" @@ -162,9 +141,9 @@ checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unreachable" diff --git a/native/vt_nif/Cargo.toml b/native/vt_nif/Cargo.toml index 5ebdebf8a..33f26bae8 100644 --- a/native/vt_nif/Cargo.toml +++ b/native/vt_nif/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["dylib"] [dependencies] rustler = "0.27.0" -avt = "0.13.0" +avt = "0.14.0" diff --git a/native/vt_nif/src/lib.rs b/native/vt_nif/src/lib.rs index 7ce2d7176..f80e3f86e 100644 --- a/native/vt_nif/src/lib.rs +++ b/native/vt_nif/src/lib.rs @@ -78,17 +78,7 @@ fn dump_screen(env: Env, resource: ResourceArc) -> NifResult<(Atom, let lines = vt .view() .iter() - .map(|line| { - line.group(|c, w| { - w > 1 - || BOX_DRAWING_RANGE.contains(c) - || BRAILLE_PATTERNS_RANGE.contains(c) - || BLOCK_ELEMENTS_RANGE.contains(c) - || POWERLINE_TRIANGLES_RANGE.contains(c) - }) - .map(|segment| segment_to_term(segment, env)) - .collect::>() - }) + .map(|line| line_to_terms(line, env)) .collect::>(); let cursor: Option<(usize, usize)> = vt.cursor().into(); @@ -96,6 +86,22 @@ fn dump_screen(env: Env, resource: ResourceArc) -> NifResult<(Atom, Ok((atoms::ok(), (lines, cursor).encode(env))) } +fn line_to_terms<'a>(line: &avt::Line, env: Env<'a>) -> Vec> { + line.chunks(|c1, c2| c1.pen() != c2.pen() || is_special_char(c1) || is_special_char(c2)) + .map(|cells| chunk_to_term(cells, env)) + .collect::>() +} + +fn is_special_char(cell: &avt::Cell) -> bool { + let ch = &cell.char(); + + cell.width() > 1 + || BOX_DRAWING_RANGE.contains(ch) + || BRAILLE_PATTERNS_RANGE.contains(ch) + || BLOCK_ELEMENTS_RANGE.contains(ch) + || POWERLINE_TRIANGLES_RANGE.contains(ch) +} + #[rustler::nif] fn text(resource: ResourceArc) -> NifResult { let vt = convert_err(resource.vt.read(), "rw_lock")?; @@ -112,11 +118,12 @@ fn text(resource: ResourceArc) -> NifResult { Ok(text.join("")) } -fn segment_to_term(segment: avt::Segment, env: Env) -> Term { - let txt = segment.text(); +fn chunk_to_term(cells: Vec, env: Env) -> Term { + let txt: String = cells.iter().map(|c| c.char()).collect(); + let pen = cells[0].pen(); let mut pairs: Vec<(String, Term)> = Vec::new(); - match segment.foreground() { + match pen.foreground() { Some(avt::Color::Indexed(c)) => { pairs.push(("fg".to_owned(), c.encode(env))); } @@ -129,7 +136,7 @@ fn segment_to_term(segment: avt::Segment, env: Env) -> Term { None => (), } - match segment.background() { + match pen.background() { Some(avt::Color::Indexed(c)) => { pairs.push(("bg".to_owned(), c.encode(env))); } @@ -142,37 +149,37 @@ fn segment_to_term(segment: avt::Segment, env: Env) -> Term { None => (), } - if segment.is_bold() { + if pen.is_bold() { pairs.push(("bold".to_owned(), true.encode(env))); } - if segment.is_faint() { + if pen.is_faint() { pairs.push(("faint".to_owned(), true.encode(env))); } - if segment.is_italic() { + if pen.is_italic() { pairs.push(("italic".to_owned(), true.encode(env))); } - if segment.is_underline() { + if pen.is_underline() { pairs.push(("underline".to_owned(), true.encode(env))); } - if segment.is_strikethrough() { + if pen.is_strikethrough() { pairs.push(("strikethrough".to_owned(), true.encode(env))); } - if segment.is_blink() { + if pen.is_blink() { pairs.push(("blink".to_owned(), true.encode(env))); } - if segment.is_inverse() { + if pen.is_inverse() { pairs.push(("inverse".to_owned(), true.encode(env))); } let attrs = Term::map_from_pairs(env, &pairs).unwrap(); - (txt, attrs, segment.char_width()).encode(env) + (txt, attrs, cells[0].width()).encode(env) } fn convert_err(result: Result, error: &'static str) -> Result { diff --git a/test/asciinema/vt_test.exs b/test/asciinema/vt_test.exs index b989d6ca2..1352eb6b5 100644 --- a/test/asciinema/vt_test.exs +++ b/test/asciinema/vt_test.exs @@ -10,13 +10,16 @@ defmodule Asciinema.VtTest do Vt.with_vt(8, 3, fn vt -> Vt.feed(vt, "foobar\r\n") Vt.feed(vt, "baz") - Vt.feed(vt, "qux") + Vt.feed(vt, "全") Vt.dump_screen(vt) end) assert {:ok, - {[[{"foobar ", %{}, 1}], [{"bazqux ", %{}, 1}], [{" ", %{}, 1}]], {6, 1}}} = - result + {[ + [{"foobar ", %{}, 1}], + [{"baz", %{}, 1}, {"全", %{}, 2}, {" ", %{}, 1}], + [{" ", %{}, 1}] + ], {4, 1}}} = result end test "feeding it a lot of data" do