From 8f037bd8f7eae96f545a4a21092d3d91f78addfd Mon Sep 17 00:00:00 2001 From: Axlefublr Date: Sat, 7 Feb 2026 18:42:47 +0800 Subject: [PATCH] prompts deduplicate their history --- helix-term/src/ui/prompt.rs | 2 +- helix-view/src/register.rs | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 50176d5836cd..801388d6aef7 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -686,7 +686,7 @@ impl Component for Prompt { // store in history if let Some(register) = self.history_register { if let Err(err) = - cx.editor.registers.push(register, self.line.clone()) + cx.editor.registers.push_unique(register, self.line.clone()) { cx.editor.set_error(err.to_string()); } diff --git a/helix-view/src/register.rs b/helix-view/src/register.rs index b2bb53ac2029..dc83b3cb7912 100644 --- a/helix-view/src/register.rs +++ b/helix-view/src/register.rs @@ -102,7 +102,7 @@ impl Registers { } } - pub fn push(&mut self, name: char, mut value: String) -> Result<()> { + fn push_impl(&mut self, name: char, mut value: String, unique: bool) -> Result<()> { match name { '_' => Ok(()), '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support pushing")), @@ -122,6 +122,9 @@ impl Registers { anyhow::bail!("Failed to push to register {name}: clipboard does not match register contents"); } + if unique { + saved_values.retain(|the| the != &value); + } saved_values.push(value.clone()); if !contents.is_empty() { value.push_str(NATIVE_LINE_ENDING.as_str()); @@ -134,12 +137,24 @@ impl Registers { Ok(()) } _ => { - self.inner.entry(name).or_default().push(value); + let the = self.inner.entry(name).or_default(); + if unique { + the.retain(|the| the != &value); + } + the.push(value); Ok(()) } } } + pub fn push_unique(&mut self, name: char, value: String) -> Result<()> { + self.push_impl(name, value, true) + } + + pub fn push(&mut self, name: char, value: String) -> Result<()> { + self.push_impl(name, value, false) + } + pub fn first<'a>(&'a self, name: char, editor: &'a Editor) -> Option> { self.read(name, editor).and_then(|mut values| values.next()) }