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 | 
