From 5ede0c906ab174678e39237fe55f24bc5ae99348 Mon Sep 17 00:00:00 2001 From: christianchiarulli Date: Sun, 29 Aug 2021 14:25:27 -0400 Subject: feat: darker doc highlights --- lua/lsp/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 9c948803..1e1ff22e 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -19,9 +19,9 @@ local function lsp_highlight_document(client) if client.resolved_capabilities.document_highlight then vim.api.nvim_exec( [[ - hi LspReferenceRead cterm=bold ctermbg=red guibg=#464646 - hi LspReferenceText cterm=bold ctermbg=red guibg=#464646 - hi LspReferenceWrite cterm=bold ctermbg=red guibg=#464646 + hi LspReferenceRead cterm=bold ctermbg=red guibg=#353d46 + hi LspReferenceText cterm=bold ctermbg=red guibg=#353d46 + hi LspReferenceWrite cterm=bold ctermbg=red guibg=#353d46 augroup lsp_document_highlight autocmd! * autocmd CursorHold lua vim.lsp.buf.document_highlight() -- cgit v1.2.3 From bc5b315e534ac4c15af50edc5890fe328b8825d3 Mon Sep 17 00:00:00 2001 From: "hui.liu" Date: Mon, 30 Aug 2021 20:48:17 +0800 Subject: Setup tailwindcss language server (#1376) --- lua/lsp/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 1e1ff22e..b43bd419 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -125,7 +125,7 @@ end function M.setup(lang) local lsp_utils = require "lsp.utils" local lsp = lvim.lang[lang].lsp - if lsp_utils.is_client_active(lsp.provider) then + if (lsp.active ~= nil and not lsp.active) or lsp_utils.is_client_active(lsp.provider) then return end -- cgit v1.2.3 From 34301ead61bebc8228d7212bb38389fbe02fb534 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 30 Aug 2021 18:44:34 +0430 Subject: Set correct cursor in the peek preview window (#1424) --- lua/lsp/peek.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'lua/lsp') diff --git a/lua/lsp/peek.lua b/lua/lsp/peek.lua index cc8e57a9..dbc67417 100644 --- a/lua/lsp/peek.lua +++ b/lua/lsp/peek.lua @@ -42,6 +42,7 @@ local function create_floating_file(location, opts) 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 -- cgit v1.2.3 From e9d8d8cd2ed24740ad881f74632feaafae83fe1d Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Wed, 1 Sep 2021 13:19:20 +0430 Subject: fix the string concat in logging (#1441) --- lua/lsp/null-ls/formatters.lua | 6 +++--- lua/lsp/null-ls/linters.lua | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index 26be00da..2c2a4f06 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -45,15 +45,15 @@ function M.list_configured(formatter_configs) local formatter = null_ls.builtins.formatting[fmt_config.exe] if not formatter then - Log:error("Not a valid formatter:", fmt_config.exe) + Log:error("Not a valid formatter: " .. fmt_config.exe) errors[fmt_config.exe] = {} -- Add data here when necessary else local formatter_cmd = services.find_command(formatter._opts.command) if not formatter_cmd then - Log:warn("Not found:", formatter._opts.command) + Log:warn("Not found: " .. formatter._opts.command) errors[fmt_config.exe] = {} -- Add data here when necessary else - Log:debug("Using formatter:", formatter_cmd) + Log:debug("Using formatter: " .. formatter_cmd) formatters[fmt_config.exe] = formatter.with { command = formatter_cmd, extra_args = fmt_config.args } end end diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index bc191d7e..d88a8b83 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -45,15 +45,15 @@ function M.list_configured(linter_configs) local linter = null_ls.builtins.diagnostics[lnt_config.exe] if not linter then - Log:error("Not a valid linter:", lnt_config.exe) + Log:error("Not a valid linter: " .. lnt_config.exe) errors[lnt_config.exe] = {} -- Add data here when necessary else local linter_cmd = services.find_command(linter._opts.command) if not linter_cmd then - Log:warn("Not found:", linter._opts.command) + Log:warn("Not found: " .. linter._opts.command) errors[lnt_config.exe] = {} -- Add data here when necessary else - Log:debug("Using linter:", linter_cmd) + Log:debug("Using linter: " .. linter_cmd) linters[lnt_config.exe] = linter.with { command = linter_cmd, extra_args = lnt_config.args } end end -- cgit v1.2.3 From 2fa5c64cd08889a21c677e7bef25260fa2b3b878 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Sat, 4 Sep 2021 12:23:00 +0430 Subject: use a separate func instead of replacing the diagnostics messages (#1462) * use a separate func instead of replacing the diagnostics messages * fix the styling, also return if no diagnostic is available --- lua/lsp/handlers.lua | 80 +++++++++++++++++++++++++++++++++++++++++----------- lua/lsp/init.lua | 2 +- 2 files changed, 64 insertions(+), 18 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 2322e76a..6d813bd7 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -26,28 +26,11 @@ function M.setup() local diagnostics = params.diagnostics - for i, v in ipairs(diagnostics) do - local source = v.source - if source then - if string.find(source, "/") then - source = string.sub(v.source, string.find(v.source, "([%w-_]+)$")) - end - diagnostics[i].message = string.format("%s: %s", source, v.message) - else - diagnostics[i].message = string.format("%s", v.message) - end - - if vim.tbl_contains(vim.tbl_keys(v), "code") then - diagnostics[i].message = diagnostics[i].message .. string.format(" [%s]", v.code) - end - end - vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) if not vim.api.nvim_buf_is_loaded(bufnr) then return end - vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config) end @@ -60,4 +43,67 @@ function M.setup() }) end +function M.show_line_diagnostics() + local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() + local diags = vim.deepcopy(diagnostics) + local height = #diagnostics + local width = 0 + local opts = {} + local close_events = { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" } + local diagnostic_severities = { + "Error", + "Warning", + "Information", + "Hint", + } + if height == 0 then + return + end + local bufnr = vim.api.nvim_create_buf(false, true) + + for i, diagnostic in ipairs(diagnostics) do + local source = diagnostic.source + if source then + if string.find(source, "/") then + source = string.sub(diagnostic.source, string.find(diagnostic.source, "([%w-_]+)$")) + end + diags[i].message = string.format("%s: %s", source, diagnostic.message) + else + diags[i].message = string.format("%s", diagnostic.message) + end + + if diagnostic.code then + diags[i].message = string.format("%s [%s]", diags[i].message, diagnostic.code) + end + if diags[i].message:len() > width then + width = string.len(diags[i].message) + end + end + + opts = vim.lsp.util.make_floating_popup_options(width, height, opts) + opts["style"] = "minimal" + opts["border"] = "rounded" + + 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_buf_set_var(bufnr, "lsp_floating_window", winnr) + for i, diag in ipairs(diags) do + vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { diag.message }) + vim.api.nvim_buf_add_highlight( + bufnr, + -1, + "LspDiagnosticsFloating" .. diagnostic_severities[diag.severity], + i - 1, + 0, + diag.message:len() + ) + end + + vim.api.nvim_command( + "autocmd QuitPre ++nested ++once lua pcall(vim.api.nvim_win_close, " .. winnr .. ", true)" + ) + vim.lsp.util.close_preview_autocmd(close_events, winnr) +end + return M diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index b43bd419..a734293a 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -48,7 +48,7 @@ local function add_lsp_buffer_keybindings(bufnr) ["gs"] = { "lua vim.lsp.buf.signature_help()", "show signature help" }, ["gp"] = { "lua require'lsp.peek'.Peek('definition')", "Peek definition" }, ["gl"] = { - "lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = 'single' })", + "lua require'lsp.handlers'.show_line_diagnostics()", "Show line diagnostics", }, } -- cgit v1.2.3 From 2ccae0a74657e831c19c13039e7d4bcd201bc78b Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 6 Sep 2021 12:49:00 +0430 Subject: fix `string cannot contain newlines` error while showing diagnostics (#1487) --- lua/lsp/handlers.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 6d813bd7..ae06116e 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -89,7 +89,8 @@ function M.show_line_diagnostics() vim.api.nvim_win_set_option(winnr, "winblend", 0) vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) for i, diag in ipairs(diags) do - vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { diag.message }) + local message = diag.message:gsub("[\n\r]", " ") + vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { message }) vim.api.nvim_buf_add_highlight( bufnr, -1, -- cgit v1.2.3 From 9ece2e5369de46962422837be3dce3b8e889805d Mon Sep 17 00:00:00 2001 From: Christian Chiarulli Date: Tue, 7 Sep 2021 19:23:14 -0400 Subject: feat: compe -> cmp (#1496) --- lua/lsp/init.lua | 6 ++++++ lua/lsp/kind.lua | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 lua/lsp/kind.lua (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index a734293a..edac2245 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -65,6 +65,12 @@ function M.common_capabilities() "additionalTextEdits", }, } + + local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") + if not status_ok then + return + end + capabilities = cmp_nvim_lsp.update_capabilities(capabilities) return capabilities end diff --git a/lua/lsp/kind.lua b/lua/lsp/kind.lua new file mode 100644 index 00000000..b78fd318 --- /dev/null +++ b/lua/lsp/kind.lua @@ -0,0 +1,31 @@ +local M = {} + +M.icons = { + Class = " ", + Color = " ", + Constant = "ﲀ ", + Constructor = " ", + Enum = "練", + EnumMember = " ", + Event = " ", + Field = " ", + File = "", + Folder = " ", + Function = " ", + Interface = "ﰮ ", + Keyword = " ", + Method = " ", + Module = " ", + Operator = "", + Property = " ", + Reference = " ", + Snippet = " ", + Struct = " ", + Text = " ", + TypeParameter = " ", + Unit = "塞", + Value = " ", + Variable = " ", +} + +return M -- cgit v1.2.3 From 8c83b403ef833101a93b53cc232368424b3dff9b Mon Sep 17 00:00:00 2001 From: christianchiarulli Date: Tue, 7 Sep 2021 19:40:40 -0400 Subject: fix: vim.uri bug in 0.6 --- lua/lsp/handlers.lua | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index ae06116e..2efa8d10 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -9,29 +9,43 @@ function M.setup() underline = lvim.lsp.document_highlight, }) - vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) - local config = { -- your config - virtual_text = lvim.lsp.diagnostics.virtual_text, - signs = lvim.lsp.diagnostics.signs, - underline = lvim.lsp.diagnostics.underline, - update_in_insert = lvim.lsp.diagnostics.update_in_insert, - severity_sort = lvim.lsp.diagnostics.severity_sort, - } - local uri = params.uri - local bufnr = vim.uri_to_bufnr(uri) + local config = { -- your config + virtual_text = lvim.lsp.diagnostics.virtual_text, + signs = lvim.lsp.diagnostics.signs, + underline = lvim.lsp.diagnostics.underline, + update_in_insert = lvim.lsp.diagnostics.update_in_insert, + severity_sort = lvim.lsp.diagnostics.severity_sort, + } + if vim.fn.has "nvim-0.5.1" > 0 then + vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, result, ctx, _) + local uri = result.uri + local bufnr = ctx.bufnr + if not bufnr then + return + end - if not bufnr then - return + local diagnostics = result.diagnostics + vim.lsp.diagnostic.save(diagnostics, ctx.bufnr, ctx.client_id) + if not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + vim.lsp.diagnostic.display(diagnostics, bufnr, ctx.client_id, config) end + else + vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) + local uri = params.uri + local bufnr = vim.uri_to_bufnr(uri) + if not bufnr then + return + end - local diagnostics = params.diagnostics - - vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) - - if not vim.api.nvim_buf_is_loaded(bufnr) then - return + local diagnostics = params.diagnostics + vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) + if not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config) end - vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config) end vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { -- cgit v1.2.3 From f338f3577ce0b842f6592cde544ffac37c17c75d Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Wed, 8 Sep 2021 16:38:57 +0430 Subject: show correct inline diagnostics in neovim 0.6 (#1502) --- lua/lsp/handlers.lua | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 2efa8d10..84811581 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -3,12 +3,6 @@ local M = {} function M.setup() - vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = lvim.lsp.diagnostics.virtual_text, - signs = lvim.lsp.diagnostics.signs.active, - underline = lvim.lsp.document_highlight, - }) - local config = { -- your config virtual_text = lvim.lsp.diagnostics.virtual_text, signs = lvim.lsp.diagnostics.signs, @@ -19,13 +13,13 @@ function M.setup() if vim.fn.has "nvim-0.5.1" > 0 then vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, result, ctx, _) local uri = result.uri - local bufnr = ctx.bufnr + local bufnr = vim.uri_to_bufnr(uri) if not bufnr then return end local diagnostics = result.diagnostics - vim.lsp.diagnostic.save(diagnostics, ctx.bufnr, ctx.client_id) + vim.lsp.diagnostic.save(diagnostics, bufnr, ctx.client_id) if not vim.api.nvim_buf_is_loaded(bufnr) then return end -- cgit v1.2.3 From 8eed75d67f9cbcefb91c4cb5aac0ffd013be25cc Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Mon, 13 Sep 2021 11:28:15 +0200 Subject: refactor: use more flexible paths (#1381) --- lua/lsp/init.lua | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index edac2245..3fa4fb94 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -1,16 +1,6 @@ local M = {} local Log = require "core.log" -function M.config() - vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind - - for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do - vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) - end - - require("lsp.handlers").setup() -end - local function lsp_highlight_document(client) if lvim.lsp.document_highlight == false then return -- we don't need further @@ -159,4 +149,29 @@ function M.setup(lang) end end +function M.global_setup() + vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind + + for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do + vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) + end + + require("lsp.handlers").setup() + + local null_status_ok, null_ls = pcall(require, "null-ls") + if null_status_ok then + null_ls.config() + require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) + end + + local utils = require "utils" + + local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") + if lsp_settings_status_ok then + lsp_settings.setup { + config_home = utils.join_paths(get_config_dir(), "lsp-settings"), + } + end +end + return M -- cgit v1.2.3 From e10cd48ea2b85158eb830f14629963903be8ad42 Mon Sep 17 00:00:00 2001 From: Luong Vo Date: Mon, 13 Sep 2021 16:30:06 +0700 Subject: fix: common capabilities returning nothing if no cmp_nvim_lsp (#1537) Signed-off-by: Luong Vo --- lua/lsp/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 3fa4fb94..3c921e65 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -57,10 +57,10 @@ function M.common_capabilities() } local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") - if not status_ok then - return + if status_ok then + capabilities = cmp_nvim_lsp.update_capabilities(capabilities) end - capabilities = cmp_nvim_lsp.update_capabilities(capabilities) + return capabilities end -- cgit v1.2.3 From 168eb232d12f86e98f0d90c4e73e0c9968a3cb8e Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Wed, 15 Sep 2021 23:42:57 +0430 Subject: feature: make peek function work in neovim head and 0.5 (#1559) --- lua/lsp/peek.lua | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/peek.lua b/lua/lsp/peek.lua index dbc67417..cb00488e 100644 --- a/lua/lsp/peek.lua +++ b/lua/lsp/peek.lua @@ -54,9 +54,8 @@ local function create_floating_file(location, opts) return bufnr, winnr end -local function preview_location_callback(_, method, result) +local function preview_location_callback(result) if result == nil or vim.tbl_isempty(result) then - print("peek: No location found: " .. method) return nil end @@ -74,6 +73,14 @@ local function preview_location_callback(_, method, result) end end +local function preview_location_callback_old_signature(_, _, result) + return preview_location_callback(result) +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 "%:." @@ -129,7 +136,11 @@ function M.Peek(what) else -- Make a new request and then create the new window in the callback local params = vim.lsp.util.make_position_params() - local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_location_callback) + local preview_callback = preview_location_callback_old_signature + if vim.fn.has "nvim-0.5.1" > 0 then + preview_callback = preview_location_callback_new_signature + end + local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback) if not success then print( 'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.' -- cgit v1.2.3 From 65392c553ea6a69053a99fea57c3dee6c48afa75 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Sat, 18 Sep 2021 13:23:30 +0430 Subject: feature: vim.api.diagnostics has been moved to vim.diagnostics in neovim head (#1573) --- lua/lsp/handlers.lua | 72 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 18 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 84811581..d55bd0b2 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -19,11 +19,41 @@ function M.setup() end local diagnostics = result.diagnostics - vim.lsp.diagnostic.save(diagnostics, bufnr, ctx.client_id) - if not vim.api.nvim_buf_is_loaded(bufnr) then - return + local ok, vim_diag = pcall(require, "vim.diagnostic") + if ok then + -- FIX: why can't we just use vim.diagnostic.get(buf_id)? + config.signs = true + for i, diagnostic in ipairs(diagnostics) do + local rng = diagnostic.range + diagnostics[i].lnum = rng["start"].line + diagnostics[i].end_lnum = rng["end"].line + diagnostics[i].col = rng["start"].character + diagnostics[i].end_col = rng["end"].character + end + local namespace = vim.lsp.diagnostic.get_namespace(ctx.client_id) + + vim_diag.set(namespace, bufnr, diagnostics, config) + if not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + + local sign_names = { + "DiagnosticSignError", + "DiagnosticSignWarn", + "DiagnosticSignInfo", + "DiagnosticSignHint", + } + for i, sign in ipairs(lvim.lsp.diagnostics.signs.values) do + vim.fn.sign_define(sign_names[i], { texthl = sign_names[i], text = sign.text, numhl = "" }) + end + vim_diag.show(namespace, bufnr, diagnostics, config) + else + vim.lsp.diagnostic.save(diagnostics, bufnr, ctx.client_id) + if not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + vim.lsp.diagnostic.display(diagnostics, bufnr, ctx.client_id, config) end - vim.lsp.diagnostic.display(diagnostics, bufnr, ctx.client_id, config) end else vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) @@ -53,17 +83,30 @@ end function M.show_line_diagnostics() local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() + local severity_highlight = { + "LspDiagnosticsFloatingError", + "LspDiagnosticsFloatingWarning", + "LspDiagnosticsFloatingInformation", + "LspDiagnosticsFloatingHint", + } + local ok, vim_diag = pcall(require, "vim.diagnostic") + if ok then + local buf_id = vim.api.nvim_win_get_buf(0) + local win_id = vim.api.nvim_get_current_win() + local cursor_position = vim.api.nvim_win_get_cursor(win_id) + severity_highlight = { + "DiagnosticFloatingError", + "DiagnosticFloatingWarn", + "DiagnosticFloatingInfo", + "DiagnosticFloatingHint", + } + diagnostics = vim_diag.get(buf_id, { lnum = cursor_position[1] - 1 }) + end local diags = vim.deepcopy(diagnostics) local height = #diagnostics local width = 0 local opts = {} local close_events = { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" } - local diagnostic_severities = { - "Error", - "Warning", - "Information", - "Hint", - } if height == 0 then return end @@ -99,14 +142,7 @@ function M.show_line_diagnostics() for i, diag in ipairs(diags) do local message = diag.message:gsub("[\n\r]", " ") vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { message }) - vim.api.nvim_buf_add_highlight( - bufnr, - -1, - "LspDiagnosticsFloating" .. diagnostic_severities[diag.severity], - i - 1, - 0, - diag.message:len() - ) + vim.api.nvim_buf_add_highlight(bufnr, -1, severity_highlight[diag.severity], i - 1, 0, diag.message:len()) end vim.api.nvim_command( -- cgit v1.2.3 From dbb958289b19f18739bc3d935e41e6c7ce75eab6 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 20 Sep 2021 14:15:22 +0430 Subject: add support for local stylelint (#1586) --- lua/lsp/null-ls/services.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'lua/lsp') diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua index a1e3a06c..1e76b40a 100644 --- a/lua/lsp/null-ls/services.lua +++ b/lua/lsp/null-ls/services.lua @@ -28,6 +28,7 @@ local local_providers = { prettier_d_slim = { find = from_node_modules }, eslint_d = { find = from_node_modules }, eslint = { find = from_node_modules }, + stylelint = { find = from_node_modules }, } function M.find_command(command) -- cgit v1.2.3 From 55d9a15a088d688627426b034f4b71aa86a8ce9e Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Tue, 21 Sep 2021 13:29:32 +0430 Subject: [Bugfix] Wrap the `gl` floating window diagnostics (#1588) --- lua/lsp/handlers.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index d55bd0b2..2f06cb8a 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -126,18 +126,20 @@ function M.show_line_diagnostics() if diagnostic.code then diags[i].message = string.format("%s [%s]", diags[i].message, diagnostic.code) end - if diags[i].message:len() > width then - width = string.len(diags[i].message) - end + width = math.max(width, diags[i].message:len()) end + local max_width = vim.fn.winwidth(0) - 10 + width = math.min(width, max_width) opts = vim.lsp.util.make_floating_popup_options(width, height, opts) opts["style"] = "minimal" opts["border"] = "rounded" + opts["focusable"] = true 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_option(winnr, "wrap", true) vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) for i, diag in ipairs(diags) do local message = diag.message:gsub("[\n\r]", " ") -- cgit v1.2.3 From edeadaf05d98034bc91a22ad50263a7a25c6020a Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Wed, 22 Sep 2021 10:56:52 +0330 Subject: [Bugfix] instead of wrapping the `gl` diagnostics, split them (#1595) --- lua/lsp/handlers.lua | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 2f06cb8a..ffb7564a 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -81,7 +81,16 @@ function M.setup() }) end +local function split_by_chunk(text, chunkSize) + local s = {} + for i = 1, #text, chunkSize do + s[#s + 1] = text:sub(i, i + chunkSize - 1) + end + return s +end + function M.show_line_diagnostics() + -- TODO: replace all this with vim.diagnostic.show_position_diagnostics() local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() local severity_highlight = { "LspDiagnosticsFloatingError", @@ -102,7 +111,8 @@ function M.show_line_diagnostics() } diagnostics = vim_diag.get(buf_id, { lnum = cursor_position[1] - 1 }) end - local diags = vim.deepcopy(diagnostics) + local lines = {} + local max_width = vim.fn.winwidth(0) - 5 local height = #diagnostics local width = 0 local opts = {} @@ -111,26 +121,31 @@ function M.show_line_diagnostics() return end local bufnr = vim.api.nvim_create_buf(false, true) - + local diag_message + table.sort(diagnostics, function(a, b) + return a.severity < b.severity + end) for i, diagnostic in ipairs(diagnostics) do local source = diagnostic.source + diag_message = diagnostic.message:gsub("[\n\r]", " ") if source then if string.find(source, "/") then source = string.sub(diagnostic.source, string.find(diagnostic.source, "([%w-_]+)$")) end - diags[i].message = string.format("%s: %s", source, diagnostic.message) + diag_message = string.format("%d. %s: %s", i, source, diag_message) else - diags[i].message = string.format("%s", diagnostic.message) + diag_message = string.format("%d. %s", i, diag_message) end - if diagnostic.code then - diags[i].message = string.format("%s [%s]", diags[i].message, diagnostic.code) + diag_message = string.format("%s [%s]", diag_message, diagnostic.code) + end + local msgs = split_by_chunk(diag_message, max_width) + for _, diag in ipairs(msgs) do + table.insert(lines, { message = diag, severity = diagnostic.severity }) + width = math.max(diag:len(), width) end - width = math.max(width, diags[i].message:len()) end - local max_width = vim.fn.winwidth(0) - 10 - width = math.min(width, max_width) - + height = #lines opts = vim.lsp.util.make_floating_popup_options(width, height, opts) opts["style"] = "minimal" opts["border"] = "rounded" @@ -139,11 +154,9 @@ function M.show_line_diagnostics() 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_option(winnr, "wrap", true) vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) - for i, diag in ipairs(diags) do - local message = diag.message:gsub("[\n\r]", " ") - vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { message }) + for i, diag in ipairs(lines) do + vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { diag.message }) vim.api.nvim_buf_add_highlight(bufnr, -1, severity_highlight[diag.severity], i - 1, 0, diag.message:len()) end -- cgit v1.2.3 From 1e0d0181d55abe1e4248b3aeaded94cbf3308168 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Sat, 2 Oct 2021 18:04:38 +0330 Subject: feat: make lsp highlight color configurable (#1659) --- lua/lsp/init.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 3c921e65..386be075 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -9,9 +9,6 @@ local function lsp_highlight_document(client) if client.resolved_capabilities.document_highlight then vim.api.nvim_exec( [[ - hi LspReferenceRead cterm=bold ctermbg=red guibg=#353d46 - hi LspReferenceText cterm=bold ctermbg=red guibg=#353d46 - hi LspReferenceWrite cterm=bold ctermbg=red guibg=#353d46 augroup lsp_document_highlight autocmd! * autocmd CursorHold lua vim.lsp.buf.document_highlight() -- cgit v1.2.3 From d01ba08eaec1640ac2d038893525b3ba0af25813 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Sun, 3 Oct 2021 16:13:46 +0200 Subject: refactor: auto-generate language configuration (#1584) Refactor the monolithic `lvim.lang` design into a more modular approach. IMPORTANT: run `:LvimUpdate` in order to generate the new ftplugin template files. --- lua/lsp/config.lua | 27 ++++++++++ lua/lsp/init.lua | 102 ++++++++++---------------------------- lua/lsp/kind.lua | 31 ------------ lua/lsp/manager.lua | 82 ++++++++++++++++++++++++++++++ lua/lsp/null-ls/formatters.lua | 30 +++-------- lua/lsp/null-ls/init.lua | 54 +++++++------------- lua/lsp/null-ls/linters.lua | 30 +++-------- lua/lsp/null-ls/services.lua | 15 ++++++ lua/lsp/providers/jsonls.lua | 30 +++++++++++ lua/lsp/providers/sumneko_lua.lua | 19 +++++++ lua/lsp/providers/vuels.lua | 26 ++++++++++ lua/lsp/templates.lua | 98 ++++++++++++++++++++++++++++++++++++ lua/lsp/utils.lua | 57 ++++++++++++++++++--- 13 files changed, 405 insertions(+), 196 deletions(-) create mode 100644 lua/lsp/config.lua delete mode 100644 lua/lsp/kind.lua create mode 100644 lua/lsp/manager.lua create mode 100644 lua/lsp/providers/jsonls.lua create mode 100644 lua/lsp/providers/sumneko_lua.lua create mode 100644 lua/lsp/providers/vuels.lua create mode 100644 lua/lsp/templates.lua (limited to 'lua/lsp') diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua new file mode 100644 index 00000000..146301c9 --- /dev/null +++ b/lua/lsp/config.lua @@ -0,0 +1,27 @@ +return { + templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"), + diagnostics = { + signs = { + active = true, + values = { + { name = "LspDiagnosticsSignError", text = "" }, + { name = "LspDiagnosticsSignWarning", text = "" }, + { name = "LspDiagnosticsSignHint", text = "" }, + { name = "LspDiagnosticsSignInformation", text = "" }, + }, + }, + virtual_text = { + prefix = "", + spacing = 0, + }, + update_in_insert = false, + underline = true, + severity_sort = true, + }, + override = {}, + document_highlight = true, + popup_border = "single", + on_attach_callback = nil, + on_init_callback = nil, + automatic_servers_installation = true, +} diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 386be075..7f20a39d 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -1,5 +1,6 @@ local M = {} local Log = require "core.log" +local utils = require "utils" local function lsp_highlight_document(client) if lvim.lsp.document_highlight == false then @@ -61,48 +62,12 @@ function M.common_capabilities() return capabilities end -function M.get_ls_capabilities(client_id) - local client - if not client_id then - local buf_clients = vim.lsp.buf_get_clients() - for _, buf_client in ipairs(buf_clients) do - if buf_client.name ~= "null-ls" then - client_id = buf_client.id - break - end - end - end - if not client_id then - error "Unable to determine client_id" - end - - client = vim.lsp.get_client_by_id(tonumber(client_id)) - - local enabled_caps = {} - - for k, v in pairs(client.resolved_capabilities) do - if v == true then - table.insert(enabled_caps, k) - end - end - - return enabled_caps -end - function M.common_on_init(client, bufnr) if lvim.lsp.on_init_callback then lvim.lsp.on_init_callback(client, bufnr) Log:debug "Called lsp.on_init_callback" return end - - local formatters = lvim.lang[vim.bo.filetype].formatters - if not vim.tbl_isempty(formatters) and formatters[1]["exe"] ~= nil and formatters[1].exe ~= "" then - client.resolved_capabilities.document_formatting = false - Log:debug( - string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe) - ) - end end function M.common_on_attach(client, bufnr) @@ -112,63 +77,46 @@ function M.common_on_attach(client, bufnr) end lsp_highlight_document(client) add_lsp_buffer_keybindings(bufnr) - require("lsp.null-ls").setup(vim.bo.filetype) end -function M.setup(lang) - local lsp_utils = require "lsp.utils" - local lsp = lvim.lang[lang].lsp - if (lsp.active ~= nil and not lsp.active) or lsp_utils.is_client_active(lsp.provider) then - return - end - - local overrides = lvim.lsp.override - if type(overrides) == "table" then - if vim.tbl_contains(overrides, lang) then - return - end +local function bootstrap_nlsp(opts) + opts = opts or {} + local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") + if lsp_settings_status_ok then + lsp_settings.setup(opts) end +end - if lsp.provider ~= nil and lsp.provider ~= "" then - local lspconfig = require "lspconfig" +function M.get_common_opts() + return { + on_attach = M.common_on_attach, + on_init = M.common_on_init, + capabilities = M.common_capabilities(), + } +end - if not lsp.setup.on_attach then - lsp.setup.on_attach = M.common_on_attach - end - if not lsp.setup.on_init then - lsp.setup.on_init = M.common_on_init - end - if not lsp.setup.capabilities then - lsp.setup.capabilities = M.common_capabilities() - end +function M.setup() + Log:debug "Setting up LSP support" - lspconfig[lsp.provider].setup(lsp.setup) + local lsp_status_ok, _ = pcall(require, "lspconfig") + if not lsp_status_ok then + return end -end - -function M.global_setup() - vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) end - require("lsp.handlers").setup() - local null_status_ok, null_ls = pcall(require, "null-ls") - if null_status_ok then - null_ls.config() - require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) + if not utils.is_directory(lvim.lsp.templates_dir) then + require("lsp.templates").generate_templates() end - local utils = require "utils" + bootstrap_nlsp { config_home = utils.join_paths(get_config_dir(), "lsp-settings") } - local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") - if lsp_settings_status_ok then - lsp_settings.setup { - config_home = utils.join_paths(get_config_dir(), "lsp-settings"), - } - end + require("lsp.null-ls").setup() + + require("utils").toggle_autoformat() end return M diff --git a/lua/lsp/kind.lua b/lua/lsp/kind.lua deleted file mode 100644 index b78fd318..00000000 --- a/lua/lsp/kind.lua +++ /dev/null @@ -1,31 +0,0 @@ -local M = {} - -M.icons = { - Class = " ", - Color = " ", - Constant = "ﲀ ", - Constructor = " ", - Enum = "練", - EnumMember = " ", - Event = " ", - Field = " ", - File = "", - Folder = " ", - Function = " ", - Interface = "ﰮ ", - Keyword = " ", - Method = " ", - Module = " ", - Operator = "", - Property = " ", - Reference = " ", - Snippet = " ", - Struct = " ", - Text = " ", - TypeParameter = " ", - Unit = "塞", - Value = " ", - Variable = " ", -} - -return M diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua new file mode 100644 index 00000000..24d462ad --- /dev/null +++ b/lua/lsp/manager.lua @@ -0,0 +1,82 @@ +local M = {} + +local Log = require "core.log" +local lsp_utils = require "lsp.utils" + +function M.init_defaults(languages) + for _, entry in ipairs(languages) do + if not lvim.lang[entry] then + lvim.lang[entry] = { + formatters = {}, + linters = {}, + } + end + end +end + +local function is_overridden(server) + local overrides = lvim.lsp.override + if type(overrides) == "table" then + if vim.tbl_contains(overrides, server) then + return + end + end +end + +function M.setup_server(server_name) + vim.validate { + name = { server_name, "string" }, + } + + if lsp_utils.is_client_active(server_name) or is_overridden(server_name) then + return + end + + local lsp_installer_servers = require "nvim-lsp-installer.servers" + local server_available, requested_server = lsp_installer_servers.get_server(server_name) + if server_available then + if not requested_server:is_installed() then + Log:debug(string.format("[%s] is not installed", server_name)) + if lvim.lsp.automatic_servers_installation then + Log:debug(string.format("Installing [%s]", server_name)) + requested_server:install() + else + return + end + end + end + + local default_config = { + on_attach = require("lsp").common_on_attach, + on_init = require("lsp").common_on_init, + capabilities = require("lsp").common_capabilities(), + } + + local status_ok, custom_config = pcall(require, "lsp/providers/" .. requested_server.name) + if status_ok then + local new_config = vim.tbl_deep_extend("force", default_config, custom_config) + Log:debug("Using custom configuration for requested server: " .. requested_server.name) + requested_server:setup(new_config) + else + Log:debug("Using the default configuration for requested server: " .. requested_server.name) + requested_server:setup(default_config) + end +end + +function M.setup(servers) + local status_ok, _ = pcall(require, "nvim-lsp-installer") + if not status_ok then + return + end + + --- allow using a single value + if type(servers) == "string" then + servers = { servers } + end + + for _, server in ipairs(servers) do + M.setup_server(server) + end +end + +return M diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index 2c2a4f06..8199aca0 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -1,29 +1,14 @@ local M = {} -local formatters_by_ft = {} local null_ls = require "null-ls" local services = require "lsp.null-ls.services" local Log = require "core.log" -local function list_names(formatters, options) - options = options or {} - local filter = options.filter or "supported" - - return vim.tbl_keys(formatters[filter]) -end - function M.list_supported_names(filetype) - if not formatters_by_ft[filetype] then - return {} - end - return list_names(formatters_by_ft[filetype], { filter = "supported" }) -end - -function M.list_unsupported_names(filetype) - if not formatters_by_ft[filetype] then - return {} - end - return list_names(formatters_by_ft[filetype], { filter = "unsupported" }) + local null_ls_methods = require "null-ls.methods" + local formatter_method = null_ls_methods.internal["FORMATTING"] + local registered_providers = services.list_registered_providers_names(filetype) + return registered_providers[formatter_method] or {} end function M.list_available(filetype) @@ -62,12 +47,13 @@ function M.list_configured(formatter_configs) return { supported = formatters, unsupported = errors } end -function M.setup(filetype, options) - if not lvim.lang[filetype] or (formatters_by_ft[filetype] and not options.force_reload) then +function M.setup(formatter_configs, filetype) + if vim.tbl_isempty(formatter_configs) then return end - formatters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].formatters) + local formatters_by_ft = {} + formatters_by_ft[filetype] = M.list_configured(formatter_configs) null_ls.register { sources = formatters_by_ft[filetype].supported } end diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua index ce4c07d9..0540fb48 100644 --- a/lua/lsp/null-ls/init.lua +++ b/lua/lsp/null-ls/init.lua @@ -1,44 +1,26 @@ local M = {} -function M.list_supported_provider_names(filetype) - local names = {} - - local formatters = require "lsp.null-ls.formatters" - local linters = require "lsp.null-ls.linters" - - vim.list_extend(names, formatters.list_supported_names(filetype)) - vim.list_extend(names, linters.list_supported_names(filetype)) - - return names -end - -function M.list_unsupported_provider_names(filetype) - local names = {} - - local formatters = require "lsp.null-ls.formatters" - local linters = require "lsp.null-ls.linters" - - vim.list_extend(names, formatters.list_unsupported_names(filetype)) - vim.list_extend(names, linters.list_unsupported_names(filetype)) - - return names -end - --- TODO: for linters and formatters with spaces and '-' replace with '_' -function M.setup(filetype, options) - options = options or {} - - local ok, _ = pcall(require, "null-ls") - if not ok then - require("core.log"):error "Missing null-ls dependency" +local Log = require "core.log" +local formatters = require "lsp.null-ls.formatters" +local linters = require "lsp.null-ls.linters" + +function M:setup() + local status_ok, null_ls = pcall(require, "null-ls") + if not status_ok then + Log:error "Missing null-ls dependency" return end - local formatters = require "lsp.null-ls.formatters" - local linters = require "lsp.null-ls.linters" - - formatters.setup(filetype, options) - linters.setup(filetype, options) + null_ls.config() + require("lspconfig")["null-ls"].setup {} + for _, filetype in pairs(lvim.lang) do + if filetype.formatters then + formatters.setup(filetype.formatters, filetype) + end + if filetype.linters then + linters.setup(filetype.linters, filetype) + end + end end return M diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index d88a8b83..ea45fa87 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -1,29 +1,14 @@ local M = {} -local linters_by_ft = {} local null_ls = require "null-ls" local services = require "lsp.null-ls.services" local Log = require "core.log" -local function list_names(linters, options) - options = options or {} - local filter = options.filter or "supported" - - return vim.tbl_keys(linters[filter]) -end - function M.list_supported_names(filetype) - if not linters_by_ft[filetype] then - return {} - end - return list_names(linters_by_ft[filetype], { filter = "supported" }) -end - -function M.list_unsupported_names(filetype) - if not linters_by_ft[filetype] then - return {} - end - return list_names(linters_by_ft[filetype], { filter = "unsupported" }) + local null_ls_methods = require "null-ls.methods" + local linter_method = null_ls_methods.internal["DIAGNOSTICS"] + local registered_providers = services.list_registered_providers_names(filetype) + return registered_providers[linter_method] or {} end function M.list_available(filetype) @@ -62,12 +47,13 @@ function M.list_configured(linter_configs) return { supported = linters, unsupported = errors } end -function M.setup(filetype, options) - if not lvim.lang[filetype] or (linters_by_ft[filetype] and not options.force_reload) then +function M.setup(linter_configs, filetype) + if vim.tbl_isempty(linter_configs) then return end - linters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].linters) + local linters_by_ft = {} + linters_by_ft[filetype] = M.list_configured(linter_configs) null_ls.register { sources = linters_by_ft[filetype].supported } end diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua index 1e76b40a..c62fc709 100644 --- a/lua/lsp/null-ls/services.lua +++ b/lua/lsp/null-ls/services.lua @@ -45,4 +45,19 @@ function M.find_command(command) return nil end +function M.list_registered_providers_names(filetype) + local u = require "null-ls.utils" + local c = require "null-ls.config" + local registered = {} + for method, source in pairs(c.get()._methods) do + for name, filetypes in pairs(source) do + if u.filetype_matches(filetypes, filetype) then + registered[method] = registered[method] or {} + table.insert(registered[method], name) + end + end + end + return registered +end + return M diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua new file mode 100644 index 00000000..55bc1ea2 --- /dev/null +++ b/lua/lsp/providers/jsonls.lua @@ -0,0 +1,30 @@ +local schemas = nil +local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls") +if status_ok then + schemas = jsonls_settings.get_default_schemas() +end + +local opts = { + setup = { + settings = { + json = { + schemas = schemas, + -- = { + -- { + -- fileMatch = { "package.json" }, + -- url = "https://json.schemastore.org/package.json", + -- }, + -- }, + }, + }, + commands = { + Format = { + function() + vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) + end, + }, + }, + }, +} + +return opts diff --git a/lua/lsp/providers/sumneko_lua.lua b/lua/lsp/providers/sumneko_lua.lua new file mode 100644 index 00000000..4fee1fd1 --- /dev/null +++ b/lua/lsp/providers/sumneko_lua.lua @@ -0,0 +1,19 @@ +local opts = { + settings = { + Lua = { + diagnostics = { + globals = { "vim", "lvim" }, + }, + workspace = { + library = { + [require("utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true, + [vim.fn.expand "$VIMRUNTIME/lua"] = true, + [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, + }, + maxPreload = 100000, + preloadFileSize = 10000, + }, + }, + }, +} +return opts diff --git a/lua/lsp/providers/vuels.lua b/lua/lsp/providers/vuels.lua new file mode 100644 index 00000000..3f44275d --- /dev/null +++ b/lua/lsp/providers/vuels.lua @@ -0,0 +1,26 @@ +local opts = { + setup = { + root_dir = function(fname) + local util = require "lspconfig/util" + return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd() + end, + init_options = { + config = { + vetur = { + completion = { + autoImport = true, + tagCasing = "kebab", + useScaffoldSnippets = true, + }, + useWorkspaceDependencies = true, + validation = { + script = true, + style = true, + template = true, + }, + }, + }, + }, + }, +} +return opts diff --git a/lua/lsp/templates.lua b/lua/lsp/templates.lua new file mode 100644 index 00000000..6ded636d --- /dev/null +++ b/lua/lsp/templates.lua @@ -0,0 +1,98 @@ +local M = {} + +local Log = require "core.log" +local utils = require "utils" +local get_supported_filetypes = require("lsp.utils").get_supported_filetypes + +local ftplugin_dir = lvim.lsp.templates_dir + +local join_paths = _G.join_paths + +function M.remove_template_files() + -- remove any outdated files + for _, file in ipairs(vim.fn.glob(ftplugin_dir .. "/*.lua", 1, 1)) do + vim.fn.delete(file) + end +end + +---Checks if a server is ignored by default because of a conflict +---Only TSServer is enabled by default for the javascript-family +---@param server_name string +function M.is_ignored(server_name, filetypes) + --TODO: this is easy to be made configurable once stable + filetypes = filetypes or get_supported_filetypes(server_name) + + if vim.tbl_contains(filetypes, "javascript") then + if server_name == "tsserver" or server_name == "tailwindcss" then + return false + else + return true + end + end + + local blacklist = { + "jedi_language_server", + "pylsp", + "sqlls", + "sqls", + "angularls", + "ansiblels", + } + return vim.tbl_contains(blacklist, server_name) +end + +---Generates an ftplugin file based on the server_name in the selected directory +---@param server_name string name of a valid language server, e.g. pyright, gopls, tsserver, etc. +---@param dir string the full path to the desired directory +function M.generate_ftplugin(server_name, dir) + -- we need to go through lspconfig to get the corresponding filetypes currently + local filetypes = get_supported_filetypes(server_name) or {} + if not filetypes then + return + end + + if M.is_ignored(server_name, filetypes) then + return + end + + -- print("got associated filetypes: " .. vim.inspect(filetypes)) + + for _, filetype in ipairs(filetypes) do + local filename = join_paths(dir, filetype .. ".lua") + local setup_cmd = string.format([[require("lsp.manager").setup(%q)]], server_name) + -- print("using setup_cmd: " .. setup_cmd) + -- overwrite the file completely + utils.write_file(filename, setup_cmd .. "\n", "a") + end +end + +---Generates ftplugin files based on a list of server_names +---The files are generated to a runtimepath: "$LUNARVIM_RUNTIME_DIR/site/after/ftplugin/template.lua" +---@param servers_names table list of servers to be enabled. Will add all by default +function M.generate_templates(servers_names) + servers_names = servers_names or {} + + Log:debug "Templates installation in progress" + + M.remove_template_files() + + if vim.tbl_isempty(servers_names) then + local available_servers = require("nvim-lsp-installer.servers").get_available_servers() + + for _, server in pairs(available_servers) do + table.insert(servers_names, server.name) + end + end + + -- create the directory if it didn't exist + if not utils.is_directory(lvim.lsp.templates_dir) then + vim.fn.mkdir(ftplugin_dir, "p") + end + + for _, server in ipairs(servers_names) do + M.generate_ftplugin(server, ftplugin_dir) + end + Log:debug "Templates installation is complete" +end + +return M diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua index 17b9c3bc..1a5dd79d 100644 --- a/lua/lsp/utils.lua +++ b/lua/lsp/utils.lua @@ -10,19 +10,60 @@ function M.is_client_active(name) return false end --- FIXME: this should return a list instead -function M.get_active_client_by_ft(filetype) - if not lvim.lang[filetype] or not lvim.lang[filetype].lsp then - return nil - end +function M.disable_formatting_capability(client) + -- FIXME: figure out a reasonable way to do this + client.resolved_capabilities.document_formatting = false + require("core.log"):debug(string.format("Turning off formatting capability for language server [%s] ", client.name)) +end +function M.get_active_client_by_ft(filetype) + local matches = {} local clients = vim.lsp.get_active_clients() for _, client in pairs(clients) do - if client.name == lvim.lang[filetype].lsp.provider then - return client + local supported_filetypes = client.config.filetypes or {} + if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then + table.insert(matches, client) + end + end + return matches +end + +function M.get_ls_capabilities(client_id) + if not client_id then + local buf_clients = vim.lsp.buf_get_clients() + for _, buf_client in ipairs(buf_clients) do + if buf_client.name ~= "null-ls" then + client_id = buf_client.id + break + end + end + end + if not client_id then + error "Unable to determine client_id" + return + end + + local client = vim.lsp.get_client_by_id(tonumber(client_id)) + + local enabled_caps = {} + for capability, status in pairs(client.resolved_capabilities) do + if status == true then + table.insert(enabled_caps, capability) + end + end + + return enabled_caps +end + +function M.get_supported_filetypes(server_name) + -- print("got filetypes query request for: " .. server_name) + local configs = require "lspconfig/configs" + pcall(require, ("lspconfig/" .. server_name)) + for _, config in pairs(configs) do + if config.name == server_name then + return config.document_config.default_config.filetypes or {} end end - return nil end return M -- cgit v1.2.3 From 48a6d859f34f4f0ce29054f4a59722d485aaa06e Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Sun, 3 Oct 2021 22:32:11 +0330 Subject: fix: return correctly for overridden lang servers (#1669) --- lua/lsp/manager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lua/lsp') diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua index 24d462ad..5b6d9767 100644 --- a/lua/lsp/manager.lua +++ b/lua/lsp/manager.lua @@ -18,7 +18,7 @@ local function is_overridden(server) local overrides = lvim.lsp.override if type(overrides) == "table" then if vim.tbl_contains(overrides, server) then - return + return true end end end -- cgit v1.2.3 From 7a939ad771403e20341c9465af66573d225300bb Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Sun, 3 Oct 2021 22:48:41 +0200 Subject: fix: add missing table entry (#1670) --- lua/lsp/manager.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'lua/lsp') diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua index 5b6d9767..a2f23a7b 100644 --- a/lua/lsp/manager.lua +++ b/lua/lsp/manager.lua @@ -9,6 +9,7 @@ function M.init_defaults(languages) lvim.lang[entry] = { formatters = {}, linters = {}, + lsp = {}, } end end -- cgit v1.2.3 From 2104e3864550e28513cbad5cb2f48233c2c4e79e Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Mon, 4 Oct 2021 08:12:25 +0200 Subject: fix: restore the ability to override formatting (#1677) --- lua/lsp/init.lua | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 7f20a39d..fae7ca8d 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -62,18 +62,37 @@ function M.common_capabilities() return capabilities end +local function select_default_formater(client) + local client_formatting = client.resolved_capabilities.document_formatting + or client.resolved_capabilities.document_range_formatting + if client.name == "null-ls" or not client_formatting then + return + end + Log:debug("Checking for formatter overriding for " .. client.name) + local client_filetypes = client.config.filetypes or {} + for _, filetype in ipairs(client_filetypes) do + if not vim.tbl_isempty(lvim.lang[filetype].formatters) then + Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name) + client.resolved_capabilities.document_formatting = false + client.resolved_capabilities.document_range_formatting = false + return + end + end +end + function M.common_on_init(client, bufnr) if lvim.lsp.on_init_callback then lvim.lsp.on_init_callback(client, bufnr) Log:debug "Called lsp.on_init_callback" return end + select_default_formater(client) end function M.common_on_attach(client, bufnr) if lvim.lsp.on_attach_callback then lvim.lsp.on_attach_callback(client, bufnr) - Log:debug "Called lsp.on_init_callback" + Log:debug "Called lsp.on_attach_callback" end lsp_highlight_document(client) add_lsp_buffer_keybindings(bufnr) -- cgit v1.2.3 From 48472a1bf04aede946893146462e0d3a8ce51360 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 4 Oct 2021 14:04:57 +0330 Subject: feat: better default json schemas (#1678) --- lua/lsp/providers/jsonls.lua | 193 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 184 insertions(+), 9 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua index 55bc1ea2..4fa92af4 100644 --- a/lua/lsp/providers/jsonls.lua +++ b/lua/lsp/providers/jsonls.lua @@ -1,20 +1,195 @@ -local schemas = nil +local default_schemas = nil local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls") if status_ok then - schemas = jsonls_settings.get_default_schemas() + default_schemas = jsonls_settings.get_default_schemas() end +local schemas = { + { + description = "TypeScript compiler configuration file", + fileMatch = { + "tsconfig.json", + "tsconfig.*.json", + }, + url = "https://json.schemastore.org/tsconfig.json", + }, + { + description = "Lerna config", + fileMatch = { "lerna.json" }, + url = "https://json.schemastore.org/lerna.json", + }, + { + description = "Babel configuration", + fileMatch = { + ".babelrc.json", + ".babelrc", + "babel.config.json", + }, + url = "https://json.schemastore.org/babelrc.json", + }, + { + description = "ESLint config", + fileMatch = { + ".eslintrc.json", + ".eslintrc", + }, + url = "https://json.schemastore.org/eslintrc.json", + }, + { + description = "Bucklescript config", + fileMatch = { "bsconfig.json" }, + url = "https://raw.githubusercontent.com/rescript-lang/rescript-compiler/8.2.0/docs/docson/build-schema.json", + }, + { + description = "Prettier config", + fileMatch = { + ".prettierrc", + ".prettierrc.json", + "prettier.config.json", + }, + url = "https://json.schemastore.org/prettierrc", + }, + { + description = "Vercel Now config", + fileMatch = { "now.json" }, + url = "https://json.schemastore.org/now", + }, + { + description = "Stylelint config", + fileMatch = { + ".stylelintrc", + ".stylelintrc.json", + "stylelint.config.json", + }, + url = "https://json.schemastore.org/stylelintrc", + }, + { + description = "A JSON schema for the ASP.NET LaunchSettings.json files", + fileMatch = { "launchsettings.json" }, + url = "https://json.schemastore.org/launchsettings.json", + }, + { + description = "Schema for CMake Presets", + fileMatch = { + "CMakePresets.json", + "CMakeUserPresets.json", + }, + url = "https://raw.githubusercontent.com/Kitware/CMake/master/Help/manual/presets/schema.json", + }, + { + description = "Configuration file as an alternative for configuring your repository in the settings page.", + fileMatch = { + ".codeclimate.json", + }, + url = "https://json.schemastore.org/codeclimate.json", + }, + { + description = "LLVM compilation database", + fileMatch = { + "compile_commands.json", + }, + url = "https://json.schemastore.org/compile-commands.json", + }, + { + description = "Config file for Command Task Runner", + fileMatch = { + "commands.json", + }, + url = "https://json.schemastore.org/commands.json", + }, + { + description = "AWS CloudFormation provides a common language for you to describe and provision all the infrastructure resources in your cloud environment.", + fileMatch = { + "*.cf.json", + "cloudformation.json", + }, + url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/cloudformation.schema.json", + }, + { + description = "The AWS Serverless Application Model (AWS SAM, previously known as Project Flourish) extends AWS CloudFormation to provide a simplified way of defining the Amazon API Gateway APIs, AWS Lambda functions, and Amazon DynamoDB tables needed by your serverless application.", + fileMatch = { + "serverless.template", + "*.sam.json", + "sam.json", + }, + url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/sam.schema.json", + }, + { + description = "Json schema for properties json file for a GitHub Workflow template", + fileMatch = { + ".github/workflow-templates/**.properties.json", + }, + url = "https://json.schemastore.org/github-workflow-template-properties.json", + }, + { + description = "golangci-lint configuration file", + fileMatch = { + ".golangci.toml", + ".golangci.json", + }, + url = "https://json.schemastore.org/golangci-lint.json", + }, + { + description = "JSON Schema for Grafana 5.x Dashboards", + url = "https://json.schemastore.org/grafana-dashboard-5.x.json", + }, + { + description = "JSON schema for the JSON Feed format", + fileMatch = { + "feed.json", + }, + url = "https://json.schemastore.org/feed.json", + versions = { + ["1"] = "https://json.schemastore.org/feed-1.json", + ["1.1"] = "https://json.schemastore.org/feed.json", + }, + }, + { + description = "Packer template JSON configuration", + fileMatch = { + "packer.json", + }, + url = "https://json.schemastore.org/packer.json", + }, + { + description = "NPM configuration file", + fileMatch = { + "package.json", + }, + url = "https://json.schemastore.org/package.json", + }, + { + description = "Traefik v2 Dynamic Configuration File Provider", + url = "https://json.schemastore.org/traefik-v2-file-provider.json", + }, + { + description = "JSON schema for Visual Studio component configuration files", + fileMatch = { + "*.vsconfig", + }, + url = "https://json.schemastore.org/vsconfig.json", + }, + { + description = "Resume json", + fileMatch = { "resume.json" }, + url = "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json", + }, +} + +local function extend(tab1, tab2) + for _, value in ipairs(tab2) do + table.insert(tab1, value) + end + return tab1 +end + +local extended_schemas = extend(schemas, default_schemas) + local opts = { setup = { settings = { json = { - schemas = schemas, - -- = { - -- { - -- fileMatch = { "package.json" }, - -- url = "https://json.schemastore.org/package.json", - -- }, - -- }, + schemas = extended_schemas, }, }, commands = { -- cgit v1.2.3 From b1ae1e9bfb96fb8dc4b66a7fad17307236a2502e Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 4 Oct 2021 14:10:42 +0330 Subject: feat: better kubernetes support (#1679) --- lua/lsp/providers/yamlls.lua | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lua/lsp/providers/yamlls.lua (limited to 'lua/lsp') diff --git a/lua/lsp/providers/yamlls.lua b/lua/lsp/providers/yamlls.lua new file mode 100644 index 00000000..156a35b0 --- /dev/null +++ b/lua/lsp/providers/yamlls.lua @@ -0,0 +1,30 @@ +local opts = { + settings = { + yaml = { + hover = true, + completion = true, + validate = true, + schemaStore = { + enable = true, + url = "https://www.schemastore.org/api/json/catalog.json", + }, + schemas = { + kubernetes = { + "daemon.{yml,yaml}", + "manager.{yml,yaml}", + "restapi.{yml,yaml}", + "role.{yml,yaml}", + "role_binding.{yml,yaml}", + "*onfigma*.{yml,yaml}", + "*ngres*.{yml,yaml}", + "*ecre*.{yml,yaml}", + "*eployment*.{yml,yaml}", + "*ervic*.{yml,yaml}", + "kubectl-edit*.yaml", + }, + }, + }, + }, +} + +return opts -- cgit v1.2.3 From 6443f156d762cd64ac857c34f10843404f0dffde Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 4 Oct 2021 14:17:27 +0330 Subject: fix: the virtual_text charachter causes issues (#1681) --- lua/lsp/config.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua index 146301c9..f9184e6f 100644 --- a/lua/lsp/config.lua +++ b/lua/lsp/config.lua @@ -10,10 +10,7 @@ return { { name = "LspDiagnosticsSignInformation", text = "" }, }, }, - virtual_text = { - prefix = "", - spacing = 0, - }, + virtual_text = true, update_in_insert = false, underline = true, severity_sort = true, -- cgit v1.2.3 From 8fb404f7d6f449ff4a0e3d361de0e4e85e81ab4e Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Mon, 4 Oct 2021 15:48:35 +0330 Subject: fix: bring back NlspConfig completion (#1682) --- lua/lsp/providers/jsonls.lua | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua index 4fa92af4..72c67b47 100644 --- a/lua/lsp/providers/jsonls.lua +++ b/lua/lsp/providers/jsonls.lua @@ -129,10 +129,6 @@ local schemas = { }, url = "https://json.schemastore.org/golangci-lint.json", }, - { - description = "JSON Schema for Grafana 5.x Dashboards", - url = "https://json.schemastore.org/grafana-dashboard-5.x.json", - }, { description = "JSON schema for the JSON Feed format", fileMatch = { @@ -158,10 +154,6 @@ local schemas = { }, url = "https://json.schemastore.org/package.json", }, - { - description = "Traefik v2 Dynamic Configuration File Provider", - url = "https://json.schemastore.org/traefik-v2-file-provider.json", - }, { description = "JSON schema for Visual Studio component configuration files", fileMatch = { @@ -186,18 +178,16 @@ end local extended_schemas = extend(schemas, default_schemas) local opts = { - setup = { - settings = { - json = { - schemas = extended_schemas, - }, - }, - commands = { - Format = { - function() - vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) - end, - }, + settings = { + json = { + schemas = extended_schemas, + }, + }, + commands = { + Format = { + function() + vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) + end, }, }, } -- cgit v1.2.3 From 76bee64f17cb7e7db33ee61645088d2b0729eb09 Mon Sep 17 00:00:00 2001 From: dklymenk <64093836+dklymenk@users.noreply.github.com> Date: Tue, 5 Oct 2021 00:09:40 +0300 Subject: fix: return null ls setup user config (#1683) --- lua/lsp/config.lua | 3 +++ lua/lsp/null-ls/init.lua | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lua/lsp') diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua index f9184e6f..521ab50a 100644 --- a/lua/lsp/config.lua +++ b/lua/lsp/config.lua @@ -21,4 +21,7 @@ return { on_attach_callback = nil, on_init_callback = nil, automatic_servers_installation = true, + null_ls = { + setup = {}, + }, } diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua index 0540fb48..1d0af77b 100644 --- a/lua/lsp/null-ls/init.lua +++ b/lua/lsp/null-ls/init.lua @@ -12,7 +12,7 @@ function M:setup() end null_ls.config() - require("lspconfig")["null-ls"].setup {} + require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) for _, filetype in pairs(lvim.lang) do if filetype.formatters then formatters.setup(filetype.formatters, filetype) -- cgit v1.2.3 From 5fe7b7ad4d6fa699ca9cc306a788d6485fc0ba8d Mon Sep 17 00:00:00 2001 From: Subho Banerjee Date: Tue, 5 Oct 2021 14:29:58 -0500 Subject: feat(lsp): make lsp buffer-mappings configurable (#1687) --- lua/lsp/config.lua | 17 +++++++++++++++++ lua/lsp/init.lua | 40 ++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 18 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua index 521ab50a..32185b56 100644 --- a/lua/lsp/config.lua +++ b/lua/lsp/config.lua @@ -21,6 +21,23 @@ return { on_attach_callback = nil, on_init_callback = nil, automatic_servers_installation = true, + buffer_mappings = { + normal_mode = { + ["K"] = { "lua vim.lsp.buf.hover()", "Show hover" }, + ["gd"] = { "lua vim.lsp.buf.definition()", "Goto Definition" }, + ["gD"] = { "lua vim.lsp.buf.declaration()", "Goto declaration" }, + ["gr"] = { "lua vim.lsp.buf.references()", "Goto references" }, + ["gI"] = { "lua vim.lsp.buf.implementation()", "Goto Implementation" }, + ["gs"] = { "lua vim.lsp.buf.signature_help()", "show signature help" }, + ["gp"] = { "lua require'lsp.peek'.Peek('definition')", "Peek definition" }, + ["gl"] = { + "lua require'lsp.handlers'.show_line_diagnostics()", + "Show line diagnostics", + }, + }, + insert_mode = {}, + visual_mode = {}, + }, null_ls = { setup = {}, }, diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index fae7ca8d..284b9dfe 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -22,25 +22,29 @@ local function lsp_highlight_document(client) end local function add_lsp_buffer_keybindings(bufnr) - local status_ok, wk = pcall(require, "which-key") - if not status_ok then - return - end - - local keys = { - ["K"] = { "lua vim.lsp.buf.hover()", "Show hover" }, - ["gd"] = { "lua vim.lsp.buf.definition()", "Goto Definition" }, - ["gD"] = { "lua vim.lsp.buf.declaration()", "Goto declaration" }, - ["gr"] = { "lua vim.lsp.buf.references()", "Goto references" }, - ["gI"] = { "lua vim.lsp.buf.implementation()", "Goto Implementation" }, - ["gs"] = { "lua vim.lsp.buf.signature_help()", "show signature help" }, - ["gp"] = { "lua require'lsp.peek'.Peek('definition')", "Peek definition" }, - ["gl"] = { - "lua require'lsp.handlers'.show_line_diagnostics()", - "Show line diagnostics", - }, + local mappings = { + normal_mode = "n", + insert_mode = "i", + visual_mode = "v", } - wk.register(keys, { mode = "n", buffer = bufnr }) + + if lvim.builtin.which_key.active then + -- Remap using which_key + local status_ok, wk = pcall(require, "which-key") + if not status_ok then + return + end + for mode_name, mode_char in pairs(mappings) do + wk.register(lvim.lsp.buffer_mappings[mode_name], { mode = mode_char, buffer = bufnr }) + end + else + -- Remap using nvim api + for mode_name, mode_char in pairs(mappings) do + for key, remap in pairs(lvim.lsp.buffer_mappings[mode_name]) do + vim.api.nvim_buf_set_keymap(bufnr, mode_char, key, remap[1], { noremap = true, silent = true }) + end + end + end end function M.common_capabilities() -- cgit v1.2.3 From 0ad60e90a9b0dd557df10f73bec344e88549a9d7 Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Wed, 6 Oct 2021 02:07:23 +0330 Subject: [Feature] better code action prompt and auto show codelens actions (#1698) --- lua/lsp/config.lua | 1 + lua/lsp/init.lua | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'lua/lsp') diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua index 32185b56..f13d9659 100644 --- a/lua/lsp/config.lua +++ b/lua/lsp/config.lua @@ -17,6 +17,7 @@ return { }, override = {}, document_highlight = true, + code_lens_refresh = true, popup_border = "single", on_attach_callback = nil, on_init_callback = nil, diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 284b9dfe..2631c0fc 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -21,6 +21,25 @@ local function lsp_highlight_document(client) end end +local function lsp_code_lens_refresh(client) + if lvim.lsp.code_lens_refresh == false then + return + end + + if client.resolved_capabilities.code_lens then + vim.api.nvim_exec( + [[ + augroup lsp_code_lens_refresh + autocmd! * + autocmd InsertLeave lua vim.lsp.codelens.refresh() + autocmd InsertLeave lua vim.lsp.codelens.display() + augroup END + ]], + false + ) + end +end + local function add_lsp_buffer_keybindings(bufnr) local mappings = { normal_mode = "n", @@ -99,6 +118,7 @@ function M.common_on_attach(client, bufnr) Log:debug "Called lsp.on_attach_callback" end lsp_highlight_document(client) + lsp_code_lens_refresh(client) add_lsp_buffer_keybindings(bufnr) end -- cgit v1.2.3 From c0e3c8d43ae6ca011e4036329ae31115957d1394 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Thu, 7 Oct 2021 17:47:53 +0200 Subject: feat(lsp): handle user configuration in setup() (#1707) --- lua/lsp/init.lua | 1 + lua/lsp/manager.lua | 81 ++++++++++++++++++++++++++------------------------- lua/lsp/templates.lua | 2 +- 3 files changed, 44 insertions(+), 40 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 2631c0fc..18b27513 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -149,6 +149,7 @@ function M.setup() for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) end + require("lsp.handlers").setup() if not utils.is_directory(lvim.lsp.templates_dir) then diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua index a2f23a7b..9cb81910 100644 --- a/lua/lsp/manager.lua +++ b/lua/lsp/manager.lua @@ -24,59 +24,62 @@ local function is_overridden(server) end end -function M.setup_server(server_name) - vim.validate { - name = { server_name, "string" }, - } - - if lsp_utils.is_client_active(server_name) or is_overridden(server_name) then - return - end - - local lsp_installer_servers = require "nvim-lsp-installer.servers" - local server_available, requested_server = lsp_installer_servers.get_server(server_name) - if server_available then - if not requested_server:is_installed() then - Log:debug(string.format("[%s] is not installed", server_name)) - if lvim.lsp.automatic_servers_installation then - Log:debug(string.format("Installing [%s]", server_name)) - requested_server:install() - else - return - end - end - end - - local default_config = { +---Resolve the configuration for a server based on both common and user configuration +---@param name string +---@param user_config table [optional] +---@return table +local function resolve_config(name, user_config) + local config = { on_attach = require("lsp").common_on_attach, on_init = require("lsp").common_on_init, capabilities = require("lsp").common_capabilities(), } - local status_ok, custom_config = pcall(require, "lsp/providers/" .. requested_server.name) + local status_ok, custom_config = pcall(require, "lsp/providers/" .. name) if status_ok then - local new_config = vim.tbl_deep_extend("force", default_config, custom_config) - Log:debug("Using custom configuration for requested server: " .. requested_server.name) - requested_server:setup(new_config) - else - Log:debug("Using the default configuration for requested server: " .. requested_server.name) - requested_server:setup(default_config) + Log:debug("Using custom configuration for requested server: " .. name) + config = vim.tbl_deep_extend("force", config, custom_config) end + + if user_config then + config = vim.tbl_deep_extend("force", config, user_config) + end + + return config end -function M.setup(servers) - local status_ok, _ = pcall(require, "nvim-lsp-installer") - if not status_ok then +---Setup a language server by providing a name +---@param server_name string name of the language server +---@param user_config table [optional] when available it will take predence over any default configurations +function M.setup(server_name, user_config) + vim.validate { name = { server_name, "string" } } + + if lsp_utils.is_client_active(server_name) or is_overridden(server_name) then return end - --- allow using a single value - if type(servers) == "string" then - servers = { servers } + local config = resolve_config(server_name, user_config) + local server_available, requested_server = require("nvim-lsp-installer.servers").get_server(server_name) + + local function ensure_installed(server) + if server:is_installed() then + return true + end + if not lvim.lsp.automatic_servers_installation then + Log:debug(server.name .. " is not managed by the automatic installer") + return false + end + Log:debug(string.format("Installing [%s]", server.name)) + server:install() + vim.schedule(function() + vim.cmd [[LspStart]] + end) end - for _, server in ipairs(servers) do - M.setup_server(server) + if server_available and ensure_installed(requested_server) then + requested_server:setup(config) + else + require("lspconfig")[server_name].setup(config) end end diff --git a/lua/lsp/templates.lua b/lua/lsp/templates.lua index 6ded636d..fbbc37f6 100644 --- a/lua/lsp/templates.lua +++ b/lua/lsp/templates.lua @@ -23,7 +23,7 @@ function M.is_ignored(server_name, filetypes) filetypes = filetypes or get_supported_filetypes(server_name) if vim.tbl_contains(filetypes, "javascript") then - if server_name == "tsserver" or server_name == "tailwindcss" then + if server_name == "tsserver" then return false else return true -- cgit v1.2.3 From f4899e316516fc6fc544b148cb7e9a04fbda130e Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Fri, 8 Oct 2021 08:57:11 +0200 Subject: fix: register null-ls providers per filetype (#1709) --- lua/lsp/null-ls/formatters.lua | 13 ++++++++----- lua/lsp/null-ls/init.lua | 10 +++++----- lua/lsp/null-ls/linters.lua | 13 ++++++++----- 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index 8199aca0..636b0bde 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -23,7 +23,7 @@ function M.list_available(filetype) return formatters end -function M.list_configured(formatter_configs) +function M.list_configured(formatter_configs, filetype) local formatters, errors = {}, {} for _, fmt_config in ipairs(formatter_configs) do @@ -39,7 +39,11 @@ function M.list_configured(formatter_configs) errors[fmt_config.exe] = {} -- Add data here when necessary else Log:debug("Using formatter: " .. formatter_cmd) - formatters[fmt_config.exe] = formatter.with { command = formatter_cmd, extra_args = fmt_config.args } + formatters[fmt_config.exe] = formatter.with { + command = formatter_cmd, + extra_args = fmt_config.args, + filetypes = { filetype }, + } end end end @@ -52,9 +56,8 @@ function M.setup(formatter_configs, filetype) return end - local formatters_by_ft = {} - formatters_by_ft[filetype] = M.list_configured(formatter_configs) - null_ls.register { sources = formatters_by_ft[filetype].supported } + local formatters_by_ft = M.list_configured(formatter_configs, filetype) + null_ls.register { sources = formatters_by_ft.supported } end return M diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua index 1d0af77b..3c8909af 100644 --- a/lua/lsp/null-ls/init.lua +++ b/lua/lsp/null-ls/init.lua @@ -13,12 +13,12 @@ function M:setup() null_ls.config() require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) - for _, filetype in pairs(lvim.lang) do - if filetype.formatters then - formatters.setup(filetype.formatters, filetype) + for filetype, config in pairs(lvim.lang) do + if not vim.tbl_isempty(config.formatters) then + formatters.setup(config.formatters, filetype) end - if filetype.linters then - linters.setup(filetype.linters, filetype) + if not vim.tbl_isempty(config.linters) then + linters.setup(config.linters, filetype) end end end diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index ea45fa87..34a78a65 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -23,7 +23,7 @@ function M.list_available(filetype) return linters end -function M.list_configured(linter_configs) +function M.list_configured(linter_configs, filetype) local linters, errors = {}, {} for _, lnt_config in pairs(linter_configs) do @@ -39,7 +39,11 @@ function M.list_configured(linter_configs) errors[lnt_config.exe] = {} -- Add data here when necessary else Log:debug("Using linter: " .. linter_cmd) - linters[lnt_config.exe] = linter.with { command = linter_cmd, extra_args = lnt_config.args } + linters[lnt_config.exe] = linter.with { + command = linter_cmd, + extra_args = lnt_config.args, + filetypes = { filetype }, + } end end end @@ -52,9 +56,8 @@ function M.setup(linter_configs, filetype) return end - local linters_by_ft = {} - linters_by_ft[filetype] = M.list_configured(linter_configs) - null_ls.register { sources = linters_by_ft[filetype].supported } + local linters_by_ft = M.list_configured(linter_configs, filetype) + null_ls.register { sources = linters_by_ft.supported } end return M -- cgit v1.2.3 From 5fef931d8720f2ef0d7a0fca18b96f31fd36689a Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Sat, 9 Oct 2021 09:33:23 +0330 Subject: fix: move jsonls commands under setup (#1685) --- lua/lsp/providers/jsonls.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua index 72c67b47..1fffa686 100644 --- a/lua/lsp/providers/jsonls.lua +++ b/lua/lsp/providers/jsonls.lua @@ -183,11 +183,13 @@ local opts = { schemas = extended_schemas, }, }, - commands = { - Format = { - function() - vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) - end, + setup = { + commands = { + Format = { + function() + vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) + end, + }, }, }, } -- cgit v1.2.3 From 195b07a464d37328892a502cf7ce3690b6a5b2e4 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Sat, 9 Oct 2021 13:38:35 +0200 Subject: fix(lsp): use correct check for formatter override (#1726) --- lua/lsp/init.lua | 3 +-- lua/lsp/utils.lua | 6 ------ 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 18b27513..88111005 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -94,11 +94,10 @@ local function select_default_formater(client) Log:debug("Checking for formatter overriding for " .. client.name) local client_filetypes = client.config.filetypes or {} for _, filetype in ipairs(client_filetypes) do - if not vim.tbl_isempty(lvim.lang[filetype].formatters) then + if lvim.lang[filetype] and #vim.tbl_keys(lvim.lang[filetype].formatters) > 0 then Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name) client.resolved_capabilities.document_formatting = false client.resolved_capabilities.document_range_formatting = false - return end end end diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua index 1a5dd79d..87ba2337 100644 --- a/lua/lsp/utils.lua +++ b/lua/lsp/utils.lua @@ -10,12 +10,6 @@ function M.is_client_active(name) return false end -function M.disable_formatting_capability(client) - -- FIXME: figure out a reasonable way to do this - client.resolved_capabilities.document_formatting = false - require("core.log"):debug(string.format("Turning off formatting capability for language server [%s] ", client.name)) -end - function M.get_active_client_by_ft(filetype) local matches = {} local clients = vim.lsp.get_active_clients() -- cgit v1.2.3 From efd82c87568a791b2f7fb9c94b763f2c1950dc8e Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Sat, 9 Oct 2021 13:39:15 +0200 Subject: feat: configure multiple filetypes per provider (#1725) --- lua/lsp/null-ls/formatters.lua | 8 ++++---- lua/lsp/null-ls/init.lua | 10 ++++++++-- lua/lsp/null-ls/linters.lua | 10 +++++----- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index 636b0bde..d6455d5f 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -23,7 +23,7 @@ function M.list_available(filetype) return formatters end -function M.list_configured(formatter_configs, filetype) +function M.list_configured(formatter_configs) local formatters, errors = {}, {} for _, fmt_config in ipairs(formatter_configs) do @@ -42,7 +42,7 @@ function M.list_configured(formatter_configs, filetype) formatters[fmt_config.exe] = formatter.with { command = formatter_cmd, extra_args = fmt_config.args, - filetypes = { filetype }, + filetypes = fmt_config.filetypes, } end end @@ -51,12 +51,12 @@ function M.list_configured(formatter_configs, filetype) return { supported = formatters, unsupported = errors } end -function M.setup(formatter_configs, filetype) +function M.setup(formatter_configs) if vim.tbl_isempty(formatter_configs) then return end - local formatters_by_ft = M.list_configured(formatter_configs, filetype) + local formatters_by_ft = M.list_configured(formatter_configs) null_ls.register { sources = formatters_by_ft.supported } end diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua index 3c8909af..0d030c22 100644 --- a/lua/lsp/null-ls/init.lua +++ b/lua/lsp/null-ls/init.lua @@ -15,10 +15,16 @@ function M:setup() require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) for filetype, config in pairs(lvim.lang) do if not vim.tbl_isempty(config.formatters) then - formatters.setup(config.formatters, filetype) + vim.tbl_map(function(c) + c.filetypes = { filetype } + end, config.formatters) + formatters.setup(config.formatters) end if not vim.tbl_isempty(config.linters) then - linters.setup(config.linters, filetype) + vim.tbl_map(function(c) + c.filetypes = { filetype } + end, config.formatters) + linters.setup(config.linters) end end end diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index 34a78a65..e60411e6 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -23,7 +23,7 @@ function M.list_available(filetype) return linters end -function M.list_configured(linter_configs, filetype) +function M.list_configured(linter_configs) local linters, errors = {}, {} for _, lnt_config in pairs(linter_configs) do @@ -42,7 +42,7 @@ function M.list_configured(linter_configs, filetype) linters[lnt_config.exe] = linter.with { command = linter_cmd, extra_args = lnt_config.args, - filetypes = { filetype }, + filetypes = lnt_config.filetypes, } end end @@ -51,13 +51,13 @@ function M.list_configured(linter_configs, filetype) return { supported = linters, unsupported = errors } end -function M.setup(linter_configs, filetype) +function M.setup(linter_configs) if vim.tbl_isempty(linter_configs) then return end - local linters_by_ft = M.list_configured(linter_configs, filetype) - null_ls.register { sources = linters_by_ft.supported } + local linters = M.list_configured(linter_configs) + null_ls.register { sources = linters.supported } end return M -- cgit v1.2.3 From b524100f016de6b934894547d48f9ef811902397 Mon Sep 17 00:00:00 2001 From: Luc Sinet Date: Sat, 9 Oct 2021 13:45:34 +0200 Subject: feat: support wildcard filetypes for null-ls providers (#1447) Co-authored-by: kylo252 <59826753+kylo252@users.noreply.github.com> --- lua/lsp/null-ls/formatters.lua | 9 ++++++--- lua/lsp/null-ls/linters.lua | 9 ++++++--- lua/lsp/null-ls/services.lua | 4 ++-- lua/lsp/utils.lua | 15 +++++++-------- 4 files changed, 21 insertions(+), 16 deletions(-) (limited to 'lua/lsp') diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index d6455d5f..4728b908 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -13,9 +13,11 @@ end function M.list_available(filetype) local formatters = {} + local tbl = require "utils.table" for _, provider in pairs(null_ls.builtins.formatting) do - -- TODO: Add support for wildcard filetypes - if vim.tbl_contains(provider.filetypes or {}, filetype) then + if tbl.contains(provider.filetypes or {}, function(ft) + return ft == "*" or ft == filetype + end) then table.insert(formatters, provider.name) end end @@ -27,7 +29,8 @@ function M.list_configured(formatter_configs) local formatters, errors = {}, {} for _, fmt_config in ipairs(formatter_configs) do - local formatter = null_ls.builtins.formatting[fmt_config.exe] + local formatter_name = fmt_config.exe:gsub("-", "_") + local formatter = null_ls.builtins.formatting[formatter_name] if not formatter then Log:error("Not a valid formatter: " .. fmt_config.exe) diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index e60411e6..549c6cdd 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -13,9 +13,11 @@ end function M.list_available(filetype) local linters = {} + local tbl = require "utils.table" for _, provider in pairs(null_ls.builtins.diagnostics) do - -- TODO: Add support for wildcard filetypes - if vim.tbl_contains(provider.filetypes or {}, filetype) then + if tbl.contains(provider.filetypes or {}, function(ft) + return ft == "*" or ft == filetype + end) then table.insert(linters, provider.name) end end @@ -27,7 +29,8 @@ function M.list_configured(linter_configs) local linters, errors = {}, {} for _, lnt_config in pairs(linter_configs) do - local linter = null_ls.builtins.diagnostics[lnt_config.exe] + local linter_name = lnt_config.exe:gsub("-", "_") + local linter = null_ls.builtins.diagnostics[linter_name] if not linter then Log:error("Not a valid linter: " .. lnt_config.exe) diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua index c62fc709..ef9e7d22 100644 --- a/lua/lsp/null-ls/services.lua +++ b/lua/lsp/null-ls/services.lua @@ -4,8 +4,8 @@ local function find_root_dir() local util = require "lspconfig/util" local lsp_utils = require "lsp.utils" - local status_ok, ts_client = lsp_utils.is_client_active "typescript" - if status_ok then + local ts_client = lsp_utils.is_client_active "typescript" + if ts_client then return ts_client.config.root_dir end local dirname = vim.fn.expand "%:p:h" diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua index 87ba2337..59003406 100644 --- a/lua/lsp/utils.lua +++ b/lua/lsp/utils.lua @@ -1,16 +1,15 @@ local M = {} +local tbl = require "utils.table" + function M.is_client_active(name) local clients = vim.lsp.get_active_clients() - for _, client in pairs(clients) do - if client.name == name then - return true, client - end - end - return false + return tbl.find_first(clients, function(client) + return client.name == name + end) end -function M.get_active_client_by_ft(filetype) +function M.get_active_clients_by_ft(filetype) local matches = {} local clients = vim.lsp.get_active_clients() for _, client in pairs(clients) do @@ -22,7 +21,7 @@ function M.get_active_client_by_ft(filetype) return matches end -function M.get_ls_capabilities(client_id) +function M.get_client_capabilities(client_id) if not client_id then local buf_clients = vim.lsp.buf_get_clients() for _, buf_client in ipairs(buf_clients) do -- cgit v1.2.3