diff --git a/Cargo.lock b/Cargo.lock index a265f22..6dc093f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,6 +394,7 @@ dependencies = [ "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -682,6 +683,11 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-segmentation" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.4" @@ -817,6 +823,7 @@ dependencies = [ "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" +"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" diff --git a/Cargo.toml b/Cargo.toml index 32a7b5c..463b2bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ percent-encoding = "1.0" regex = "0.2" lazy_static = "1.0" unicode-width = "0.1.4" +unicode-segmentation = "1.2.0" serde = "1.0" serde_derive = "1.0" diff --git a/src/cmd_line.rs b/src/cmd_line.rs index 03dbfc3..67dd089 100644 --- a/src/cmd_line.rs +++ b/src/cmd_line.rs @@ -28,7 +28,7 @@ pub struct Level { } impl Level { - pub fn insert(&mut self, c: &str, shift: bool, render_state: &shell::RenderState) { + pub fn insert(&mut self, c: String, shift: bool, render_state: &shell::RenderState) { self.model_layout.insert_char(c, shift); self.update_preferred_size(render_state); } @@ -405,7 +405,7 @@ impl CmdLine { let mut state = self.state.borrow_mut(); if let Some(level) = state.levels.get_mut((level - 1) as usize) { - level.insert(&c, shift, render_state); + level.insert(c, shift, render_state); level.update_cache(&*render_state); } else { error!("Level {} does not exists", level); diff --git a/src/shell.rs b/src/shell.rs index 858b101..900f398 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1156,9 +1156,8 @@ impl State { } pub fn on_put(&mut self, text: String) -> RepaintMode { - let ch = text.chars().last().unwrap_or(' '); let double_width = text.is_empty(); - RepaintMode::Area(self.model.put(ch, double_width, self.cur_attrs.as_ref())) + RepaintMode::Area(self.model.put(text, double_width, self.cur_attrs.as_ref())) } pub fn on_clear(&mut self) -> RepaintMode { diff --git a/src/ui_model/cell.rs b/src/ui_model/cell.rs index b981ed0..9d528db 100644 --- a/src/ui_model/cell.rs +++ b/src/ui_model/cell.rs @@ -76,24 +76,30 @@ impl Attrs { } } +const EMPTY_STRING: String = String::new(); + #[derive(Clone)] pub struct Cell { pub attrs: Attrs, - pub ch: char, + pub ch: String, pub dirty: bool, } impl Cell { - pub fn new(ch: char) -> Cell { + pub fn new_empty() -> Cell { + Cell::new(EMPTY_STRING) + } + + pub fn new(ch: String) -> Cell { Cell { attrs: Attrs::new(), - ch: ch, + ch, dirty: true, } } pub fn clear(&mut self) { - self.ch = ' '; + self.ch = EMPTY_STRING; self.attrs.clear(); self.dirty = true; } diff --git a/src/ui_model/line.rs b/src/ui_model/line.rs index e358b84..ca835f4 100644 --- a/src/ui_model/line.rs +++ b/src/ui_model/line.rs @@ -21,7 +21,7 @@ pub struct Line { impl Line { pub fn new(columns: usize) -> Self { Line { - line: vec![Cell::new(' '); columns].into_boxed_slice(), + line: vec![Cell::new_empty(); columns].into_boxed_slice(), item_line: vec![None; columns].into_boxed_slice(), cell_to_item: vec![-1; columns].into_boxed_slice(), dirty_line: true, @@ -257,7 +257,7 @@ impl StyledLine { continue; } - line_str.push(cell.ch); + line_str.push_str(&cell.ch); let len = line_str.len() - byte_offset; for _ in 0..len { diff --git a/src/ui_model/mod.rs b/src/ui_model/mod.rs index 1ac54f9..60c5dbd 100644 --- a/src/ui_model/mod.rs +++ b/src/ui_model/mod.rs @@ -93,7 +93,7 @@ impl UiModel { (self.cur_row, self.cur_col) } - pub fn put(&mut self, ch: char, double_width: bool, attrs: Option<&Attrs>) -> ModelRect { + pub fn put(&mut self, ch: String, double_width: bool, attrs: Option<&Attrs>) -> ModelRect { let mut changed_region = self.cur_point(); let line = &mut self.model[self.cur_row]; line.dirty_line = true; diff --git a/src/ui_model/model_layout.rs b/src/ui_model/model_layout.rs index 0ff40b4..82c92d2 100644 --- a/src/ui_model/model_layout.rs +++ b/src/ui_model/model_layout.rs @@ -8,7 +8,7 @@ pub struct ModelLayout { pub model: UiModel, rows_filled: usize, cols_filled: usize, - lines: Vec, Vec)>>, + lines: Vec, Vec)>>, } impl ModelLayout { @@ -23,7 +23,7 @@ impl ModelLayout { } } - pub fn layout_append(&mut self, mut lines: Vec, Vec)>>) { + pub fn layout_append(&mut self, mut lines: Vec, Vec)>>) { let rows_filled = self.rows_filled; let take_from = self.lines.len(); @@ -32,7 +32,7 @@ impl ModelLayout { self.layout_replace(rows_filled, take_from); } - pub fn layout(&mut self, lines: Vec, Vec)>>) { + pub fn layout(&mut self, lines: Vec, Vec)>>) { self.lines = lines; self.layout_replace(0, 0); } @@ -67,12 +67,11 @@ impl ModelLayout { } } - pub fn insert_char(&mut self, c: &str, shift: bool) { - if c.is_empty() { + pub fn insert_char(&mut self, ch: String, shift: bool) { + if ch.is_empty() { return; } - let ch = c.chars().next().unwrap(); let (row, col) = self.model.get_cursor(); if shift { @@ -85,7 +84,7 @@ impl ModelLayout { self.model.set_cursor(row, col); } - fn insert_into_lines(&mut self, ch: char) { + fn insert_into_lines(&mut self, ch: String) { let line = &mut self.lines[0]; let cur_col = self.model.cur_col; @@ -152,7 +151,7 @@ impl ModelLayout { } } - fn count_lines(lines: &[Vec<(Option, Vec)>], max_columns: usize) -> usize { + fn count_lines(lines: &[Vec<(Option, Vec)>], max_columns: usize) -> usize { let mut row_count = 0; for line in lines {