on master help sign in
Do not add intermediate lines to jumplist with :<linenum> command. (#5751)
f4bdbe4Kyle Smith
helix-term/src/commands.rs+7−3
@@ -2828,10 +2828,15 @@ fn push_jump(view: &mut View, doc: &Document) {
2828}
2828}
2829
2829
2830fn goto_line(cx: &mut Context) {
2830fn goto_line(cx: &mut Context) {
2831− goto_line_impl(cx.editor, cx.count)
2831+ if cx.count.is_some() {
2832+ let (view, doc) = current!(cx.editor);
2833+ push_jump(view, doc);
2834+
2835+ goto_line_without_jumplist(cx.editor, cx.count);
2836+ }
2832}
2837}
2833
2838
2834−fn goto_line_impl(editor: &mut Editor, count: Option<NonZeroUsize>) {
2839+fn goto_line_without_jumplist(editor: &mut Editor, count: Option<NonZeroUsize>) {
2835 if let Some(count) = count {
2840 if let Some(count) = count {
2836 let (view, doc) = current!(editor);
2841 let (view, doc) = current!(editor);
2837 let text = doc.text().slice(..);
2842 let text = doc.text().slice(..);
@@ -2848,7 +2853,6 @@ fn goto_line_impl(editor: &mut Editor, count: Option<NonZeroUsize>) {
2848 .clone()
2853 .clone()
2849 .transform(|range| range.put_cursor(text, pos, editor.mode == Mode::Select));
2854 .transform(|range| range.put_cursor(text, pos, editor.mode == Mode::Select));
2850
2855
2851− push_jump(view, doc);
2852 doc.set_selection(view.id, selection);
2856 doc.set_selection(view.id, selection);
2853 }
2857 }
2854}
2858}
helix-term/src/commands/typed.rs+50−30
@@ -1572,47 +1572,67 @@ fn tutor(
1572 Ok(())
1572 Ok(())
1573}
1573}
1574
1574
1575+fn abort_goto_line_number_preview(cx: &mut compositor::Context) {
1576+ if let Some(last_selection) = cx.editor.last_selection.take() {
1577+ let scrolloff = cx.editor.config().scrolloff;
1578+
1579+ let (view, doc) = current!(cx.editor);
1580+ doc.set_selection(view.id, last_selection);
1581+ view.ensure_cursor_in_view(doc, scrolloff);
1582+ }
1583+}
1584+
1585+fn update_goto_line_number_preview(
1586+ cx: &mut compositor::Context,
1587+ args: &[Cow<str>],
1588+) -> anyhow::Result<()> {
1589+ cx.editor.last_selection.get_or_insert_with(|| {
1590+ let (view, doc) = current!(cx.editor);
1591+ doc.selection(view.id).clone()
1592+ });
1593+
1594+ let scrolloff = cx.editor.config().scrolloff;
1595+ let line = args[0].parse::<usize>()?;
1596+ goto_line_without_jumplist(cx.editor, NonZeroUsize::new(line));
1597+
1598+ let (view, doc) = current!(cx.editor);
1599+ view.ensure_cursor_in_view(doc, scrolloff);
1600+
1601+ Ok(())
1602+}
1603+
1575pub(super) fn goto_line_number(
1604pub(super) fn goto_line_number(
1576 cx: &mut compositor::Context,
1605 cx: &mut compositor::Context,
1577 args: &[Cow<str>],
1606 args: &[Cow<str>],
1578 event: PromptEvent,
1607 event: PromptEvent,
1579) -> anyhow::Result<()> {
1608) -> anyhow::Result<()> {
1580 match event {
1609 match event {
1581− PromptEvent::Abort => {
1610+ PromptEvent::Abort => abort_goto_line_number_preview(cx),
1582− if let Some(line_number) = cx.editor.last_line_number {
1583− goto_line_impl(cx.editor, NonZeroUsize::new(line_number));
1584− let (view, doc) = current!(cx.editor);
1585− view.ensure_cursor_in_view(doc, line_number);
1586− cx.editor.last_line_number = None;
1587− }
1588− return Ok(());
1589− }
1590 PromptEvent::Validate => {
1611 PromptEvent::Validate => {
1591 ensure!(!args.is_empty(), "Line number required");
1612 ensure!(!args.is_empty(), "Line number required");
1592− cx.editor.last_line_number = None;
1613+
1593− }
1614+ // If we are invoked directly via a keybinding, Validate is
1594− PromptEvent::Update => {
1615+ // sent without any prior Update events. Ensure the cursor
1595− if args.is_empty() {
1616+ // is moved to the appropriate location.
1596− if let Some(line_number) = cx.editor.last_line_number {
1617+ update_goto_line_number_preview(cx, args)?;
1597− // When a user hits backspace and there are no numbers left,
1618+
1598− // we can bring them back to their original line
1619+ let last_selection = cx
1599− goto_line_impl(cx.editor, NonZeroUsize::new(line_number));
1620+ .editor
1600− let (view, doc) = current!(cx.editor);
1621+ .last_selection
1601− view.ensure_cursor_in_view(doc, line_number);
1622+ .take()
1602− cx.editor.last_line_number = None;
1623+ .expect("update_goto_line_number_preview should always set last_selection");
1603− }
1624+
1604− return Ok(());
1605− }
1606 let (view, doc) = current!(cx.editor);
1625 let (view, doc) = current!(cx.editor);
1607− let text = doc.text().slice(..);
1626+ view.jumps.push((doc.id(), last_selection));
1608− let line = doc.selection(view.id).primary().cursor_line(text);
1609− cx.editor.last_line_number.get_or_insert(line + 1);
1610 }
1627 }
1628+
1629+ // When a user hits backspace and there are no numbers left,
1630+ // we can bring them back to their original selection. If they
1631+ // begin typing numbers again, we'll start a new preview session.
1632+ PromptEvent::Update if args.is_empty() => abort_goto_line_number_preview(cx),
1633+ PromptEvent::Update => update_goto_line_number_preview(cx, args)?,
1611 }
1634 }
1612− let line = args[0].parse::<usize>()?;
1635+
1613− goto_line_impl(cx.editor, NonZeroUsize::new(line));
1614− let (view, doc) = current!(cx.editor);
1615− view.ensure_cursor_in_view(doc, line);
1616 Ok(())
1636 Ok(())
1617}
1637}
1618
1638
helix-view/src/editor.rs+8−3
@@ -40,12 +40,12 @@ use anyhow::{anyhow, bail, Error};
40
40
41pub use helix_core::diagnostic::Severity;
41pub use helix_core::diagnostic::Severity;
42pub use helix_core::register::Registers;
42pub use helix_core::register::Registers;
43−use helix_core::Position;
44use helix_core::{
43use helix_core::{
45 auto_pairs::AutoPairs,
44 auto_pairs::AutoPairs,
46 syntax::{self, AutoPairConfig},
45 syntax::{self, AutoPairConfig},
47 Change,
46 Change,
48};
47};
48+use helix_core::{Position, Selection};
49use helix_dap as dap;
49use helix_dap as dap;
50use helix_lsp::lsp;
50use helix_lsp::lsp;
51
51
@@ -848,7 +848,12 @@ pub struct Editor {
848 /// The currently applied editor theme. While previewing a theme, the previewed theme
848 /// The currently applied editor theme. While previewing a theme, the previewed theme
849 /// is set here.
849 /// is set here.
850 pub theme: Theme,
850 pub theme: Theme,
851− pub last_line_number: Option<usize>,
851+
852+ /// The primary Selection prior to starting a goto_line_number preview. This is
853+ /// restored when the preview is aborted, or added to the jumplist when it is
854+ /// confirmed.
855+ pub last_selection: Option<Selection>,
856+
852 pub status_msg: Option<(Cow<'static, str>, Severity)>,
857 pub status_msg: Option<(Cow<'static, str>, Severity)>,
853 pub autoinfo: Option<Info>,
858 pub autoinfo: Option<Info>,
854
859
@@ -964,7 +969,7 @@ impl Editor {
964 syn_loader,
969 syn_loader,
965 theme_loader,
970 theme_loader,
966 last_theme: None,
971 last_theme: None,
967− last_line_number: None,
972+ last_selection: None,
968 registers: Registers::default(),
973 registers: Registers::default(),
969 clipboard_provider: get_clipboard_provider(),
974 clipboard_provider: get_clipboard_provider(),
970 status_msg: None,
975 status_msg: None,