]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Add support for workspace folders
authorYegappan Lakshmanan <yegappan@yahoo.com>
Wed, 30 Dec 2020 22:44:48 +0000 (14:44 -0800)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Wed, 30 Dec 2020 22:44:48 +0000 (14:44 -0800)
autoload/lsp.vim
plugin/lsp.vim

index 8bf65c3fb48290d5b33f569204a9def1947e256e..bc3e1ee5b421c7d7e6165ebb7bd6fb24f0a97970 100644 (file)
@@ -1127,6 +1127,7 @@ def s:initServer(lspserver: dict<any>)
 
   var clientCaps: dict<any> = {
        'workspace': {
+           'workspaceFolders': v:true,
            'applyEdit': v:true,
        },
        'textDocument': {},
@@ -1183,6 +1184,7 @@ def s:startServer(lspserver: dict<any>): number
   lspserver.nextID = 1
   lspserver.requests = {}
   lspserver.completePending = v:false
+  lspserver.workspaceFolders = [getcwd()]
 
   var job = job_start(cmd, opts)
   if job->job_status() == 'fail'
@@ -2267,4 +2269,127 @@ def lsp#showWorkspaceSymbols()
   lspserver.sendMessage(req)
 enddef
 
+# Display the list of workspace folders
+def lsp#listWorkspaceFolders()
+  var ftype = &filetype
+  if ftype == ''
+    return
+  endif
+
+  var lspserver: dict<any> = s:lspGetServer(ftype)
+  if lspserver->empty()
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not found')
+    return
+  endif
+  if !lspserver.running
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not running')
+    return
+  endif
+
+  echomsg 'Workspace Folders: ' .. string(lspserver.workspaceFolders)
+enddef
+
+# Add a workspace folder. Default is to use the current folder.
+def lsp#addWorkspaceFolder(dirArg: string)
+  var ftype = &filetype
+  if ftype == ''
+    return
+  endif
+
+  var lspserver: dict<any> = s:lspGetServer(ftype)
+  if lspserver->empty()
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not found')
+    return
+  endif
+  if !lspserver.running
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not running')
+    return
+  endif
+
+  if !lspserver.caps->has_key('workspace')
+         || !lspserver.caps.workspace->has_key('workspaceFolders')
+         || !lspserver.caps.workspace.workspaceFolders->has_key('supported')
+         || !lspserver.caps.workspace.workspaceFolders.supported
+      ErrMsg('Error: LSP server does not support workspace folders')
+    return
+  endif
+
+  var dirName: string = dirArg
+  if dirName == ''
+    dirName = input("Add Workspace Folder: ", getcwd(), 'dir')
+    if dirName == ''
+      return
+    endif
+  endif
+  :redraw!
+  if !dirName->isdirectory()
+    ErrMsg('Error: ' .. dirName .. ' is not a directory')
+    return
+  endif
+
+  if lspserver.workspaceFolders->index(dirName) != -1
+    ErrMsg('Error: ' .. dirName .. ' is already part of this workspace')
+    return
+  endif
+
+  var notif: dict<any> = lspserver.createNotification('workspace/didChangeWorkspaceFolders')
+  # interface DidChangeWorkspaceFoldersParams
+  notif.params->extend({'event': {'added': [dirName], 'removed': []}})
+  lspserver.sendMessage(notif)
+
+  lspserver.workspaceFolders->add(dirName)
+enddef
+
+# Remove a workspace folder. Default is to use the current folder.
+def lsp#removeWorkspaceFolder(dirArg: string)
+  var ftype = &filetype
+  if ftype == ''
+    return
+  endif
+
+  var lspserver: dict<any> = s:lspGetServer(ftype)
+  if lspserver->empty()
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not found')
+    return
+  endif
+  if !lspserver.running
+    ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not running')
+    return
+  endif
+
+  if !lspserver.caps->has_key('workspace')
+         || !lspserver.caps.workspace->has_key('workspaceFolders')
+         || !lspserver.caps.workspace.workspaceFolders->has_key('supported')
+         || !lspserver.caps.workspace.workspaceFolders.supported
+      ErrMsg('Error: LSP server does not support workspace folders')
+    return
+  endif
+
+  var dirName: string = dirArg
+  if dirName == ''
+    dirName = input("Remove Workspace Folder: ", getcwd(), 'dir')
+    if dirName == ''
+      return
+    endif
+  endif
+  :redraw!
+  if !dirName->isdirectory()
+    ErrMsg('Error: ' .. dirName .. ' is not a directory')
+    return
+  endif
+
+  var idx: number = lspserver.workspaceFolders->index(dirName)
+  if idx == -1
+    ErrMsg('Error: ' .. dirName .. ' is not currently part of this workspace')
+    return
+  endif
+
+  var notif: dict<any> = lspserver.createNotification('workspace/didChangeWorkspaceFolders')
+  # interface DidChangeWorkspaceFoldersParams
+  notif.params->extend({'event': {'added': [], 'removed': [dirName]}})
+  lspserver.sendMessage(notif)
+
+  lspserver.workspaceFolders->remove(idx)
+enddef
+
 # vim: shiftwidth=2 softtabstop=2
index b701a16a1194829848048276bd8d133f22c911cf..06ca1c4cd10f4157b233d85adfa0e89ff03fc382 100644 (file)
@@ -36,4 +36,7 @@ command! -nargs=0 -bar LspCalling call lsp#outgoingCalls()
 command! -nargs=0 -bar LspRename call lsp#rename()
 command! -nargs=0 -bar LspCodeAction call lsp#codeAction()
 command! -nargs=0 -bar LspShowWorkspaceSymbols call lsp#showWorkspaceSymbols()
+command! -nargs=0 -bar LspWorkspaceListFolders call lsp#listWorkspaceFolders()
+command! -nargs=1 -bar -complete=dir LspWorkspaceAddFolder call lsp#addWorkspaceFolder(<q-args>)
+command! -nargs=1 -bar -complete=dir LspWorkspaceRemoveFolder call lsp#removeWorkspaceFolder(<q-args>)