@@ -8,6 +8,8 @@ use lsp_types::*;
88
99use fnv:: FnvHashMap ;
1010use std:: collections:: hash_map:: Entry ;
11+ use std:: collections:: HashMap ;
12+ use vhdl_lang:: ast:: Designator ;
1113
1214use crate :: rpc_channel:: SharedRpcChannel ;
1315use std:: io;
@@ -117,6 +119,10 @@ impl VHDLServer {
117119 hover_provider : Some ( HoverProviderCapability :: Simple ( true ) ) ,
118120 references_provider : Some ( OneOf :: Left ( true ) ) ,
119121 implementation_provider : Some ( ImplementationProviderCapability :: Simple ( true ) ) ,
122+ rename_provider : Some ( OneOf :: Right ( RenameOptions {
123+ prepare_provider : Some ( true ) ,
124+ work_done_progress_options : Default :: default ( ) ,
125+ } ) ) ,
120126 ..Default :: default ( )
121127 } ;
122128
@@ -365,6 +371,54 @@ impl VHDLServer {
365371 ) )
366372 }
367373
374+ pub fn prepare_rename (
375+ & mut self ,
376+ params : & TextDocumentPositionParams ,
377+ ) -> Option < PrepareRenameResponse > {
378+ let source = self
379+ . project
380+ . get_source ( & uri_to_file_name ( & params. text_document . uri ) ) ?;
381+
382+ let ( pos, ent) = self
383+ . project
384+ . item_at_cursor ( & source, from_lsp_pos ( params. position ) ) ?;
385+
386+ if let Designator :: Identifier ( _) = ent. designator ( ) {
387+ Some ( PrepareRenameResponse :: Range ( to_lsp_range ( pos. range ) ) )
388+ } else {
389+ // It does not make sense to rename operator symbols and character literals
390+ // Also they have different representations that would not be handled consistently
391+ // Such as function "+"(arg1, arg2 : integer) but used as foo + bar
392+ None
393+ }
394+ }
395+
396+ pub fn rename ( & mut self , params : & RenameParams ) -> Option < WorkspaceEdit > {
397+ let source = self . project . get_source ( & uri_to_file_name (
398+ & params. text_document_position . text_document . uri ,
399+ ) ) ?;
400+
401+ let ent = self . project . find_declaration (
402+ & source,
403+ from_lsp_pos ( params. text_document_position . position ) ,
404+ ) ?;
405+
406+ let mut changes: HashMap < Url , Vec < TextEdit > > = Default :: default ( ) ;
407+
408+ for srcpos in self . project . find_all_references ( ent) {
409+ let loc = srcpos_to_location ( & srcpos) ;
410+ changes. entry ( loc. uri ) . or_default ( ) . push ( TextEdit {
411+ range : loc. range ,
412+ new_text : params. new_name . clone ( ) ,
413+ } ) ;
414+ }
415+
416+ Some ( WorkspaceEdit {
417+ changes : Some ( changes) ,
418+ ..Default :: default ( )
419+ } )
420+ }
421+
368422 pub fn text_document_hover ( & mut self , params : & TextDocumentPositionParams ) -> Option < Hover > {
369423 let source = self
370424 . project
0 commit comments