]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Add support for the LspServerRestart command to restart the LSP server
authorYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 18 Feb 2022 01:54:35 +0000 (17:54 -0800)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 18 Feb 2022 01:54:35 +0000 (17:54 -0800)
README.md
autoload/handlers.vim
autoload/lsp.vim
autoload/lspserver.vim
doc/lsp.txt
plugin/lsp.vim

index 0f1614ade02293ed698756d56644cde38809d63f..380bfddeed123982110731dfc0ee0bae8dc5a2a1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -115,6 +115,7 @@ Command|Description
 :LspWorkspaceAddFolder `{folder}`| Add a folder to the workspace
 :LspWorkspaceRemoveFolder `{folder}`|Remove a folder from the workspace
 :LspWorkspaceListFolders|Show the list of folders in the workspace
+:LspServerRestart|Restart the LSP server for the current buffer
 
 ## Similar Vim LSP Plugins
 
index ce0b20c62a6099e4e50574c183482e370901d7de..2995634e1e2924100d131a8cfccce1134341503b 100644 (file)
@@ -122,6 +122,11 @@ def ProcessInitializeReply(lspserver: dict<any>, req: dict<any>, reply: dict<any
   endif
 enddef
 
+# Process a 'shutdown' reply from the LSP server.
+def ProcessShutdownReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>): void
+  return
+enddef
+
 # process the 'textDocument/definition' / 'textDocument/declaration' /
 # 'textDocument/typeDefinition' and 'textDocument/implementation' replies from
 # the LSP server
@@ -674,6 +679,7 @@ export def ProcessReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>):
   var lsp_reply_handlers: dict<func> =
     {
       'initialize': function('ProcessInitializeReply'),
+      'shutdown': function('ProcessShutdownReply'),
       'textDocument/definition': function('ProcessDefDeclReply'),
       'textDocument/declaration': function('ProcessDefDeclReply'),
       'textDocument/typeDefinition': function('ProcessDefDeclReply'),
@@ -700,7 +706,7 @@ export def ProcessReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>):
   if lsp_reply_handlers->has_key(req.method)
     lsp_reply_handlers[req.method](lspserver, req, reply)
   else
-    util.ErrMsg("Error: Unsupported reply received from LSP server: " .. reply->string())
+    util.ErrMsg("Error: Unsupported reply received from LSP server: " .. reply->string() .. " for request: " .. req->string())
   endif
 enddef
 
index 6005ec0c9c743f6feb156217f29b6367e728710e..85fe67b62603af557a5ce238692eb9eb7129e7fd 100644 (file)
@@ -401,10 +401,12 @@ enddef
 # Notify LSP server to remove a file
 export def RemoveFile(bnr: number): void
   var lspserver: dict<any> = buf.BufLspServerGet(bnr)
-  if lspserver->empty() || !lspserver.running
+  if lspserver->empty()
     return
   endif
-  lspserver.textdocDidClose(bnr)
+  if lspserver.running
+    lspserver.textdocDidClose(bnr)
+  endif
   diag.DiagRemoveFile(lspserver, bnr)
   buf.BufLspServerRemove(bnr)
 enddef
@@ -418,6 +420,35 @@ export def StopAllServers()
   endfor
 enddef
 
+# Restart the LSP server for the current buffer
+export def RestartServer()
+  var lspserver: dict<any> = CurbufGetServerChecked()
+  if lspserver->empty()
+    return
+  endif
+
+  # Stop the server
+  lspserver.stopServer()
+
+  # Remove all the buffers with the same file type as the current buffer
+  var ftype: string = &filetype
+  for binfo in getbufinfo()
+    if getbufvar(binfo.bufnr, '&filetype') == ftype
+      RemoveFile(binfo.bufnr)
+    endif
+  endfor
+
+  # Start the server again
+  lspserver.startServer(true)
+
+  # Add all the buffers with the same file type as the current buffer
+  for binfo in getbufinfo({bufloaded: 1})
+    if getbufvar(binfo.bufnr, '&filetype') == ftype
+      AddFile(binfo.bufnr)
+    endif
+  endfor
+enddef
+
 # Register a LSP server for one or more file types
 export def AddServer(serverList: list<dict<any>>)
   for server in serverList
