diff options
author | Michael Davis | 2023-02-07 03:43:48 +0000 |
---|---|---|
committer | GitHub | 2023-02-07 03:43:48 +0000 |
commit | 23ed8c12f17c28ee888b5560d0ab2a9f9cd74dc9 (patch) | |
tree | cb233f45dd46fe84dd10c22e18fa14be8961b6ce | |
parent | f71f27f804016aa7a8e3517cebeef0861088fb0f (diff) |
Select change range for goto_first/last_change commands (#5206)
This matches the behavior from 42ad1a9e043e2e0fb148924ff79b9abbe06907ae
but for the first and last change. The selection rules are the same
as for goto_next/prev_change: additions and modifications select the
added and modified range while deletions are represented with a point.
-rw-r--r-- | helix-term/src/commands.rs | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index d1dc9223..157d19f7 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2927,14 +2927,6 @@ fn exit_select_mode(cx: &mut Context) { } } -fn goto_pos(editor: &mut Editor, pos: usize) { - let (view, doc) = current!(editor); - - push_jump(view, doc); - doc.set_selection(view.id, Selection::point(pos)); - align_view(doc, view, Align::Center); -} - fn goto_first_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); let selection = match doc.diagnostics().first() { @@ -3012,7 +3004,7 @@ fn goto_last_change(cx: &mut Context) { fn goto_first_change_impl(cx: &mut Context, reverse: bool) { let editor = &mut cx.editor; - let (_, doc) = current!(editor); + let (view, doc) = current!(editor); if let Some(handle) = doc.diff_handle() { let hunk = { let hunks = handle.hunks(); @@ -3024,8 +3016,8 @@ fn goto_first_change_impl(cx: &mut Context, reverse: bool) { hunks.nth_hunk(idx) }; if hunk != Hunk::NONE { - let pos = doc.text().line_to_char(hunk.after.start as usize); - goto_pos(editor, pos) + let range = hunk_range(hunk, doc.text().slice(..)); + doc.set_selection(view.id, Selection::single(range.anchor, range.head)); } } } @@ -3069,14 +3061,7 @@ fn goto_next_change_impl(cx: &mut Context, direction: Direction) { return range; }; let hunk = hunks.nth_hunk(hunk_idx); - - let hunk_start = doc_text.line_to_char(hunk.after.start as usize); - let hunk_end = if hunk.after.is_empty() { - hunk_start + 1 - } else { - doc_text.line_to_char(hunk.after.end as usize) - }; - let new_range = Range::new(hunk_start, hunk_end); + let new_range = hunk_range(hunk, doc_text); if editor.mode == Mode::Select { let head = if new_range.head < range.anchor { new_range.anchor @@ -3096,6 +3081,20 @@ fn goto_next_change_impl(cx: &mut Context, direction: Direction) { cx.editor.last_motion = Some(Motion(Box::new(motion))); } +/// Returns the [Range] for a [Hunk] in the given text. +/// Additions and modifications cover the added and modified ranges. +/// Deletions are represented as the point at the start of the deletion hunk. +fn hunk_range(hunk: Hunk, text: RopeSlice) -> Range { + let anchor = text.line_to_char(hunk.after.start as usize); + let head = if hunk.after.is_empty() { + anchor + 1 + } else { + text.line_to_char(hunk.after.end as usize) + }; + + Range::new(anchor, head) +} + pub mod insert { use super::*; pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>; |