@@ -2927,14 +2927,6 @@ fn exit_select_mode(cx: &mut Context) {
29272927 }
29282928}
29292929
2930−fn goto_pos(editor: &mut Editor, pos: usize) {
2931− let (view, doc) = current!(editor);
2932−
2933− push_jump(view, doc);
2934− doc.set_selection(view.id, Selection::point(pos));
2935− align_view(doc, view, Align::Center);
2936−}
2937−
29382930fn goto_first_diag(cx: &mut Context) {
29392931 let (view, doc) = current!(cx.editor);
29402932 let selection = match doc.diagnostics().first() {
@@ -3012,7 +3004,7 @@ fn goto_last_change(cx: &mut Context) {
30123004
30133005fn goto_first_change_impl(cx: &mut Context, reverse: bool) {
30143006 let editor = &mut cx.editor;
3015− let (_, doc) = current!(editor);
3007+ let (view, doc) = current!(editor);
30163008 if let Some(handle) = doc.diff_handle() {
30173009 let hunk = {
30183010 let hunks = handle.hunks();
@@ -3024,8 +3016,8 @@ fn goto_first_change_impl(cx: &mut Context, reverse: bool) {
30243016 hunks.nth_hunk(idx)
30253017 };
30263018 if hunk != Hunk::NONE {
3027− let pos = doc.text().line_to_char(hunk.after.start as usize);
3028− goto_pos(editor, pos)
3019+ let range = hunk_range(hunk, doc.text().slice(..));
3020+ doc.set_selection(view.id, Selection::single(range.anchor, range.head));
30293021 }
30303022 }
30313023}
@@ -3069,14 +3061,7 @@ fn goto_next_change_impl(cx: &mut Context, direction: Direction) {
30693061 return range;
30703062 };
30713063 let hunk = hunks.nth_hunk(hunk_idx);
3072−
3073− let hunk_start = doc_text.line_to_char(hunk.after.start as usize);
3074− let hunk_end = if hunk.after.is_empty() {
3075− hunk_start + 1
3076− } else {
3077− doc_text.line_to_char(hunk.after.end as usize)
3078− };
3079− let new_range = Range::new(hunk_start, hunk_end);
3064+ let new_range = hunk_range(hunk, doc_text);
30803065 if editor.mode == Mode::Select {
30813066 let head = if new_range.head < range.anchor {
30823067 new_range.anchor
@@ -3096,6 +3081,20 @@ fn goto_next_change_impl(cx: &mut Context, direction: Direction) {
30963081 cx.editor.last_motion = Some(Motion(Box::new(motion)));
30973082}
30983083
3084+/// Returns the [Range] for a [Hunk] in the given text.
3085+/// Additions and modifications cover the added and modified ranges.
3086+/// Deletions are represented as the point at the start of the deletion hunk.
3087+fn hunk_range(hunk: Hunk, text: RopeSlice) -> Range {
3088+ let anchor = text.line_to_char(hunk.after.start as usize);
3089+ let head = if hunk.after.is_empty() {
3090+ anchor + 1
3091+ } else {
3092+ text.line_to_char(hunk.after.end as usize)
3093+ };
3094+
3095+ Range::new(anchor, head)
3096+}
3097+
30993098pub mod insert {
31003099 use super::*;
31013100 pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;