diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index b1c29378d..d16fd7764 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -400,6 +400,8 @@ impl MappableCommand { goto_implementation, "Goto implementation", goto_file_start, "Goto line number else file start", goto_file_end, "Goto file end", + extend_file_start, "Extend to line number else file start", + extend_file_end, "Extend to file end", goto_file, "Goto files/URLs in selections", goto_file_hsplit, "Goto files in selections (hsplit)", goto_file_vsplit, "Goto files in selections (vsplit)", @@ -1222,28 +1224,58 @@ fn goto_next_paragraph(cx: &mut Context) { } fn goto_file_start(cx: &mut Context) { + goto_file_start_impl( + cx, + if cx.editor.mode == Mode::Select { + Movement::Extend + } else { + Movement::Move + }, + ); +} + +fn extend_file_start(cx: &mut Context) { + goto_file_start_impl(cx, Movement::Extend); +} + +fn goto_file_start_impl(cx: &mut Context, movement: Movement) { if cx.count.is_some() { - goto_line(cx); + goto_line_impl(cx, movement); } else { let (view, doc) = current!(cx.editor); let text = doc.text().slice(..); let selection = doc .selection(view.id) .clone() - .transform(|range| range.put_cursor(text, 0, cx.editor.mode == Mode::Select)); + .transform(|range| range.put_cursor(text, 0, movement == Movement::Extend)); push_jump(view, doc); doc.set_selection(view.id, selection); } } fn goto_file_end(cx: &mut Context) { + goto_file_end_impl( + cx, + if cx.editor.mode == Mode::Select { + Movement::Extend + } else { + Movement::Move + }, + ); +} + +fn extend_file_end(cx: &mut Context) { + goto_file_end_impl(cx, Movement::Extend) +} + +fn goto_file_end_impl(cx: &mut Context, movement: Movement) { let (view, doc) = current!(cx.editor); let text = doc.text().slice(..); let pos = doc.text().len_chars(); let selection = doc .selection(view.id) .clone() - .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select)); + .transform(|range| range.put_cursor(text, pos, movement == Movement::Extend)); push_jump(view, doc); doc.set_selection(view.id, selection); } @@ -3525,15 +3557,30 @@ fn push_jump(view: &mut View, doc: &Document) { } fn goto_line(cx: &mut Context) { + goto_line_impl( + cx, + if cx.editor.mode == Mode::Select { + Movement::Extend + } else { + Movement::Move + }, + ); +} + +fn goto_line_impl(cx: &mut Context, movement: Movement) { if cx.count.is_some() { let (view, doc) = current!(cx.editor); push_jump(view, doc); - goto_line_without_jumplist(cx.editor, cx.count); + goto_line_without_jumplist(cx.editor, cx.count, movement); } } -fn goto_line_without_jumplist(editor: &mut Editor, count: Option) { +fn goto_line_without_jumplist( + editor: &mut Editor, + count: Option, + movement: Movement, +) { if let Some(count) = count { let (view, doc) = current!(editor); let text = doc.text().slice(..); @@ -3548,7 +3595,7 @@ fn goto_line_without_jumplist(editor: &mut Editor, count: Option) let selection = doc .selection(view.id) .clone() - .transform(|range| range.put_cursor(text, pos, editor.mode == Mode::Select)); + .transform(|range| range.put_cursor(text, pos, movement == Movement::Extend)); doc.set_selection(view.id, selection); } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 7ad0369fc..6703fe2ca 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1814,7 +1814,15 @@ fn update_goto_line_number_preview( let scrolloff = cx.editor.config().scrolloff; let line = args[0].parse::()?; - goto_line_without_jumplist(cx.editor, NonZeroUsize::new(line)); + goto_line_without_jumplist( + cx.editor, + NonZeroUsize::new(line), + if cx.editor.mode == Mode::Select { + Movement::Extend + } else { + Movement::Move + }, + ); let (view, doc) = current!(cx.editor); view.ensure_cursor_in_view(doc, scrolloff);