Add the '%' (current filename) register

This register also comes from Kakoune. It's read-only and produces the
current document's name, defaulting to the scratch buffer name
constant.

(Also see PR5577.)

Co-authored-by: Ivan Tham <pickfire@riseup.net>
pull/7793/head
Michael Davis 1 year ago committed by Blaž Hrastnik
parent da2afe7353
commit 32d071a392

@ -2,7 +2,7 @@ use std::{borrow::Cow, collections::HashMap, iter};
use anyhow::Result; use anyhow::Result;
use crate::Editor; use crate::{document::SCRATCH_BUFFER_NAME, Editor};
/// A key-value store for saving sets of values. /// A key-value store for saving sets of values.
/// ///
@ -13,6 +13,7 @@ use crate::Editor;
/// * Black hole (`_`): all values read and written are discarded /// * Black hole (`_`): all values read and written are discarded
/// * Selection indices (`#`): index number of each selection starting at 1 /// * Selection indices (`#`): index number of each selection starting at 1
/// * Selection contents (`.`) /// * Selection contents (`.`)
/// * Document path (`%`): filename of the current buffer
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Registers { pub struct Registers {
inner: HashMap<char, Vec<String>>, inner: HashMap<char, Vec<String>>,
@ -36,6 +37,17 @@ impl Registers {
let text = doc.text().slice(..); let text = doc.text().slice(..);
Some(RegisterValues::new(doc.selection(view.id).fragments(text))) Some(RegisterValues::new(doc.selection(view.id).fragments(text)))
} }
'%' => {
let doc = doc!(editor);
let path = doc
.path()
.as_ref()
.map(|p| p.to_string_lossy())
.unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());
Some(RegisterValues::new(iter::once(path)))
}
_ => self _ => self
.inner .inner
.get(&name) .get(&name)
@ -46,7 +58,7 @@ impl Registers {
pub fn write(&mut self, name: char, values: Vec<String>) -> Result<()> { pub fn write(&mut self, name: char, values: Vec<String>) -> Result<()> {
match name { match name {
'_' => Ok(()), '_' => Ok(()),
'#' | '.' => Err(anyhow::anyhow!("Register {name} does not support writing")), '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support writing")),
_ => { _ => {
self.inner.insert(name, values); self.inner.insert(name, values);
Ok(()) Ok(())
@ -57,7 +69,7 @@ impl Registers {
pub fn push(&mut self, name: char, value: String) -> Result<()> { pub fn push(&mut self, name: char, value: String) -> Result<()> {
match name { match name {
'_' => Ok(()), '_' => Ok(()),
'#' | '.' => Err(anyhow::anyhow!("Register {name} does not support pushing")), '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support pushing")),
_ => { _ => {
self.inner.entry(name).or_insert_with(Vec::new).push(value); self.inner.entry(name).or_insert_with(Vec::new).push(value);
Ok(()) Ok(())
@ -89,6 +101,7 @@ impl Registers {
('_', "<empty>"), ('_', "<empty>"),
('#', "<selection indices>"), ('#', "<selection indices>"),
('.', "<selection contents>"), ('.', "<selection contents>"),
('%', "<document path>"),
] ]
.iter() .iter()
.copied(), .copied(),
@ -101,7 +114,7 @@ impl Registers {
pub fn remove(&mut self, name: char) -> bool { pub fn remove(&mut self, name: char) -> bool {
match name { match name {
'_' | '#' | '.' => false, '_' | '#' | '.' | '%' => false,
_ => self.inner.remove(&name).is_some(), _ => self.inner.remove(&name).is_some(),
} }
} }

Loading…
Cancel
Save