mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
LSP: Feature/add workspace folders (#12638)
* First implementation of workspace folders * Add completion for current directory * Add tracking of workspace folders * Add workspace folder listing * Add checks on adding/removing workspaces * Add appropriate initialization options * Add documentation * Make workspaceFolders available wherever client is
This commit is contained in:
parent
2d5dd85eef
commit
0d83a1c43f
@ -996,6 +996,19 @@ type_definition() *vim.lsp.buf.type_definition()*
|
||||
Jumps to the definition of the type of the symbol under the
|
||||
cursor.
|
||||
|
||||
add_workspace_folder({path}) *vim.lsp.buf.add_workspace_folder()*
|
||||
Add the folder at path to the workspace folders. If {path} is
|
||||
not provided, the user will be prompted for a path using
|
||||
|input()|.
|
||||
|
||||
remove_workspace_folder({path}) *vim.lsp.buf.remove_workspace_folder()*
|
||||
Remove the folder at path from the workspace folders. If
|
||||
{path} is not provided, the user will be prompted for
|
||||
a path using |input()|.
|
||||
|
||||
list_workspace_folders() *vim.lsp.buf.list_workspace_folders()*
|
||||
List all folders in the workspace.
|
||||
|
||||
workspace_symbol({query}) *vim.lsp.buf.workspace_symbol()*
|
||||
Lists all symbols in the current workspace in the quickfix
|
||||
window.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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|
|
||||
|
Loading…
Reference in New Issue
Block a user