summaryrefslogtreecommitdiff
path: root/lua/lvim/lsp
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lvim/lsp')
-rw-r--r--lua/lvim/lsp/config.lua32
-rw-r--r--lua/lvim/lsp/init.lua11
-rw-r--r--lua/lvim/lsp/peek.lua157
-rw-r--r--lua/lvim/lsp/providers/sumneko_lua.lua63
-rw-r--r--lua/lvim/lsp/utils.lua119
5 files changed, 117 insertions, 265 deletions
diff --git a/lua/lvim/lsp/config.lua b/lua/lvim/lsp/config.lua
index 96a1b823..358e83f8 100644
--- a/lua/lvim/lsp/config.lua
+++ b/lua/lvim/lsp/config.lua
@@ -10,6 +10,7 @@ local skipped_servers = {
"eslint",
"eslintls",
"golangci_lint_ls",
+ "gradle_ls",
"graphql",
"jedi_language_server",
"ltex",
@@ -18,10 +19,12 @@ local skipped_servers = {
"psalm",
"pylsp",
"quick_lint_js",
- "rome",
"reason_ls",
+ "rome",
+ "ruby_ls",
"scry",
"solang",
+ "solc",
"solidity_ls",
"sorbet",
"sourcekit",
@@ -30,8 +33,8 @@ local skipped_servers = {
"sqlls",
"sqls",
"stylelint_lsp",
- "tflint",
"svlangserver",
+ "tflint",
"verible",
"vuels",
}
@@ -46,10 +49,10 @@ return {
signs = {
active = true,
values = {
- { name = "DiagnosticSignError", text = "ï™™" },
- { name = "DiagnosticSignWarn", text = "" },
- { name = "DiagnosticSignHint", text = "ï µ" },
- { name = "DiagnosticSignInfo", text = "" },
+ { name = "DiagnosticSignError", text = lvim.icons.diagnostics.Error },
+ { name = "DiagnosticSignWarn", text = lvim.icons.diagnostics.Warning },
+ { name = "DiagnosticSignHint", text = lvim.icons.diagnostics.Hint },
+ { name = "DiagnosticSignInfo", text = lvim.icons.diagnostics.Info },
},
},
virtual_text = true,
@@ -72,18 +75,13 @@ return {
end,
},
},
- document_highlight = true,
+ document_highlight = false,
code_lens_refresh = true,
float = {
focusable = true,
style = "minimal",
border = "rounded",
},
- peek = {
- max_height = 15,
- max_width = 30,
- context = 10,
- },
on_attach_callback = nil,
on_init_callback = nil,
automatic_configuration = {
@@ -100,12 +98,6 @@ return {
["gr"] = { vim.lsp.buf.references, "Goto references" },
["gI"] = { vim.lsp.buf.implementation, "Goto Implementation" },
["gs"] = { vim.lsp.buf.signature_help, "show signature help" },
- ["gp"] = {
- function()
- require("lvim.lsp.peek").Peek "definition"
- end,
- "Peek definition",
- },
["gl"] = {
function()
local config = lvim.lsp.diagnostics.float
@@ -143,7 +135,9 @@ return {
},
},
null_ls = {
- setup = {},
+ setup = {
+ debug = false,
+ },
config = {},
},
---@deprecated use lvim.lsp.automatic_configuration.skipped_servers instead
diff --git a/lua/lvim/lsp/init.lua b/lua/lvim/lsp/init.lua
index 0b361972..c8a2b22f 100644
--- a/lua/lvim/lsp/init.lua
+++ b/lua/lvim/lsp/init.lua
@@ -25,6 +25,11 @@ local function add_lsp_buffer_keybindings(bufnr)
end
function M.common_capabilities()
+ local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
+ if status_ok then
+ return cmp_nvim_lsp.default_capabilities()
+ end
+
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
capabilities.textDocument.completion.completionItem.resolveSupport = {
@@ -35,11 +40,6 @@ function M.common_capabilities()
},
}
- local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
- if status_ok then
- capabilities = cmp_nvim_lsp.update_capabilities(capabilities)
- end
-
return capabilities
end
@@ -74,6 +74,7 @@ function M.common_on_attach(client, bufnr)
end
add_lsp_buffer_keybindings(bufnr)
add_lsp_buffer_options(bufnr)
+ lu.setup_document_symbols(client, bufnr)
end
function M.get_common_opts()
diff --git a/lua/lvim/lsp/peek.lua b/lua/lvim/lsp/peek.lua
deleted file mode 100644
index 65c67e92..00000000
--- a/lua/lvim/lsp/peek.lua
+++ /dev/null
@@ -1,157 +0,0 @@
-local M = {
- floating_buf = nil,
- floating_win = nil,
- prev_result = nil,
-}
-
-local function create_floating_file(location, opts)
- vim.validate {
- location = { location, "t" },
- opts = { opts, "t", true },
- }
-
- -- Set some defaults
- opts = opts or {}
- local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }
-
- -- location may be LocationLink or Location
- local uri = location.targetUri or location.uri
- if uri == nil then
- return
- end
- local bufnr = vim.uri_to_bufnr(uri)
- if not vim.api.nvim_buf_is_loaded(bufnr) then
- vim.fn.bufload(bufnr)
- end
-
- local range = location.targetRange or location.range
-
- local contents = vim.api.nvim_buf_get_lines(
- bufnr,
- range.start.line,
- math.min(
- range["end"].line + 1 + (opts.context or lvim.lsp.peek.max_height),
- range.start.line + (opts.max_height or lvim.lsp.peek.max_height)
- ),
- false
- )
- if next(contents) == nil then
- vim.notify("peek: Unable to get contents of the file!", vim.log.levels.WARN)
- return
- end
- local width, height = vim.lsp.util._make_floating_popup_size(contents, opts)
- local if_nil = vim.F.if_nil
- opts = vim.lsp.util.make_floating_popup_options(
- if_nil(width, lvim.lsp.peek.max_width),
- if_nil(height, lvim.lsp.peek.max_height),
- opts
- )
- -- Don't make it minimal as it is meant to be fully featured
- opts["style"] = nil
-
- vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")
-
- local winnr = vim.api.nvim_open_win(bufnr, false, opts)
- vim.api.nvim_win_set_option(winnr, "winblend", 0)
-
- vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })
- vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)
-
- -- Set some autocmds to close the window
- vim.api.nvim_command(
- string.format("autocmd %s <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", unpack(close_events), winnr)
- )
-
- return bufnr, winnr
-end
-
-local function preview_location_callback(result)
- if result == nil or vim.tbl_isempty(result) then
- return nil
- end
-
- local opts = {
- border = "rounded",
- context = lvim.lsp.peek.context,
- }
-
- if vim.tbl_islist(result) then
- M.prev_result = result[1]
- M.floating_buf, M.floating_win = create_floating_file(result[1], opts)
- else
- M.prev_result = result
- M.floating_buf, M.floating_win = create_floating_file(result, opts)
- end
-end
-
-local function preview_location_callback_new_signature(_, result)
- return preview_location_callback(result)
-end
-
-function M.open_file()
- -- Get the file currently open in the floating window
- local filepath = vim.fn.expand "%:."
-
- if not filepath then
- vim.notify("peek: Unable to open the file!", vim.log.levels.ERROR)
- return
- end
-
- -- Close the floating window
- pcall(vim.api.nvim_win_close, M.floating_win, true)
-
- -- Edit the file
- vim.cmd("edit " .. filepath)
-
- local winnr = vim.api.nvim_get_current_win()
-
- -- Set the cursor at the right position
- M.set_cursor_to_prev_pos(winnr)
-end
-
-function M.set_cursor_to_prev_pos(winnr)
- -- Get position of the thing to peek at
- local location = M.prev_result
- local range = location.targetRange or location.range
- local cursor_pos = { range.start.line + 1, range.start.character }
-
- -- Set the winnr to the floating window if none was passed in
- winnr = winnr or M.floating_win
- -- Set the cursor at the correct position in the floating window
- vim.api.nvim_win_set_cursor(winnr, cursor_pos)
-end
-
-function M.Peek(what)
- -- If a window already exists, focus it at the right position!
- if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
- local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win)
- if not success_1 then
- vim.notify("peek: You cannot edit the current file in a preview!", vim.log.levels.ERROR)
- return
- end
-
- -- Set the cursor at the correct position in the floating window
- M.set_cursor_to_prev_pos()
-
- vim.api.nvim_buf_set_keymap(
- M.floating_buf,
- "n",
- "<CR>",
- ":lua require('lvim.lsp.peek').open_file()<CR>",
- { noremap = true, silent = true }
- )
- else
- -- Make a new request and then create the new window in the callback
- local params = vim.lsp.util.make_position_params()
- local preview_callback = preview_location_callback_new_signature
- local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
- if not success then
- vim.notify(
- 'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.',
- vim.log.levels.ERROR
- )
- end
- end
-end
-
-return M
diff --git a/lua/lvim/lsp/providers/sumneko_lua.lua b/lua/lvim/lsp/providers/sumneko_lua.lua
index 6cd78157..2caa23b6 100644
--- a/lua/lvim/lsp/providers/sumneko_lua.lua
+++ b/lua/lvim/lsp/providers/sumneko_lua.lua
@@ -1,32 +1,59 @@
-local dev_opts = {
+local default_workspace = {
library = {
- vimruntime = true, -- runtime path
- types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others
- -- plugins = true, -- installed opt or start plugins in packpath
- -- you can also specify the list of plugins to make available as a workspace library
- plugins = { "plenary.nvim" },
+ vim.fn.expand "$VIMRUNTIME",
+ get_lvim_base_dir(),
+ require("neodev.config").types(),
},
- override = nil, -- function(root_dir, options) end,
+
+ maxPreload = 5000,
+ preloadFileSize = 10000,
}
-local lua_dev_loaded, lua_dev = pcall(require, "lua-dev")
-if lua_dev_loaded then
- lua_dev.setup(dev_opts)
+local add_packages_to_workspace = function(packages, config)
+ -- config.settings.Lua = config.settings.Lua or { workspace = default_workspace }
+ local runtimedirs = vim.api.nvim__get_runtime({ "lua" }, true, { is_lua = true })
+ local workspace = config.settings.Lua.workspace
+ for _, v in pairs(runtimedirs) do
+ for _, pack in ipairs(packages) do
+ if v:match(pack) and not vim.tbl_contains(workspace.library, v) then
+ table.insert(workspace.library, v)
+ end
+ end
+ end
+end
+
+local lspconfig = require "lspconfig"
+
+local make_on_new_config = function(on_new_config, _)
+ return lspconfig.util.add_hook_before(on_new_config, function(new_config, _)
+ local server_name = new_config.name
+
+ if server_name ~= "sumneko_lua" then
+ return
+ end
+ local plugins = { "plenary.nvim", "telescope.nvim", "nvim-treesitter", "LuaSnip" }
+ add_packages_to_workspace(plugins, new_config)
+ end)
end
+lspconfig.util.default_config = vim.tbl_extend("force", lspconfig.util.default_config, {
+ on_new_config = make_on_new_config(lspconfig.util.default_config.on_new_config),
+})
+
local opts = {
settings = {
Lua = {
- diagnostics = {
- globals = { "vim", "lvim", "packer_plugins" },
- },
- workspace = {
- library = {
- [require("lvim.utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
+ telemetry = { enable = false },
+ runtime = {
+ version = "LuaJIT",
+ special = {
+ reload = "require",
},
- maxPreload = 100000,
- preloadFileSize = 10000,
},
+ diagnostics = {
+ globals = { "vim", "lvim", "packer_plugins", "reload" },
+ },
+ workspace = default_workspace,
},
},
}
diff --git a/lua/lvim/lsp/utils.lua b/lua/lvim/lsp/utils.lua
index b92ef11c..44e4f5f7 100644
--- a/lua/lvim/lsp/utils.lua
+++ b/lua/lvim/lsp/utils.lua
@@ -1,6 +1,7 @@
local M = {}
local tbl = require "lvim.utils.table"
+local Log = require "lvim.core.log"
function M.is_client_active(name)
local clients = vim.lsp.get_active_clients()
@@ -22,25 +23,14 @@ function M.get_active_clients_by_ft(filetype)
end
function M.get_client_capabilities(client_id)
- local client
- if not client_id then
- local buf_clients = vim.lsp.buf_get_clients()
- for _, buf_client in pairs(buf_clients) do
- if buf_client.name ~= "null-ls" then
- client = buf_client
- break
- end
- end
- else
- client = vim.lsp.get_client_by_id(tonumber(client_id))
- end
+ local client = vim.lsp.get_client_by_id(tonumber(client_id))
if not client then
- error "Unable to determine client_id"
+ Log:warn("Unable to determine client from client_id: " .. client_id)
return
end
local enabled_caps = {}
- for capability, status in pairs(client.server_capabilities or client.resolved_capabilities) do
+ for capability, status in pairs(client.server_capabilities) do
if status == true then
table.insert(enabled_caps, capability)
end
@@ -82,30 +72,55 @@ function M.get_all_supported_filetypes()
end
function M.setup_document_highlight(client, bufnr)
+ if lvim.builtin.illuminate.active then
+ Log:debug "skipping setup for document_highlight, illuminate already active"
+ return
+ end
local status_ok, highlight_supported = pcall(function()
return client.supports_method "textDocument/documentHighlight"
end)
if not status_ok or not highlight_supported then
return
end
- local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
- group = "lsp_document_highlight",
+ local group = "lsp_document_highlight"
+ local hl_events = { "CursorHold", "CursorHoldI" }
+
+ local ok, hl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+ group = group,
+ buffer = bufnr,
+ event = hl_events,
})
- if not augroup_exist then
- vim.api.nvim_create_augroup("lsp_document_highlight", {})
+
+ if ok and #hl_autocmds > 0 then
+ return
end
- vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
- group = "lsp_document_highlight",
+
+ vim.api.nvim_create_augroup(group, { clear = false })
+ vim.api.nvim_create_autocmd(hl_events, {
+ group = group,
buffer = bufnr,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd("CursorMoved", {
- group = "lsp_document_highlight",
+ group = group,
buffer = bufnr,
callback = vim.lsp.buf.clear_references,
})
end
+function M.setup_document_symbols(client, bufnr)
+ vim.g.navic_silence = false -- can be set to true to suppress error
+ local symbols_supported = client.supports_method "textDocument/documentSymbol"
+ if not symbols_supported then
+ Log:debug("skipping setup for document_symbols, method not supported by " .. client.name)
+ return
+ end
+ local status_ok, navic = pcall(require, "nvim-navic")
+ if status_ok then
+ navic.attach(client, bufnr)
+ end
+end
+
function M.setup_codelens_refresh(client, bufnr)
local status_ok, codelens_supported = pcall(function()
return client.supports_method "textDocument/codeLens"
@@ -113,14 +128,20 @@ function M.setup_codelens_refresh(client, bufnr)
if not status_ok or not codelens_supported then
return
end
- local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
- group = "lsp_code_lens_refresh",
+ local group = "lsp_code_lens_refresh"
+ local cl_events = { "BufEnter", "InsertLeave" }
+ local ok, cl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+ group = group,
+ buffer = bufnr,
+ event = cl_events,
})
- if not augroup_exist then
- vim.api.nvim_create_augroup("lsp_code_lens_refresh", {})
+
+ if ok and #cl_autocmds > 0 then
+ return
end
- vim.api.nvim_create_autocmd({ "BufEnter", "InsertLeave" }, {
- group = "lsp_code_lens_refresh",
+ vim.api.nvim_create_augroup(group, { clear = false })
+ vim.api.nvim_create_autocmd(cl_events, {
+ group = group,
buffer = bufnr,
callback = vim.lsp.codelens.refresh,
})
@@ -135,9 +156,9 @@ function M.format_filter(client)
local n = require "null-ls"
local s = require "null-ls.sources"
local method = n.methods.FORMATTING
- local avalable_formatters = s.get_available(filetype, method)
+ local available_formatters = s.get_available(filetype, method)
- if #avalable_formatters > 0 then
+ if #available_formatters > 0 then
return client.name == "null-ls"
elseif client.supports_method "textDocument/formatting" then
return true
@@ -146,47 +167,13 @@ function M.format_filter(client)
end
end
----Provide vim.lsp.buf.format for nvim <0.8
----@param opts table
+---Simple wrapper for vim.lsp.buf.format() to provide defaults
+---@param opts table|nil
function M.format(opts)
opts = opts or {}
opts.filter = opts.filter or M.format_filter
- if vim.lsp.buf.format then
- return vim.lsp.buf.format(opts)
- end
-
- local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
-
- ---@type table|nil
- local clients = vim.lsp.get_active_clients {
- id = opts.id,
- bufnr = bufnr,
- name = opts.name,
- }
-
- if opts.filter then
- clients = vim.tbl_filter(opts.filter, clients)
- end
-
- clients = vim.tbl_filter(function(client)
- return client.supports_method "textDocument/formatting"
- end, clients)
-
- if #clients == 0 then
- vim.notify_once "[LSP] Format request failed, no matching language servers."
- end
-
- local timeout_ms = opts.timeout_ms or 1000
- for _, client in pairs(clients) do
- local params = vim.lsp.util.make_formatting_params(opts.formatting_options)
- local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
- if result and result.result then
- vim.lsp.util.apply_text_edits(result.result, bufnr, client.offset_encoding)
- elseif err then
- vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)
- end
- end
+ return vim.lsp.buf.format(opts)
end
return M