diff --git a/Cargo.lock b/Cargo.lock index b435889..a265f22 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-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -681,6 +682,11 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-width" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.0.4" @@ -811,6 +817,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-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" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" diff --git a/Cargo.toml b/Cargo.toml index 345a294..32a7b5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ rmpv = "0.4" percent-encoding = "1.0" regex = "0.2" lazy_static = "1.0" +unicode-width = "0.1.4" serde = "1.0" serde_derive = "1.0" diff --git a/src/cmd_line.rs b/src/cmd_line.rs index ee588f4..02324a9 100644 --- a/src/cmd_line.rs +++ b/src/cmd_line.rs @@ -24,7 +24,6 @@ pub struct Level { } impl Level { - //TODO: double width chars render, also note in text wrapping //TODO: im pub fn insert(&mut self, c: &str, shift: bool, render_state: &shell::RenderState) { diff --git a/src/main.rs b/src/main.rs index 4003ead..7873512 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ extern crate percent_encoding; extern crate phf; extern crate rmpv; extern crate regex; +extern crate unicode_width; extern crate serde; #[macro_use] diff --git a/src/ui_model/model_layout.rs b/src/ui_model/model_layout.rs index 211584e..0ff40b4 100644 --- a/src/ui_model/model_layout.rs +++ b/src/ui_model/model_layout.rs @@ -1,5 +1,7 @@ use std::cmp::max; +use unicode_width::UnicodeWidthChar; + use ui_model::{Attrs, UiModel}; pub struct ModelLayout { @@ -116,19 +118,24 @@ impl ModelLayout { for content in lines { for &(ref attr, ref ch_list) in content { for ch in ch_list { - if col_idx >= self.model.columns { + let ch_width = ch.width().unwrap_or(1); + + if col_idx + ch_width > self.model.columns { col_idx = 0; row_idx += 1; } self.model.set_cursor(row_idx, col_idx as usize); self.model.put(*ch, false, attr.as_ref()); - - if max_col_idx < col_idx { - max_col_idx = col_idx; + if ch_width > 1 { + self.model.put(' ', true, attr.as_ref()); } - col_idx += 1; + if max_col_idx < col_idx { + max_col_idx = col_idx + ch_width - 1; + } + + col_idx += ch_width; } if col_idx < self.model.columns { @@ -229,4 +236,16 @@ mod tests { assert_eq!(3, cols); assert_eq!('b', model.model.model()[0].line[1].ch); } + + #[test] + fn test_double_width() { + let lines = vec![vec![(None, vec!['あ'; 3])]; 1]; + let mut model = ModelLayout::new(7); + model.layout(lines); + model.set_cursor(1); + + let (cols, rows) = model.size(); + assert_eq!(1, rows); + assert_eq!(6, cols); + } }