@ -11,15 +11,31 @@ use crate::Editor;
/// behaviors when read or written to:
/// behaviors when read or written to:
///
///
/// * 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 contents (`.`)
#[ derive(Debug, Default) ]
#[ derive(Debug, Default) ]
pub struct Registers {
pub struct Registers {
inner : HashMap < char , Vec < String > > ,
inner : HashMap < char , Vec < String > > ,
}
}
impl Registers {
impl Registers {
pub fn read < ' a > ( & ' a self , name : char , _ editor: & ' a Editor ) -> Option < RegisterValues < ' a > > {
pub fn read < ' a > ( & ' a self , name : char , editor: & ' a Editor ) -> Option < RegisterValues < ' a > > {
match name {
match name {
'_' = > Some ( RegisterValues ::new ( iter ::empty ( ) ) ) ,
'_' = > Some ( RegisterValues ::new ( iter ::empty ( ) ) ) ,
'#' = > {
let ( view , doc ) = current_ref ! ( editor ) ;
let selections = doc . selection ( view . id ) . len ( ) ;
// ExactSizeIterator is implemented for Range<usize> but
// not RangeInclusive<usize>.
Some ( RegisterValues ::new (
( 0 .. selections ) . map ( | i | ( i + 1 ) . to_string ( ) . into ( ) ) ,
) )
}
'.' = > {
let ( view , doc ) = current_ref ! ( editor ) ;
let text = doc . text ( ) . slice ( .. ) ;
Some ( RegisterValues ::new ( doc . selection ( view . id ) . fragments ( text ) ) )
}
_ = > self
_ = > self
. inner
. inner
. get ( & name )
. get ( & name )
@ -30,6 +46,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" ) ) ,
_ = > {
_ = > {
self . inner . insert ( name , values ) ;
self . inner . insert ( name , values ) ;
Ok ( ( ) )
Ok ( ( ) )
@ -40,6 +57,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" ) ) ,
_ = > {
_ = > {
self . inner . entry ( name ) . or_insert_with ( Vec ::new ) . push ( value ) ;
self . inner . entry ( name ) . or_insert_with ( Vec ::new ) . push ( value ) ;
Ok ( ( ) )
Ok ( ( ) )
@ -66,7 +84,15 @@ impl Registers {
( * name , preview )
( * name , preview )
} )
} )
. chain ( [ ( '_' , "<empty>" ) ] . iter ( ) . copied ( ) )
. chain (
[
( '_' , "<empty>" ) ,
( '#' , "<selection indices>" ) ,
( '.' , "<selection contents>" ) ,
]
. iter ( )
. copied ( ) ,
)
}
}
pub fn clear ( & mut self ) {
pub fn clear ( & mut self ) {
@ -75,7 +101,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 ( ) ,
}
}
}
}