diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index f4fcb6f62..5b8e27075 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -84,5 +84,6 @@ | `:run-shell-command`, `:sh` | Run a shell command | | `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. | | `:clear-register` | Clear given register. If no argument is provided, clear all registers. | +| `:clear-jumplist`, `:clj` | Pops items from the jump list. If not argument is provided, clear the jump list. | | `:redraw` | Clear and re-render the whole UI | | `:move` | Move the current buffer and its corresponding file to a different path | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index f530ce10d..ef976d50d 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2385,6 +2385,32 @@ fn clear_register( Ok(()) } +fn clear_jumplist( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + ensure!(args.len() <= 1, ":clear-jumplist takes at most 1 argument"); + + let doc = doc!(cx.editor); + let view = view_mut!(cx.editor); + let selection = doc.selection(view.id); + if args.len() == 1 { + let to_remove = args[0].parse::()?; + view.jumps.remove_from_head(to_remove); + } else { + view.jumps.clear(); + } + if view.jumps.len() == 0 { + // Fixup cases where the jumplist is emptied into an invalid state + view.jumps.push((doc.id(), selection.clone())); + } + Ok(()) +} + fn redraw( cx: &mut compositor::Context, _args: &[Cow], @@ -3075,6 +3101,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: clear_register, signature: CommandSignature::none(), }, + TypableCommand { + name: "clear-jumplist", + aliases: &["clj"], + doc: "Pops items from the jump list. If not argument is provided, clear the jump list.", + fun: clear_jumplist, + signature: CommandSignature::none(), + }, TypableCommand { name: "redraw", aliases: &[], diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index e5e2641a8..08ddeb93f 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -84,6 +84,23 @@ impl JumpList { self.jumps.iter() } + pub fn remove_from_head(&mut self, to_remove: usize) { + for _ in 0..to_remove { + if self.jumps.pop_front().is_none() { + break; + } + } + self.current = self.jumps.len(); + } + + pub fn clear(&mut self) { + self.jumps.clear(); + } + + pub fn len(&self) -> usize { + self.jumps.len() + } + /// Applies a [`Transaction`] of changes to the jumplist. /// This is necessary to ensure that changes to documents do not leave jump-list /// selections pointing to parts of the text which no longer exist.