@@ -779,7 +810,8 @@ export def Rename()
     return
   endif
 
-  var newName: string = input("Rename symbol: ", expand('<cword>'))
+  var sym: string = expand('<cword>')
+  var newName: string = input("Rename symbol '" .. sym .. "' to: ", sym)
   if newName == ''
     return
   endif
index 6d9f1e895be5d6ec04fd15c808ab5470eab14c00..2077722dfac816d732908e26f2235c97d2b84639 100644 (file)
@@ -70,14 +70,16 @@ enddef
 # LSP server exit callback
 def Exit_cb(lspserver: dict<any>, job: job, status: number): void
   util.WarnMsg("LSP server exited with status " .. status)
-  lspserver.job = v:null
   lspserver.running = false
   lspserver.ready = false
   lspserver.requests = {}
 enddef
 
 # Start a LSP server
-def StartServer(lspserver: dict<any>): number
+#
+# If 'isSync' is true, then waits for the server to send the initialize
+# reponse message.
+def StartServer(lspserver: dict<any>, isSync: bool = false): number
   if lspserver.running
     util.WarnMsg("LSP server for is already running")
     return 0
@@ -109,20 +111,23 @@ def StartServer(lspserver: dict<any>): number
     return 1
   endif
 
-  # wait for the LSP server to start
+  # wait a little for the LSP server to start
   sleep 10m
 
   lspserver.job = job
   lspserver.running = true
 
-  lspserver.initServer()
+  lspserver.initServer(isSync)
 
   return 0
 enddef
 
 # Request: 'initialize'
 # Param: InitializeParams
-def InitServer(lspserver: dict<any>)
+#
+# If 'isSync' is true, then waits for the server to send the initialize
+# reponse message.
+def InitServer(lspserver: dict<any>, isSync: bool = false)
   var req = lspserver.createRequest('initialize')
 
   # client capabilities (ClientCapabilities)
@@ -171,6 +176,9 @@ def InitServer(lspserver: dict<any>)
   req.params->extend(initparams)
 
   lspserver.sendMessage(req)
+  if isSync
+    lspserver.waitForReponse(req)
+  endif
 enddef
 
 # Send a "initialized" LSP notification
@@ -185,6 +193,7 @@ enddef
 def ShutdownServer(lspserver: dict<any>): void
   var req = lspserver.createRequest('shutdown')
   lspserver.sendMessage(req)
+  lspserver.waitForReponse(req)
 enddef
 
 # Send a 'exit' notification to the LSP server
@@ -201,15 +210,23 @@ def StopServer(lspserver: dict<any>): number
     return 0
   endif
 
+  # Send the shutdown request to the server
   lspserver.shutdownServer()
 
-  # Wait for the server to process the shutodwn request
-  sleep 1
-
+  # Notify the server to exit
   lspserver.exitServer()
 
-  lspserver.job->job_stop()
-  lspserver.job = v:null
+  # Wait for the server to process the exit notification and exit for a
+  # maximum of 2 seconds.
+  var maxCount: number = 1000
+  while lspserver.job->job_status() == 'run' && maxCount > 0
+    sleep 2m
+    maxCount -= 1
+  endwhile
+
+  if lspserver.job->job_status() == 'run'
+    lspserver.job->job_stop()
+  endif
   lspserver.running = false
   lspserver.ready = false
   lspserver.requests = {}
@@ -921,7 +938,7 @@ def SelectionRange(lspserver: dict<any>, fname: string)
   var req = lspserver.createRequest('textDocument/selectionRange')
   # interface SelectionRangeParams
   # interface TextDocumentIdentifier
-  req.params->extend({textDocument: {uri: util.LspFileToUri(fname)}, positions: [s:GetLspPosition()]})
+  req.params->extend({textDocument: {uri: util.LspFileToUri(fname)}, positions: [GetLspPosition()]})
   lspserver.sendMessage(req)
 
   lspserver.waitForReponse(req)
index 411ee85a8f7a0be18a4d2ba08cb5aa75d4b93eff..f463686d4d96370396b7814360f5d847dfae87b2 100644 (file)
@@ -2,7 +2,7 @@
 
 Author: Yegappan Lakshmanan  (yegappan AT yahoo DOT com)
 For Vim version 8.2.2342 and above
