summaryrefslogtreecommitdiff
path: root/helix-view
diff options
context:
space:
mode:
authorMatthew Toohey2022-06-21 16:36:36 +0000
committerGitHub2022-06-21 16:36:36 +0000
commit6a3f7f2c399f0b92cef97b0c85ebe976fd7cfcac (patch)
treec350427ff1949f6e95464227ca0583bce8400c70 /helix-view
parentfa4934cff9aa5b86b907e218313a7b370962ae67 (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.rs53
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.