diff options
Diffstat (limited to 'lua/lvim/lsp')
-rw-r--r-- | lua/lvim/lsp/config.lua | 32 | ||||
-rw-r--r-- | lua/lvim/lsp/init.lua | 11 | ||||
-rw-r--r-- | lua/lvim/lsp/peek.lua | 157 | ||||
-rw-r--r-- | lua/lvim/lsp/providers/sumneko_lua.lua | 63 | ||||
-rw-r--r-- | lua/lvim/lsp/utils.lua | 119 |
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 |