aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/lsp.lua6
-rw-r--r--runtime/lua/vim/lsp/buf.lua55
-rw-r--r--runtime/lua/vim/lsp/protocol.lua24
-rw-r--r--runtime/lua/vim/lsp/util.lua3
4 files changed, 87 insertions, 1 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index dacdbcfa17..92f56b2ddf 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -597,7 +597,10 @@ function lsp.start_client(config)
-- -- workspace folder in the user interface.
-- name
-- }
- workspaceFolders = nil;
+ workspaceFolders = {{
+ uri = vim.uri_from_fname(config.root_dir);
+ name = string.format("%s", config.root_dir);
+ }};
}
if config.before_init then
-- TODO(ashkan) handle errors here.
@@ -610,6 +613,7 @@ function lsp.start_client(config)
rpc.notify('initialized', {[vim.type_idx]=vim.types.dictionary})
client.initialized = true
uninitialized_clients[client_id] = nil
+ client.workspaceFolders = initialize_params.workspaceFolders
client.server_capabilities = assert(result.capabilities, "initialize result doesn't contain capabilities")
-- These are the cleaned up capabilities we use for dynamically deciding
-- when to send certain events to clients.
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index fa62905c0a..a70581478b 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -238,6 +238,61 @@ function M.outgoing_calls()
end)
end
+--- List workspace folders.
+function M.list_workspace_folders()
+ local workspace_folders = {}
+ for _, client in ipairs(vim.lsp.buf_get_clients()) do
+ for _, folder in ipairs(client.workspaceFolders) do
+ table.insert(workspace_folders, folder.name)
+ end
+ end
+ return workspace_folders
+end
+
+--- Add a workspace folder.
+function M.add_workspace_folder(workspace_folder)
+ workspace_folder = workspace_folder or npcall(vfn.input, "Workspace Folder: ", vfn.expand('%:p:h'))
+ vim.api.nvim_command("redraw")
+ if not (workspace_folder and #workspace_folder > 0) then return end
+ if vim.fn.isdirectory(workspace_folder) == 0 then
+ print(workspace_folder, " is not a valid directory")
+ return
+ end
+ local params = util.make_workspace_params({{uri = vim.uri_from_fname(workspace_folder); name = workspace_folder}}, {{}})
+ for _, client in ipairs(vim.lsp.buf_get_clients()) do
+ local found = false
+ for _, folder in ipairs(client.workspaceFolders) do
+ if folder.name == workspace_folder then
+ found = true
+ print(workspace_folder, "is already part of this workspace")
+ break
+ end
+ end
+ if not found then
+ vim.lsp.buf_notify(0, 'workspace/didChangeWorkspaceFolders', params)
+ table.insert(client.workspaceFolders, params.event.added[1])
+ end
+ end
+end
+
+--- Remove a workspace folder.
+function M.remove_workspace_folder(workspace_folder)
+ workspace_folder = workspace_folder or npcall(vfn.input, "Workspace Folder: ", vfn.expand('%:p:h'))
+ vim.api.nvim_command("redraw")
+ if not (workspace_folder and #workspace_folder > 0) then return end
+ local params = util.make_workspace_params({{}}, {{uri = vim.uri_from_fname(workspace_folder); name = workspace_folder}})
+ for _, client in ipairs(vim.lsp.buf_get_clients()) do
+ for idx, folder in ipairs(client.workspaceFolders) do
+ if folder.name == workspace_folder then
+ vim.lsp.buf_notify(0, 'workspace/didChangeWorkspaceFolders', params)
+ client.workspaceFolders[idx] = nil
+ return
+ end
+ end
+ end
+ print(workspace_folder, "is not currently part of the workspace")
+end
+
--- Lists all symbols in the current workspace in the quickfix window.
---
--- The list is filtered against {query}; if the argument is omitted from the
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 07b4e8b926..1f21bd7eb0 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -716,6 +716,7 @@ function protocol.make_client_capabilities()
};
hierarchicalWorkspaceSymbolSupport = true;
};
+ workspaceFolders = true;
applyEdit = true;
};
callHierarchy = {
@@ -974,6 +975,28 @@ function protocol.resolve_capabilities(server_capabilities)
error("The server sent invalid implementationProvider")
end
+ local workspace = server_capabilities.workspace
+ local workspace_properties = {}
+ if workspace == nil or workspace.workspaceFolders == nil then
+ -- Defaults if omitted.
+ workspace_properties = {
+ workspace_folder_properties = {
+ supported = false;
+ changeNotifications=false;
+ }
+ }
+ elseif type(workspace.workspaceFolders) == 'table' then
+ workspace_properties = {
+ workspace_folder_properties = {
+ supported = vim.F.ifnil(workspace.workspaceFolders.supported, false);
+ changeNotifications = vim.F.ifnil(workspace.workspaceFolders.changeNotifications, false);
+
+ }
+ }
+ else
+ error("The server sent invalid workspace")
+ end
+
local signature_help_properties
if server_capabilities.signatureHelpProvider == nil then
signature_help_properties = {
@@ -993,6 +1016,7 @@ function protocol.resolve_capabilities(server_capabilities)
return vim.tbl_extend("error"
, text_document_sync_properties
, signature_help_properties
+ , workspace_properties
, general_properties
)
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 3deec6d74e..f78a36fda2 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1314,6 +1314,9 @@ function M.make_text_document_params()
return { uri = vim.uri_from_bufnr(0) }
end
+function M.make_workspace_params(added, removed)
+ return { event = { added = added; removed = removed; } }
+end
--- Returns visual width of tabstop.
---
--@see |softtabstop|