@@ -11,15 +11,31 @@ use crate::Editor;
1111/// behaviors when read or written to:
1212///
1313/// * Black hole (`_`): all values read and written are discarded
14+/// * Selection indices (`#`): index number of each selection starting at 1
15+/// * Selection contents (`.`)
1416#[derive(Debug, Default)]
1517pub struct Registers {
1618 inner: HashMap<char, Vec<String>>,
1719}
1820
1921impl Registers {
20− pub fn read<'a>(&'a self, name: char, _editor: &'a Editor) -> Option<RegisterValues<'a>> {
22+ pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option<RegisterValues<'a>> {
2123 match name {
2224 '_' => Some(RegisterValues::new(iter::empty())),
25+ '#' => {
26+ let (view, doc) = current_ref!(editor);
27+ let selections = doc.selection(view.id).len();
28+ // ExactSizeIterator is implemented for Range<usize> but
29+ // not RangeInclusive<usize>.
30+ Some(RegisterValues::new(
31+ (0..selections).map(|i| (i + 1).to_string().into()),
32+ ))
33+ }
34+ '.' => {
35+ let (view, doc) = current_ref!(editor);
36+ let text = doc.text().slice(..);
37+ Some(RegisterValues::new(doc.selection(view.id).fragments(text)))
38+ }
2339 _ => self
2440 .inner
2541 .get(&name)
@@ -30,6 +46,7 @@ impl Registers {
3046 pub fn write(&mut self, name: char, values: Vec<String>) -> Result<()> {
3147 match name {
3248 '_' => Ok(()),
49+ '#' | '.' => Err(anyhow::anyhow!("Register {name} does not support writing")),
3350 _ => {
3451 self.inner.insert(name, values);
3552 Ok(())
@@ -40,6 +57,7 @@ impl Registers {
4057 pub fn push(&mut self, name: char, value: String) -> Result<()> {
4158 match name {
4259 '_' => Ok(()),
60+ '#' | '.' => Err(anyhow::anyhow!("Register {name} does not support pushing")),
4361 _ => {
4462 self.inner.entry(name).or_insert_with(Vec::new).push(value);
4563 Ok(())
@@ -66,7 +84,15 @@ impl Registers {
6684
6785 (*name, preview)
6886 })
69− .chain([('_', "<empty>")].iter().copied())
87+ .chain(
88+ [
89+ ('_', "<empty>"),
90+ ('#', "<selection indices>"),
91+ ('.', "<selection contents>"),
92+ ]
93+ .iter()
94+ .copied(),
95+ )
7096 }
7197
7298 pub fn clear(&mut self) {
@@ -75,7 +101,7 @@ impl Registers {
75101
76102 pub fn remove(&mut self, name: char) -> bool {
77103 match name {
78− '_' => false,
104+ '_' | '#' | '.' => false,
79105 _ => self.inner.remove(&name).is_some(),
80106 }
81107 }