@@ -1572,47 +1572,67 @@ fn tutor(
15721572 Ok(())
15731573}
15741574
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+
15751604pub(super) fn goto_line_number(
15761605 cx: &mut compositor::Context,
15771606 args: &[Cow<str>],
15781607 event: PromptEvent,
15791608) -> anyhow::Result<()> {
15801609 match event {
1581− PromptEvent::Abort => {
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− }
1610+ PromptEvent::Abort => abort_goto_line_number_preview(cx),
15901611 PromptEvent::Validate => {
15911612 ensure!(!args.is_empty(), "Line number required");
1592− cx.editor.last_line_number = None;
1593− }
1594− PromptEvent::Update => {
1595− if args.is_empty() {
1596− if let Some(line_number) = cx.editor.last_line_number {
1597− // When a user hits backspace and there are no numbers left,
1598− // we can bring them back to their original line
1599− goto_line_impl(cx.editor, NonZeroUsize::new(line_number));
1600− let (view, doc) = current!(cx.editor);
1601− view.ensure_cursor_in_view(doc, line_number);
1602− cx.editor.last_line_number = None;
1603− }
1604− return Ok(());
1605− }
1613+
1614+ // If we are invoked directly via a keybinding, Validate is
1615+ // sent without any prior Update events. Ensure the cursor
1616+ // is moved to the appropriate location.
1617+ update_goto_line_number_preview(cx, args)?;
1618+
1619+ let last_selection = cx
1620+ .editor
1621+ .last_selection
1622+ .take()
1623+ .expect("update_goto_line_number_preview should always set last_selection");
1624+
16061625 let (view, doc) = current!(cx.editor);
1607− let text = doc.text().slice(..);
1608− let line = doc.selection(view.id).primary().cursor_line(text);
1609− cx.editor.last_line_number.get_or_insert(line + 1);
1626+ view.jumps.push((doc.id(), last_selection));
16101627 }
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)?,
16111634 }
1612− let line = args[0].parse::<usize>()?;
1613− goto_line_impl(cx.editor, NonZeroUsize::new(line));
1614− let (view, doc) = current!(cx.editor);
1615− view.ensure_cursor_in_view(doc, line);
1635+
16161636 Ok(())
16171637}
16181638