-Last change: Feb 4, 2022
+Last change: Feb 17, 2022
 
 ==============================================================================
                                                *lsp-license*
@@ -126,6 +126,7 @@ The following commands are provided:
                        Show the list of folders in the workspace
 :LspShowServerCapabilities
                        Display the list of capabilities of a LSP server.
+:LspServerRestart      Restart the LSP server for the current buffer.
 
 ==============================================================================
 4. Configuration                               *lsp-configuration*
@@ -485,17 +486,21 @@ diagnostic messages, you can add the following line to your .vimrc file:
 :LspWorkspaceRemoveFolder {folder}
                        Remove a folder from the workspace
 
-                                               *:LspWorkspaceListFolders*
-:LspWorkspaceListFolders
+:LspWorkspaceListFolders                       *:LspWorkspaceListFolders*
                        Show the list of folders in the workspace.
 
-                                               *:LspShowServerCapabilities*
-:LspShowServerCapabilities
+:LspShowServerCapabilities                     *:LspShowServerCapabilities*
                        Display the list of capabilities of a LSP server.
                        The server capabilities are described in the LSP
                        protocol specification under the "ServerCapabilities"
                        interface.
 
+                                               *:LspServerRestart*
+:LspServerRestart      Restart (stop and then start) the LSP server for the
+                       current buffer. All the loaded buffers with the same
+                       filetype as the current buffer are added back to the
+                       server.
+
 ==============================================================================
 6. Insert mode completion
 
index 83b98d7a7d92b2318bb38b88f61ab808993c1bb9..7d241ea513b0fa9a9cb1aac982e9d08bd9018a0f 100644 (file)
@@ -16,6 +16,7 @@ if has('patch-8.2.4257')
   opt.lspOptions = lspoptions.lspOptions
   lspf.enableServerTrace = lsp.EnableServerTrace
   lspf.addServer = lsp.AddServer
+  lspf.restartServer = lsp.RestartServer
   lspf.LspServerReady = lsp.ServerReady
   lspf.addFile = lsp.AddFile
   lspf.removeFile = lsp.RemoveFile
@@ -55,6 +56,7 @@ elseif has('patch-8.2.4019')
   opt.lspOptions = opt_import.lspOptions
   lspf.enableServerTrace = lsp_import.EnableServerTrace
   lspf.addServer = lsp_import.AddServer
+  lspf.restartServer = lsp_import.RestartServer
   lspf.LspServerReady = lsp_import.ServerReady
   lspf.addFile = lsp_import.AddFile
   lspf.removeFile = lsp_import.RemoveFile
@@ -90,6 +92,7 @@ else
   import {lspOptions, OptionsSet} from '../autoload/lspoptions.vim'
   import {EnableServerTrace,
          AddServer,
+         RestartServer,
          ServerReady,
          AddFile,
          RemoveFile,
@@ -126,6 +129,7 @@ else
   opt.lspOptions = lspOptions
   lspf.enableServerTrace = EnableServerTrace
   lspf.addServer = AddServer
+  lspf.restartServer = RestartServer
   lspf.LspServerReady = ServerReady
   lspf.addFile = AddFile
   lspf.removeFile = RemoveFile
@@ -182,6 +186,7 @@ enddef
 
 var TshowServers = lspf.showServers
 var TshowServerCapabilities = lspf.showServerCapabilities
+var TrestartServer = lspf.restartServer
 var TsetTraceServer = lspf.setTraceServer
 var TaddFile = lspf.addFile
 var TremoveFile = lspf.removeFile
@@ -229,6 +234,7 @@ augroup END
 # LSP commands
 command! -nargs=0 -bar LspShowServers call TshowServers()
 command! -nargs=0 -bar LspShowServerCapabilities call TshowServerCapabilities()
+command! -nargs=0 -bar LspServerRestart call TrestartServer()
 command! -nargs=1 -bar LspSetTrace call TsetTraceServer(<q-args>)
 command! -nargs=0 -bar LspGotoDefinition call TgotoDefinition(v:false)
 command! -nargs=0 -bar LspGotoDeclaration call TgotoDeclaration(v:false)