From 5972f66ef6b2a845661f04b7064c5eb29f89788e Mon Sep 17 00:00:00 2001 From: ath3 Date: Thu, 25 Nov 2021 15:34:46 +0100 Subject: [PATCH] Implement black hole register --- book/src/usage.md | 2 ++ helix-core/src/register.rs | 40 ++++++++++++++++++++++++++----------- helix-term/src/commands.rs | 7 ++++--- helix-term/src/ui/prompt.rs | 19 ++++++++++-------- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/book/src/usage.md b/book/src/usage.md index 6b7cbc415e5c4..cf7d9d488309a 100644 --- a/book/src/usage.md +++ b/book/src/usage.md @@ -23,8 +23,10 @@ If there is a selected register before invoking a change or delete command, the | `/` | Last search | | `:` | Last executed command | | `"` | Last yanked text | +| `_` | Black hole | > There is no special register for copying to system clipboard, instead special commands and keybindings are provided. See the [keymap](keymap.md#space-mode) for the specifics. +> The black hole register works as a no-op register, meaning no data will be written to / read from it. ## Surround diff --git a/helix-core/src/register.rs b/helix-core/src/register.rs index c5444eb73856a..439ccddd349d7 100644 --- a/helix-core/src/register.rs +++ b/helix-core/src/register.rs @@ -7,15 +7,23 @@ pub struct Register { } impl Register { - pub const fn new(name: char) -> Self { - Self { - name, - values: Vec::new(), + pub const fn new(name: char) -> Option { + if name != '_' { + Some(Self { + name, + values: Vec::new(), + }) + } else { + None } } - pub fn new_with_values(name: char, values: Vec) -> Self { - Self { name, values } + pub fn new_with_values(name: char, values: Vec) -> Option { + if name != '_' { + Some(Self { name, values }) + } else { + None + } } pub const fn name(&self) -> char { @@ -46,15 +54,23 @@ impl Registers { self.inner.get(&name) } - pub fn get_mut(&mut self, name: char) -> &mut Register { - self.inner - .entry(name) - .or_insert_with(|| Register::new(name)) + pub fn get_mut(&mut self, name: char) -> Option<&mut Register> { + if name != '_' { + Some( + self.inner + .entry(name) + .or_insert_with(|| Register::new(name).unwrap()), + ) + } else { + None + } } pub fn write(&mut self, name: char, values: Vec) { - self.inner - .insert(name, Register::new_with_values(name, values)); + if name != '_' { + self.inner + .insert(name, Register::new_with_values(name, values).unwrap()); + } } pub fn read(&self, name: char) -> Option<&[String]> { diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ff8d7a4ffe83a..7243ce933d7aa 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1503,7 +1503,7 @@ fn search_selection(cx: &mut Context) { let contents = doc.text().slice(..); let query = doc.selection(view.id).primary().fragment(contents); let regex = regex::escape(&query); - cx.editor.registers.get_mut('/').push(regex); + cx.editor.registers.get_mut('/').unwrap().push(regex); let msg = format!("register '{}' set to '{}'", '\\', query); cx.editor.set_status(msg); } @@ -1710,8 +1710,9 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) { let values: Vec = selection.fragments(text).map(Cow::into_owned).collect(); let reg_name = cx.register.unwrap_or('"'); let registers = &mut cx.editor.registers; - let reg = registers.get_mut(reg_name); - reg.write(values); + if let Some(reg) = registers.get_mut(reg_name) { + reg.write(values); + } }; // then delete diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index e90b0772785ea..04043fc524a18 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -481,24 +481,27 @@ impl Component for Prompt { if let Some(register) = self.history_register { // store in history - let register = cx.editor.registers.get_mut(register); - register.push(self.line.clone()); + if let Some(register) = cx.editor.registers.get_mut(register) { + register.push(self.line.clone()); + } } return close_fn; } } ctrl!('p') | key!(Up) => { if let Some(register) = self.history_register { - let register = cx.editor.registers.get_mut(register); - self.change_history(register.read(), CompletionDirection::Backward); - (self.callback_fn)(cx, &self.line, PromptEvent::Update); + if let Some(register) = cx.editor.registers.get_mut(register) { + self.change_history(register.read(), CompletionDirection::Backward); + (self.callback_fn)(cx, &self.line, PromptEvent::Update); + } } } ctrl!('n') | key!(Down) => { if let Some(register) = self.history_register { - let register = cx.editor.registers.get_mut(register); - self.change_history(register.read(), CompletionDirection::Forward); - (self.callback_fn)(cx, &self.line, PromptEvent::Update); + if let Some(register) = cx.editor.registers.get_mut(register) { + self.change_history(register.read(), CompletionDirection::Forward); + (self.callback_fn)(cx, &self.line, PromptEvent::Update); + } } } key!(Tab) => {