@@ -38,7 +38,7 @@ let projectsFiles: Map<
3838// ^ caching AND states AND distributed system. Why does LSP has to be stupid like this
3939
4040// will be properly defined later depending on the mode (stdio/node-rpc)
41- let send : ( msg : m . Message ) => void = ( _ ) => { } ;
41+ let send : ( msg : m . Message ) => void = ( _ ) => { } ;
4242
4343interface CreateInterfaceRequestParams {
4444 uri : string ;
@@ -282,19 +282,58 @@ function references(msg: p.RequestMessage) {
282282 return response ;
283283}
284284
285+ function prepareRename ( msg : p . RequestMessage ) : m . ResponseMessage {
286+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_prepareRename
287+ let params = msg . params as p . PrepareRenameParams ;
288+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
289+ let locations : null | p . Location [ ] = utils . getReferencesForPosition (
290+ filePath ,
291+ params . position
292+ ) ;
293+
294+ let result : p . Range | null = null ;
295+
296+ if ( locations !== null ) {
297+ locations . forEach ( loc => {
298+ if (
299+ path . normalize ( fileURLToPath ( loc . uri ) ) ===
300+ path . normalize ( fileURLToPath ( params . textDocument . uri ) )
301+ ) {
302+ let { start, end } = loc . range ;
303+ let pos = params . position ;
304+ if (
305+ start . character <= pos . character &&
306+ start . line <= pos . line &&
307+ end . character >= pos . character &&
308+ end . line >= pos . line
309+ ) {
310+ result = loc . range ;
311+ } ;
312+ }
313+ } ) ;
314+ }
315+
316+ let response : m . ResponseMessage = {
317+ jsonrpc : c . jsonrpcVersion ,
318+ id : msg . id ,
319+ result
320+ } ;
321+ return response ;
322+ }
323+
285324function rename ( msg : p . RequestMessage ) {
286325 // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
287326 let params = msg . params as p . RenameParams ;
288327 let filePath = fileURLToPath ( params . textDocument . uri ) ;
289328 let documentChanges :
290329 | ( p . RenameFile | p . TextDocumentEdit ) [ ]
291330 | null = utils . runAnalysisAfterSanityCheck ( filePath , [
292- "rename" ,
293- filePath ,
294- params . position . line ,
295- params . position . character ,
296- params . newName
297- ] ) ;
331+ "rename" ,
332+ filePath ,
333+ params . position . line ,
334+ params . position . character ,
335+ params . newName
336+ ] ) ;
298337
299338 let result : WorkspaceEdit | null = null ;
300339
@@ -591,7 +630,7 @@ function onMessage(msg: m.Message) {
591630 hoverProvider : true ,
592631 definitionProvider : true ,
593632 referencesProvider : true ,
594- renameProvider : true ,
633+ renameProvider : { prepareProvider : true } ,
595634 documentSymbolProvider : false ,
596635 completionProvider : { triggerCharacters : [ "." , ">" , "@" , "~" ] } ,
597636 } ,
@@ -642,6 +681,8 @@ function onMessage(msg: m.Message) {
642681 send ( definition ( msg ) ) ;
643682 } else if ( msg . method === p . ReferencesRequest . method ) {
644683 send ( references ( msg ) ) ;
684+ } else if ( msg . method === p . PrepareRenameRequest . method ) {
685+ send ( prepareRename ( msg ) ) ;
645686 } else if ( msg . method === p . RenameRequest . method ) {
646687 send ( rename ( msg ) ) ;
647688 } else if ( msg . method === p . DocumentSymbolRequest . method ) {
0 commit comments