@ -1232,49 +1232,115 @@ pub fn hover(cx: &mut Context) {
}
}
pub fn rename_symbol ( cx : & mut Context ) {
pub fn rename_symbol ( cx : & mut Context ) {
let ( view , doc ) = current_ref ! ( cx . editor ) ;
fn get_prefill_from_word_boundary ( editor : & Editor ) -> String {
let text = doc . text ( ) . slice ( .. ) ;
let ( view , doc ) = current_ref ! ( editor ) ;
let primary_selection = doc . selection ( view . id ) . primary ( ) ;
let text = doc . text ( ) . slice ( .. ) ;
let prefill = if primary_selection . len ( ) > 1 {
let primary_selection = doc . selection ( view . id ) . primary ( ) ;
primary_selection
if primary_selection . len ( ) > 1 {
} else {
primary_selection
use helix_core ::textobject ::{ textobject_word , TextObject } ;
} else {
textobject_word ( text , primary_selection , TextObject ::Inside , 1 , false )
use helix_core ::textobject ::{ textobject_word , TextObject } ;
textobject_word ( text , primary_selection , TextObject ::Inside , 1 , false )
}
. fragment ( text )
. into ( )
}
}
. fragment ( text )
. into ( ) ;
fn get_prefill_from_lsp_response (
ui ::prompt_with_input (
editor : & Editor ,
cx ,
offset_encoding : OffsetEncoding ,
"rename-to:" . into ( ) ,
response : Option < lsp ::PrepareRenameResponse > ,
prefill ,
) -> Result < String , & ' static str > {
None ,
match response {
ui ::completers ::none ,
Some ( lsp ::PrepareRenameResponse ::Range ( range ) ) = > {
move | cx : & mut compositor ::Context , input : & str , event : PromptEvent | {
let text = doc ! ( editor ) . text ( ) ;
if event ! = PromptEvent ::Validate {
return ;
Ok ( lsp_range_to_range ( text , range , offset_encoding )
. ok_or ( "lsp sent invalid selection range for rename" ) ?
. fragment ( text . slice ( .. ) )
. into ( ) )
}
Some ( lsp ::PrepareRenameResponse ::RangeWithPlaceholder { placeholder , .. } ) = > {
Ok ( placeholder )
}
Some ( lsp ::PrepareRenameResponse ::DefaultBehavior { .. } ) = > {
Ok ( get_prefill_from_word_boundary ( editor ) )
}
}
None = > Err ( "lsp did not respond to prepare rename request" ) ,
}
}
let ( view , doc ) = current ! ( cx . editor ) ;
fn create_rename_prompt ( editor : & Editor , prefill : String ) -> Box < ui ::Prompt > {
let language_server = language_server ! ( cx . editor , doc ) ;
let prompt = ui ::Prompt ::new (
let offset_encoding = language_server . offset_encoding ( ) ;
"rename-to:" . into ( ) ,
None ,
ui ::completers ::none ,
move | cx : & mut compositor ::Context , input : & str , event : PromptEvent | {
if event ! = PromptEvent ::Validate {
return ;
}
let pos = doc . position ( view . id , offset_encoding ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
let language_server = language_server ! ( cx . editor , doc ) ;
let offset_encoding = language_server . offset_encoding ( ) ;
let pos = doc . position ( view . id , offset_encoding ) ;
let future =
match language_server . rename_symbol ( doc . identifier ( ) , pos , input . to_string ( ) ) {
Some ( future ) = > future ,
None = > {
cx . editor
. set_error ( "Language server does not support symbol renaming" ) ;
return ;
}
} ;
match block_on ( future ) {
Ok ( edits ) = > apply_workspace_edit ( cx . editor , offset_encoding , & edits ) ,
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
} ,
)
. with_line ( prefill , editor ) ;
let future =
Box ::new ( prompt )
match language_server . rename_symbol ( doc . identifier ( ) , pos , input . to_string ( ) ) {
}
Some ( future ) = > future ,
None = > {
let ( view , doc ) = current ! ( cx . editor ) ;
cx . editor
let language_server = language_server ! ( cx . editor , doc ) ;
. set_error ( "Language server does not support symbol renaming" ) ;
let offset_encoding = language_server . offset_encoding ( ) ;
let pos = doc . position ( view . id , offset_encoding ) ;
match language_server . prepare_rename ( doc . identifier ( ) , pos ) {
// Language server supports textDocument/prepareRename, use it.
Some ( future ) = > cx . callback (
future ,
move | editor , compositor , response : Option < lsp ::PrepareRenameResponse > | {
let prefill = match get_prefill_from_lsp_response ( editor , offset_encoding , response )
{
Ok ( p ) = > p ,
Err ( e ) = > {
editor . set_error ( e ) ;
return ;
return ;
}
}
} ;
} ;
match block_on ( future ) {
Ok ( edits ) = > apply_workspace_edit ( cx . editor , offset_encoding , & edits ) ,
let prompt = create_rename_prompt ( editor , prefill ) ;
Err ( err ) = > cx . editor . set_error ( err . to_string ( ) ) ,
}
compositor . push ( prompt ) ;
} ,
} ,
) ;
) ,
// Language server does not support textDocument/prepareRename, fall back
// to word boundary selection.
None = > {
let prefill = get_prefill_from_word_boundary ( cx . editor ) ;
let prompt = create_rename_prompt ( cx . editor , prefill ) ;
cx . push_layer ( prompt ) ;
}
} ;
}
}
pub fn select_references_to_symbol_under_cursor ( cx : & mut Context ) {
pub fn select_references_to_symbol_under_cursor ( cx : & mut Context ) {