@ -16,6 +16,7 @@ use helix_view::{
} ;
} ;
pub type Completion = ( RangeFrom < usize > , Cow < ' static , str > ) ;
pub type Completion = ( RangeFrom < usize > , Cow < ' static , str > ) ;
type PromptCharHandler = Box < dyn Fn ( & mut Prompt , char , & Context ) > ;
pub struct Prompt {
pub struct Prompt {
prompt : Cow < ' static , str > ,
prompt : Cow < ' static , str > ,
@ -28,6 +29,7 @@ pub struct Prompt {
completion_fn : Box < dyn FnMut ( & Editor , & str ) -> Vec < Completion > > ,
completion_fn : Box < dyn FnMut ( & Editor , & str ) -> Vec < Completion > > ,
callback_fn : Box < dyn FnMut ( & mut Context , & str , PromptEvent ) > ,
callback_fn : Box < dyn FnMut ( & mut Context , & str , PromptEvent ) > ,
pub doc_fn : Box < dyn Fn ( & str ) -> Option < Cow < str > > > ,
pub doc_fn : Box < dyn Fn ( & str ) -> Option < Cow < str > > > ,
next_char_handler : Option < PromptCharHandler > ,
}
}
#[ derive(Clone, Copy, PartialEq) ]
#[ derive(Clone, Copy, PartialEq) ]
@ -78,6 +80,7 @@ impl Prompt {
completion_fn : Box ::new ( completion_fn ) ,
completion_fn : Box ::new ( completion_fn ) ,
callback_fn : Box ::new ( callback_fn ) ,
callback_fn : Box ::new ( callback_fn ) ,
doc_fn : Box ::new ( | _ | None ) ,
doc_fn : Box ::new ( | _ | None ) ,
next_char_handler : None ,
}
}
}
}
@ -191,6 +194,13 @@ impl Prompt {
}
}
pub fn insert_char ( & mut self , c : char , cx : & Context ) {
pub fn insert_char ( & mut self , c : char , cx : & Context ) {
if let Some ( handler ) = & self . next_char_handler . take ( ) {
handler ( self , c , cx ) ;
self . next_char_handler = None ;
return ;
}
self . line . insert ( self . cursor , c ) ;
self . line . insert ( self . cursor , c ) ;
let mut cursor = GraphemeCursor ::new ( self . cursor , self . line . len ( ) , false ) ;
let mut cursor = GraphemeCursor ::new ( self . cursor , self . line . len ( ) , false ) ;
if let Ok ( Some ( pos ) ) = cursor . next_boundary ( & self . line , 0 ) {
if let Ok ( Some ( pos ) ) = cursor . next_boundary ( & self . line , 0 ) {
@ -538,6 +548,35 @@ impl Component for Prompt {
( self . callback_fn ) ( cx , & self . line , PromptEvent ::Update )
( self . callback_fn ) ( cx , & self . line , PromptEvent ::Update )
}
}
ctrl ! ( 'q' ) = > self . exit_selection ( ) ,
ctrl ! ( 'q' ) = > self . exit_selection ( ) ,
ctrl ! ( 'r' ) = > {
self . completion = cx
. editor
. registers
. inner ( )
. iter ( )
. map ( | ( ch , reg ) | {
let content = reg
. read ( )
. get ( 0 )
. and_then ( | s | s . lines ( ) . next ( ) . to_owned ( ) )
. unwrap_or_default ( ) ;
( 0 .. , format! ( "{} {}" , ch , & content ) . into ( ) )
} )
. collect ( ) ;
self . next_char_handler = Some ( Box ::new ( | prompt , c , context | {
prompt . insert_str (
context
. editor
. registers
. read ( c )
. and_then ( | r | r . first ( ) )
. map_or ( "" , | r | r . as_str ( ) ) ,
) ;
prompt . recalculate_completion ( context . editor ) ;
} ) ) ;
( self . callback_fn ) ( cx , & self . line , PromptEvent ::Update ) ;
return EventResult ::Consumed ( None ) ;
}
// any char event that's not mapped to any other combo
// any char event that's not mapped to any other combo
KeyEvent {
KeyEvent {
code : KeyCode ::Char ( c ) ,
code : KeyCode ::Char ( c ) ,