aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorMatthew Toohey2022-06-21 16:36:36 +0000
committerGitHub2022-06-21 16:36:36 +0000
commit6a3f7f2c399f0b92cef97b0c85ebe976fd7cfcac (patch)
treec350427ff1949f6e95464227ca0583bce8400c70 /helix-term
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-term')
-rw-r--r--helix-term/src/commands.rs26
1 files changed, 14 insertions, 12 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 046351a3..d7937ff5 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -16,14 +16,14 @@ use helix_core::{
line_ending::{get_line_ending_of_str, line_end_char_index, str_is_line_ending},
match_brackets,
movement::{self, Direction},
- object, pos_at_coords,
+ object, pos_at_coords, pos_at_visual_coords,
regex::{self, Regex, RegexBuilder},
search::{self, CharMatcher},
selection, shellwords, surround, textobject,
tree_sitter::Node,
unicode::width::UnicodeWidthChar,
- LineEnding, Position, Range, Rope, RopeGraphemes, RopeSlice, Selection, SmallVec, Tendril,
- Transaction,
+ visual_coords_at_pos, LineEnding, Position, Range, Rope, RopeGraphemes, RopeSlice, Selection,
+ SmallVec, Tendril, Transaction,
};
use helix_view::{
clipboard::ClipboardType,
@@ -511,7 +511,7 @@ fn no_op(_cx: &mut Context) {}
fn move_impl<F>(cx: &mut Context, move_fn: F, dir: Direction, behaviour: Movement)
where
- F: Fn(RopeSlice, Range, Direction, usize, Movement) -> Range,
+ F: Fn(RopeSlice, Range, Direction, usize, Movement, usize) -> Range,
{
let count = cx.count();
let (view, doc) = current!(cx.editor);
@@ -520,7 +520,7 @@ where
let selection = doc
.selection(view.id)
.clone()
- .transform(|range| move_fn(text, range, dir, count, behaviour));
+ .transform(|range| move_fn(text, range, dir, count, behaviour, doc.tab_width()));
doc.set_selection(view.id, selection);
}
@@ -1412,9 +1412,10 @@ fn copy_selection_on_line(cx: &mut Context, direction: Direction) {
range.head
};
- // TODO: this should use visual offsets / pos_at_screen_coords
- let head_pos = coords_at_pos(text, head);
- let anchor_pos = coords_at_pos(text, range.anchor);
+ let tab_width = doc.tab_width();
+
+ let head_pos = visual_coords_at_pos(text, head, tab_width);
+ let anchor_pos = visual_coords_at_pos(text, range.anchor, tab_width);
let height = std::cmp::max(head_pos.row, anchor_pos.row)
- std::cmp::min(head_pos.row, anchor_pos.row)
@@ -1444,12 +1445,13 @@ fn copy_selection_on_line(cx: &mut Context, direction: Direction) {
break;
}
- let anchor = pos_at_coords(text, Position::new(anchor_row, anchor_pos.col), true);
- let head = pos_at_coords(text, Position::new(head_row, head_pos.col), true);
+ let anchor =
+ pos_at_visual_coords(text, Position::new(anchor_row, anchor_pos.col), tab_width);
+ let head = pos_at_visual_coords(text, Position::new(head_row, head_pos.col), tab_width);
// skip lines that are too short
- if coords_at_pos(text, anchor).col == anchor_pos.col
- && coords_at_pos(text, head).col == head_pos.col
+ if visual_coords_at_pos(text, anchor, tab_width).col == anchor_pos.col
+ && visual_coords_at_pos(text, head, tab_width).col == head_pos.col
{
if is_primary {
primary_index = ranges.len();