2023-09-06 00:26:45 +02:00
|
|
|
-- LSP: Key-maps
|
2023-09-06 01:26:46 +02:00
|
|
|
-- https://github.com/rafi/vim-config
|
2023-09-06 00:26:45 +02:00
|
|
|
|
|
|
|
local M = {}
|
|
|
|
|
|
|
|
---@type PluginLspKeys
|
|
|
|
M._keys = nil
|
|
|
|
|
|
|
|
---@return (LazyKeys|{has?:string})[]
|
|
|
|
function M.get()
|
|
|
|
if M._keys then
|
|
|
|
return M._keys
|
|
|
|
end
|
|
|
|
local format = function()
|
2023-09-06 10:19:56 +02:00
|
|
|
require('plex.plugins.lsp.format').format({ force = true })
|
2023-09-06 00:26:45 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
---@class PluginLspKeys
|
|
|
|
-- stylua: ignore
|
|
|
|
M._keys = {
|
|
|
|
{ 'gD', vim.lsp.buf.declaration, desc = 'Goto Declaration', has = 'declaration' },
|
|
|
|
{ 'gd', vim.lsp.buf.definition, desc = 'Goto Definition', has = 'definition' },
|
|
|
|
{ 'gr', vim.lsp.buf.references, desc = 'References', has = 'references' },
|
|
|
|
{ 'gy', vim.lsp.buf.type_definition, desc = 'Goto Type Definition', has = 'typeDefinition' },
|
|
|
|
{ 'gi', vim.lsp.buf.implementation, desc = 'Goto Implementation', has = 'implementation' },
|
|
|
|
{ 'gK', vim.lsp.buf.signature_help, desc = 'Signature Help', has = 'signatureHelp' },
|
|
|
|
{ '<C-g>h', vim.lsp.buf.signature_help, mode = 'i', desc = 'Signature Help', has = 'signatureHelp' },
|
|
|
|
{ ']d', M.diagnostic_goto(true), desc = 'Next Diagnostic' },
|
|
|
|
{ '[d', M.diagnostic_goto(false), desc = 'Prev Diagnostic' },
|
|
|
|
{ ']e', M.diagnostic_goto(true, 'ERROR'), desc = 'Next Error' },
|
|
|
|
{ '[e', M.diagnostic_goto(false, 'ERROR'), desc = 'Prev Error' },
|
|
|
|
|
|
|
|
{ ',wa', vim.lsp.buf.add_workspace_folder, desc = 'Show Workspace Folders' },
|
|
|
|
{ ',wr', vim.lsp.buf.remove_workspace_folder, desc = 'Remove Workspace Folder' },
|
|
|
|
{ ',wl', '<cmd>lua =vim.lsp.buf.list_workspace_folders()<CR>', desc = 'List Workspace Folders' },
|
|
|
|
|
2023-09-06 18:36:38 +02:00
|
|
|
{ '<localleader>K', function()
|
2023-09-06 00:26:45 +02:00
|
|
|
-- Show hover documentation or folded lines.
|
2023-09-06 10:19:56 +02:00
|
|
|
local winid = require('plex.lib.utils').has('nvim-ufo')
|
2023-09-06 00:26:45 +02:00
|
|
|
and require('ufo').peekFoldedLinesUnderCursor() or nil
|
|
|
|
if not winid then
|
|
|
|
vim.lsp.buf.hover()
|
|
|
|
end
|
|
|
|
end },
|
|
|
|
|
|
|
|
{ '<Leader>ud', function() M.diagnostic_toggle(false) end, desc = 'Disable Diagnostics' },
|
|
|
|
{ '<Leader>uD', function() M.diagnostic_toggle(true) end, desc = 'Disable All Diagnostics' },
|
|
|
|
|
|
|
|
{ '<leader>cl', '<cmd>LspInfo<cr>' },
|
|
|
|
{ '<leader>cf', format, desc = 'Format Document', has = 'formatting' },
|
|
|
|
{ '<leader>cf', format, mode = 'x', desc = 'Format Range' }, -- , has = 'rangeFormatting'
|
|
|
|
{ '<Leader>cr', vim.lsp.buf.rename, desc = 'Rename', has = 'rename' },
|
|
|
|
{ '<Leader>ce', vim.diagnostic.open_float, desc = 'Open diagnostics' },
|
|
|
|
{ '<Leader>ca', vim.lsp.buf.code_action, mode = { 'n', 'x' }, has = 'codeAction', desc = 'Code Action' },
|
|
|
|
{ '<Leader>cA', function()
|
|
|
|
vim.lsp.buf.code_action({
|
|
|
|
context = {
|
|
|
|
only = { 'source' },
|
|
|
|
diagnostics = {},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
end, desc = 'Source Action', has = 'codeAction' },
|
|
|
|
}
|
|
|
|
return M._keys
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param method string
|
|
|
|
function M.has(buffer, method)
|
|
|
|
method = method:find('/') and method or 'textDocument/' .. method
|
|
|
|
local clients
|
|
|
|
if vim.lsp.get_clients ~= nil then
|
|
|
|
clients = vim.lsp.get_clients({ bufnr = buffer })
|
|
|
|
else
|
|
|
|
---@diagnostic disable-next-line: deprecated
|
|
|
|
clients = vim.lsp.get_active_clients({ bufnr = buffer })
|
|
|
|
end
|
|
|
|
for _, client in ipairs(clients) do
|
|
|
|
if client.supports_method(method) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param buffer integer
|
|
|
|
function M.resolve(buffer)
|
|
|
|
local Keys = require('lazy.core.handler.keys')
|
|
|
|
local keymaps = {} ---@type table<string,LazyKeys|{has?:string}>
|
|
|
|
|
|
|
|
local function add(keymap)
|
|
|
|
local keys = Keys.parse(keymap)
|
|
|
|
if keys[2] == false then
|
|
|
|
keymaps[keys.id] = nil
|
|
|
|
else
|
|
|
|
keymaps[keys.id] = keys
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for _, keymap in ipairs(M.get()) do
|
|
|
|
add(keymap)
|
|
|
|
end
|
|
|
|
|
2023-09-06 10:19:56 +02:00
|
|
|
local opts = require('plex.lib.utils').opts('nvim-lspconfig')
|
2023-09-06 00:26:45 +02:00
|
|
|
local clients
|
|
|
|
if vim.lsp.get_clients ~= nil then
|
|
|
|
clients = vim.lsp.get_clients({ bufnr = buffer })
|
|
|
|
else
|
|
|
|
---@diagnostic disable-next-line: deprecated
|
|
|
|
clients = vim.lsp.get_active_clients({ bufnr = buffer })
|
|
|
|
end
|
|
|
|
for _, client in ipairs(clients) do
|
|
|
|
local maps = opts.servers[client.name] and opts.servers[client.name].keys
|
|
|
|
or {}
|
|
|
|
for _, keymap in ipairs(maps) do
|
|
|
|
add(keymap)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return keymaps
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param client lsp.Client
|
|
|
|
---@param buffer integer
|
|
|
|
function M.on_attach(client, buffer)
|
|
|
|
local Keys = require('lazy.core.handler.keys')
|
|
|
|
local keymaps = M.resolve(buffer)
|
|
|
|
|
|
|
|
for _, keys in pairs(keymaps) do
|
|
|
|
if not keys.has or M.has(buffer, keys.has) then
|
|
|
|
local opts = Keys.opts(keys)
|
|
|
|
---@diagnostic disable-next-line: no-unknown
|
|
|
|
opts.has = nil
|
|
|
|
opts.silent = opts.silent ~= false
|
|
|
|
opts.buffer = buffer
|
|
|
|
vim.keymap.set(keys.mode or 'n', keys[1], keys[2], opts)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Toggle diagnostics locally (false) or globally (true).
|
|
|
|
---@param global boolean
|
|
|
|
function M.diagnostic_toggle(global)
|
|
|
|
local bufnr, cmd, msg, state
|
|
|
|
if global then
|
|
|
|
bufnr = nil
|
|
|
|
state = vim.g.diagnostics_disabled
|
|
|
|
vim.g.diagnostics_disabled = not state
|
|
|
|
else
|
|
|
|
bufnr = 0
|
|
|
|
if vim.fn.has('nvim-0.9') == 1 then
|
|
|
|
state = vim.diagnostic.is_disabled(bufnr)
|
|
|
|
else
|
|
|
|
state = vim.b.diagnostics_disabled
|
|
|
|
vim.b.diagnostics_disabled = not state
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
cmd = state and 'enable' or 'disable'
|
|
|
|
msg = cmd:gsub('^%l', string.upper) .. 'd diagnostics'
|
|
|
|
if global then
|
|
|
|
msg = msg .. ' globally'
|
|
|
|
end
|
|
|
|
vim.notify(msg)
|
|
|
|
vim.schedule(function()
|
|
|
|
vim.diagnostic[cmd](bufnr)
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param next boolean
|
|
|
|
---@param severity string|nil
|
|
|
|
---@return fun()
|
|
|
|
function M.diagnostic_goto(next, severity)
|
|
|
|
local go = next and vim.diagnostic.goto_next or vim.diagnostic.goto_prev
|
|
|
|
local severity_int = severity and vim.diagnostic.severity[severity] or nil
|
|
|
|
return function()
|
|
|
|
go({ severity = severity_int })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return M
|