@ -1847,11 +1847,11 @@ fn search_impl(
fn search_completions ( cx : & mut Context , reg : Option < char > ) -> Vec < String > {
let mut items = reg
. and_then ( | reg | cx . editor . registers . get( reg ) )
. map_or ( Vec ::new ( ) , | reg | reg . read( ) . iter ( ) . take( 200 ) . collect ( ) ) ;
. and_then ( | reg | cx . editor . registers . read( reg , cx . editor ) )
. map_or ( Vec ::new ( ) , | reg | reg . take( 200 ) . collect ( ) ) ;
items . sort_unstable ( ) ;
items . dedup ( ) ;
items . into_iter ( ) . cloned( ) . collect ( )
items . into_iter ( ) . map( | value | value . to_string ( ) ) . collect ( )
}
fn search ( cx : & mut Context ) {
@ -1910,9 +1910,8 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
let count = cx . count ( ) ;
let config = cx . editor . config ( ) ;
let scrolloff = config . scrolloff ;
let ( _ , doc ) = current ! ( cx . editor ) ;
let registers = & cx . editor . registers ;
if let Some ( query ) = registers . read ( '/' ) . and_then ( | query | query . last ( ) ) {
if let Some ( query ) = cx . editor . registers . last ( '/' , cx . editor ) {
let doc = doc ! ( cx . editor ) ;
let contents = doc . text ( ) . slice ( .. ) . to_string ( ) ;
let search_config = & config . search ;
let case_insensitive = if search_config . smart_case {
@ -1921,7 +1920,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
false
} ;
let wrap_around = search_config . wrap_around ;
if let Ok ( regex ) = RegexBuilder ::new ( query )
if let Ok ( regex ) = RegexBuilder ::new ( & query )
. case_insensitive ( case_insensitive )
. multi_line ( true )
. build ( )
@ -1974,12 +1973,14 @@ fn search_selection(cx: &mut Context) {
. join ( "|" ) ;
let msg = format! ( "register '{}' set to '{}'" , '/' , & regex ) ;
cx . editor . registers . push ( '/' , regex ) ;
cx . editor . set_status ( msg ) ;
match cx . editor . registers . push ( '/' , regex ) {
Ok ( _ ) = > cx . editor . set_status ( msg ) ,
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
}
fn make_search_word_bounded ( cx : & mut Context ) {
let regex = match cx . editor . registers . last ( '/' ) {
let regex = match cx . editor . registers . last ( '/' , cx . editor ) {
Some ( regex ) = > regex ,
None = > return ,
} ;
@ -1997,14 +1998,16 @@ fn make_search_word_bounded(cx: &mut Context) {
if ! start_anchored {
new_regex . push_str ( "\\b" ) ;
}
new_regex . push_str ( regex ) ;
new_regex . push_str ( & regex ) ;
if ! end_anchored {
new_regex . push_str ( "\\b" ) ;
}
let msg = format! ( "register '{}' set to '{}'" , '/' , & new_regex ) ;
cx . editor . registers . push ( '/' , new_regex ) ;
cx . editor . set_status ( msg ) ;
match cx . editor . registers . push ( '/' , new_regex ) {
Ok ( _ ) = > cx . editor . set_status ( msg ) ,
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
}
fn global_search ( cx : & mut Context ) {
@ -2367,7 +2370,10 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
let text = doc . text ( ) . slice ( .. ) ;
let values : Vec < String > = selection . fragments ( text ) . map ( Cow ::into_owned ) . collect ( ) ;
let reg_name = cx . register . unwrap_or ( '"' ) ;
cx . editor . registers . write ( reg_name , values ) ;
if let Err ( err ) = cx . editor . registers . write ( reg_name , values ) {
cx . editor . set_error ( err . to_string ( ) ) ;
return ;
}
} ;
// then delete
@ -3758,18 +3764,16 @@ fn yank(cx: &mut Context) {
. fragments ( text )
. map ( Cow ::into_owned )
. collect ( ) ;
let selections = values . len ( ) ;
let register = cx . register . unwrap_or ( '"' ) ;
let msg = format! (
"yanked {} selection(s) to register {}" ,
values . len ( ) ,
cx . register . unwrap_or ( '"' )
) ;
cx . editor
. registers
. write ( cx . register . unwrap_or ( '"' ) , values ) ;
match cx . editor . registers . write ( register , values ) {
Ok ( _ ) = > cx . editor . set_status ( format! (
"yanked {selections} selection(s) to register {register}" ,
) ) ,
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
cx . editor . set_status ( msg ) ;
exit_select_mode ( cx ) ;
}
@ -3778,6 +3782,7 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
let text = doc . text ( ) . slice ( .. ) ;
let selection = doc . selection ( view . id ) ;
let selections = selection . len ( ) ;
let joined = selection
. fragments ( text )
. fold ( String ::new ( ) , | mut acc , fragment | {
@ -3788,14 +3793,12 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
acc
} ) ;
let msg = format! (
"joined and yanked {} selection(s) to register {}" ,
selection . len ( ) ,
register ,
) ;
editor . registers . write ( register , vec! [ joined ] ) ;
editor . set_status ( msg ) ;
match editor . registers . write ( register , vec! [ joined ] ) {
Ok ( _ ) = > editor . set_status ( format! (
"joined and yanked {selections} selection(s) to register {register}" ,
) ) ,
Err ( err ) = > editor . set_error ( err . to_string ( ) ) ,
}
}
fn yank_joined ( cx : & mut Context ) {
@ -4040,34 +4043,34 @@ fn paste_primary_clipboard_before(cx: &mut Context) {
fn replace_with_yanked ( cx : & mut Context ) {
let count = cx . count ( ) ;
let reg_name = cx . register . unwrap_or ( '"' ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
let registers = & mut cx . editor . registers ;
if let Some ( values ) = registers . read ( reg_name ) {
if ! values . is_empty ( ) {
let repeat = std ::iter ::repeat (
values
. last ( )
. map ( | value | Tendril ::from ( & value . repeat ( count ) ) )
. unwrap ( ) ,
) ;
let mut values = values
. iter ( )
. map ( | value | Tendril ::from ( & value . repeat ( count ) ) )
. chain ( repeat ) ;
let selection = doc . selection ( view . id ) ;
let transaction = Transaction ::change_by_selection ( doc . text ( ) , selection , | range | {
if ! range . is_empty ( ) {
( range . from ( ) , range . to ( ) , Some ( values . next ( ) . unwrap ( ) ) )
} else {
( range . from ( ) , range . to ( ) , None )
}
} ) ;
doc . apply ( & transaction , view . id ) ;
exit_select_mode ( cx ) ;
let Some ( values ) = cx . editor . registers
. read ( reg_name , cx . editor )
. filter ( | values | values . len ( ) > 0 ) else { return } ;
let values : Vec < _ > = values . map ( | value | value . to_string ( ) ) . collect ( ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
let repeat = std ::iter ::repeat (
values
. last ( )
. map ( | value | Tendril ::from ( & value . repeat ( count ) ) )
. unwrap ( ) ,
) ;
let mut values = values
. iter ( )
. map ( | value | Tendril ::from ( & value . repeat ( count ) ) )
. chain ( repeat ) ;
let selection = doc . selection ( view . id ) ;
let transaction = Transaction ::change_by_selection ( doc . text ( ) , selection , | range | {
if ! range . is_empty ( ) {
( range . from ( ) , range . to ( ) , Some ( values . next ( ) . unwrap ( ) ) )
} else {
( range . from ( ) , range . to ( ) , None )
}
}
} ) ;
doc . apply ( & transaction , view . id ) ;
exit_select_mode ( cx ) ;
}
fn replace_selections_with_clipboard_impl (
@ -4109,12 +4112,12 @@ fn replace_selections_with_primary_clipboard(cx: &mut Context) {
fn paste ( cx : & mut Context , pos : Paste ) {
let count = cx . count ( ) ;
let reg_name = cx . register . unwrap_or ( '"' ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
let registers = & mut cx . editor . registers ;
if let Some ( values ) = registers . read ( reg_name ) {
paste_impl ( values , doc , view , pos , count , cx . editor . mode ) ;
}
let Some ( values ) = cx . editor . registers . read ( reg_name , cx . editor ) else { return } ;
let values : Vec < _ > = values . map ( | value | value . to_string ( ) ) . collect ( ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
paste_impl ( & values , doc , view , pos , count , cx . editor . mode ) ;
}
fn paste_after ( cx : & mut Context ) {
@ -5593,9 +5596,12 @@ fn record_macro(cx: &mut Context) {
}
} )
. collect ::< String > ( ) ;
cx . editor . registers . write ( reg , vec! [ s ] ) ;
cx . editor
. set_status ( format! ( "Recorded to register [{}]" , reg ) ) ;
match cx . editor . registers . write ( reg , vec! [ s ] ) {
Ok ( _ ) = > cx
. editor
. set_status ( format! ( "Recorded to register [{}]" , reg ) ) ,
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
} else {
let reg = cx . register . take ( ) . unwrap_or ( '@' ) ;
cx . editor . macro_recording = Some ( ( reg , Vec ::new ( ) ) ) ;
@ -5615,8 +5621,14 @@ fn replay_macro(cx: &mut Context) {
return ;
}
let keys : Vec < KeyEvent > = if let Some ( [ keys_str ] ) = cx . editor . registers . read ( reg ) {
match helix_view ::input ::parse_macro ( keys_str ) {
let keys : Vec < KeyEvent > = if let Some ( keys ) = cx
. editor
. registers
. read ( reg , cx . editor )
. filter ( | values | values . len ( ) = = 1 )
. map ( | mut values | values . next ( ) . unwrap ( ) )
{
match helix_view ::input ::parse_macro ( & keys ) {
Ok ( keys ) = > keys ,
Err ( err ) = > {
cx . editor . set_error ( format! ( "Invalid macro: {}" , err ) ) ;