From 14c6db57694d8f88dfe89f135b9eed3af8a9d75f Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Thu, 26 Oct 2023 11:38:09 +0200 Subject: [PATCH] Fix emoji length --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/lib.rs | 10 +++++----- src/tile.rs | 27 ++++++++++++++++++++------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbbbd99..5f73bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,7 @@ version = "0.1.0" dependencies = [ "pty-process", "termion", + "unicode-width", ] [[package]] @@ -110,6 +111,12 @@ dependencies = [ "redox_termios", ] +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index fc2ea01..a348b47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ edition = "2021" [dependencies] pty-process = "0.4.0" termion = "2.0.1" +unicode-width = "0.1.11" diff --git a/src/lib.rs b/src/lib.rs index b3a6373..940dfde 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,13 +90,13 @@ impl Multiview { /// Renders all the tiles of the multiview. pub fn render(&mut self) -> io::Result<()> { - let now = Instant::now(); + // let now = Instant::now(); - if now.duration_since(self.last_render) < Duration::from_millis(20) { - return Ok(()); - } + // if now.duration_since(self.last_render) < Duration::from_millis(20) { + // return Ok(()); + // } - self.last_render = now; + // self.last_render = now; let mut buffer = vec![]; for i in 0..self.tiles.len() { for j in 0..self.tiles[0].len() { diff --git a/src/tile.rs b/src/tile.rs index 33eff6d..0e2a76b 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -8,6 +8,8 @@ use std::thread; use pty_process::blocking::Command; use pty_process::blocking::Pty; +use unicode_width::UnicodeWidthChar; + use termion::{color, cursor, style}; use crate::{utils, Msg}; @@ -252,6 +254,7 @@ impl Tile { if c == '\x1b' { self.counting = false; } + match c { '\n' => { self.stdout.last_mut().unwrap().push(c); @@ -267,7 +270,10 @@ impl Tile { _ => { self.stdout.last_mut().unwrap().push(c); - if self.counting { + // Emoji variation selectors have no length + let is_variation_selector = c >= '\u{fe00}' && c <= '\u{fe0f}'; + + if self.counting && !is_variation_selector { self.column_number += 1; if self.column_number == self.inner_size.0 + 1 { self.stdout.push(String::new()); @@ -380,7 +386,7 @@ impl Tile { }; if c == '\x1b' { - let mut subbuffer = String::from(c); + let mut subbuffer = vec![c]; loop { let next = match char_iter.next() { @@ -404,8 +410,8 @@ impl Tile { } } - match &subbuffer[0..3] { - "\x1b[K" => { + match (subbuffer.get(0), subbuffer.get(1), subbuffer.get(2)) { + (Some('\x1b'), Some('['), Some('K')) => { if current_char_index < w { let mut spaces = String::new(); for _ in current_char_index..w { @@ -425,7 +431,7 @@ impl Tile { )); } } - _ => buffer.push(subbuffer), + _ => buffer.push(subbuffer.into_iter().collect()), } continue; @@ -442,6 +448,8 @@ impl Tile { } buffer.push(spaces); + eprintln!("Clear {}", max_char_index); + line_index += 1; current_char_index = 0; max_char_index = 0; @@ -465,8 +473,13 @@ impl Tile { } _ => { - current_char_index += 1; - max_char_index = std::cmp::max(max_char_index, current_char_index); + // Emoji variation selectors have no length + let is_variation_selector = c >= '\u{fe00}' && c <= '\u{fe0f}'; + + if !is_variation_selector { + current_char_index += UnicodeWidthChar::width(c).unwrap_or(0) as u16; + max_char_index = std::cmp::max(max_char_index, current_char_index); + } if current_char_index == w + 1 { line_index += 1;