Unnamed repository; edit this file 'description' to name the repository.
Registers: Reverse first/last and rename to latest/oldest
The `first`/`last` names exposed some internal implementation details that changed in the parent commit. The `latest`/`oldest` functions return the same as `first`/`last` before the parent commit and now have their names switched to focus on what they return about the register rather than internal register ordering details.
Michael Davis 2024-07-16
parent 0c2cf39 · commit f466212
-rw-r--r--helix-term/src/commands.rs4
-rw-r--r--helix-term/src/ui/prompt.rs4
-rw-r--r--helix-view/src/register.rs51
3 files changed, 52 insertions, 7 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 23490288..a8f6543f 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -2125,7 +2125,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
.unwrap_or(cx.editor.registers.last_search_register);
let config = cx.editor.config();
let scrolloff = config.scrolloff;
- if let Some(query) = cx.editor.registers.first(register, cx.editor) {
+ if let Some(query) = cx.editor.registers.latest(register, cx.editor) {
let search_config = &config.search;
let case_insensitive = if search_config.smart_case {
!query.chars().any(char::is_uppercase)
@@ -2205,7 +2205,7 @@ fn make_search_word_bounded(cx: &mut Context) {
let register = cx
.register
.unwrap_or(cx.editor.registers.last_search_register);
- let regex = match cx.editor.registers.first(register, cx.editor) {
+ let regex = match cx.editor.registers.latest(register, cx.editor) {
Some(regex) => regex,
None => return,
};
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 3518ddf7..ba0dd21d 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -133,7 +133,7 @@ impl Prompt {
editor: &'a Editor,
) -> Option<Cow<'a, str>> {
self.history_register
- .and_then(|reg| editor.registers.first(reg, editor))
+ .and_then(|reg| editor.registers.latest(reg, editor))
}
pub fn recalculate_completion(&mut self, editor: &Editor) {
@@ -656,7 +656,7 @@ impl Component for Prompt {
&context
.editor
.registers
- .first(c, context.editor)
+ .latest(c, context.editor)
.unwrap_or_default(),
context.editor,
);
diff --git a/helix-view/src/register.rs b/helix-view/src/register.rs
index 050a4e4c..edad8b1e 100644
--- a/helix-view/src/register.rs
+++ b/helix-view/src/register.rs
@@ -216,14 +216,59 @@ impl Registers {
}
}
- pub fn first<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {
- self.read(name, editor).and_then(|mut values| values.next())
+ /// "Selects" the index at the given index for the given register.
+ ///
+ /// Selecting an item pulls it to the front of the register's history.
+ ///
+ /// If the register is a special register other than a clipboard register ('+' or '*')
+ /// or if the index is out of bounds for the given register, this command is a no-op.
+ pub fn select_history_entry(&mut self, name: char, index: usize) -> Result<()> {
+ match name {
+ '_' | '#' | '.' | '%' => {
+ Err(anyhow::anyhow!("Register {name} does not support writing"))
+ }
+ _ => {
+ let Some(register) = self.inner.get_mut(&name) else {
+ return Ok(());
+ };
+ register.select_history_entry(index);
+ self.sync_clipboard_register(name)
+ }
+ }
}
- pub fn last<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {
+ fn sync_clipboard_register(&mut self, name: char) -> Result<()> {
+ let clipboard_type = match name {
+ '+' => ClipboardType::Clipboard,
+ '*' => ClipboardType::Selection,
+ _ => return Ok(()),
+ };
+
+ let mut contents = String::new();
+ for val in self.inner[&name].values() {
+ if !contents.is_empty() {
+ contents.push_str(NATIVE_LINE_ENDING.as_str());
+ }
+ contents.push_str(&val);
+ }
+ self.clipboard_provider
+ .set_contents(contents, clipboard_type)
+ }
+
+ /// Returns the latest value in the given register.
+ ///
+ /// The latest value is the value most recently pushed to the register when
+ /// using `push`, or the last value returned by the iterator passed to [write].
+ pub fn latest<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {
self.read(name, editor).and_then(|values| values.last())
}
+ /// Returns the oldest value in the given register.
+ /// This is the opposite of `latest`.
+ pub fn oldest<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {
+ self.read(name, editor).and_then(|mut values| values.next())
+ }
+
pub fn iter_preview(&self) -> impl Iterator<Item = (char, &str)> {
self.inner
.iter()