diff options
author | Matthew Toohey | 2022-06-21 16:36:36 +0000 |
---|---|---|
committer | GitHub | 2022-06-21 16:36:36 +0000 |
commit | 6a3f7f2c399f0b92cef97b0c85ebe976fd7cfcac (patch) | |
tree | c350427ff1949f6e95464227ca0583bce8400c70 /helix-view | |
parent | fa4934cff9aa5b86b907e218313a7b370962ae67 (diff) |
feat: make `move_vertically` aware of tabs and wide characters (#2620)
* feat: make `move_vertically` aware of tabs and wide characters
* refactor: replace unnecessary checked_sub with comparison
* refactor: leave pos_at_coords unchanged and introduce separate pos_at_visual_coords
* style: include comment to explain `pos_at_visual_coords` breaking condition
* refactor: use `pos_at_visual_coords` in `text_pos_at_screen_coords`
* feat: make `copy_selection_on_line` aware of wide characters
Diffstat (limited to 'helix-view')
-rw-r--r-- | helix-view/src/view.rs | 53 |
1 files changed, 12 insertions, 41 deletions
diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index a496fe33..bfae12a4 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -1,15 +1,9 @@ -use std::borrow::Cow; - use crate::{ graphics::Rect, gutter::{self, Gutter}, Document, DocumentId, ViewId, }; -use helix_core::{ - graphemes::{grapheme_width, RopeGraphemes}, - line_ending::line_end_char_index, - visual_coords_at_pos, Position, RopeSlice, Selection, -}; +use helix_core::{pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection}; use std::fmt; @@ -251,44 +245,21 @@ impl View { return None; } - let line_number = (row - inner.y) as usize + self.offset.row; - - if line_number > text.len_lines() - 1 { + let text_row = (row - inner.y) as usize + self.offset.row; + if text_row > text.len_lines() - 1 { return Some(text.len_chars()); } - let mut pos = text.line_to_char(line_number); - - let current_line = text.line(line_number); - - let target = (column - inner.x) as usize + self.offset.col; - let mut col = 0; - - // TODO: extract this part as pos_at_visual_coords - for grapheme in RopeGraphemes::new(current_line) { - if col >= target { - break; - } - - let width = if grapheme == "\t" { - tab_width - (col % tab_width) - } else { - let grapheme = Cow::from(grapheme); - grapheme_width(&grapheme) - }; - - // If pos is in the middle of a wider grapheme (tab for example) - // return the starting offset. - if col + width > target { - break; - } + let text_col = (column - inner.x) as usize + self.offset.col; - col += width; - // TODO: use byte pos that converts back to char pos? - pos += grapheme.chars().count(); - } - - Some(pos.min(line_end_char_index(&text.slice(..), line_number))) + Some(pos_at_visual_coords( + *text, + Position { + row: text_row, + col: text_col, + }, + tab_width, + )) } /// Translates a screen position to position in the text document. |