dotfiles-ansible/roles/nvim/files/nvim/lua/modules/lsp.lua

632 lines
24 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local M = {}
function M.signature_conf()
require('lsp_signature').setup {
bind = true, -- This is mandatory, otherwise border config doesn't work
floating_window = true,
fix_pos = true,
hint_enable = false,
hint_prefix = '',
hint_scheme = 'String',
hi_parameter = 'Visual',
transpancy = 5,
handler_opts = {border = 'single'},
zindex = 50, -- set to 200 to make the float window on top of others
toggle_key = '<C-k>'
}
end
function M.saga_conf()
require('lspsaga').init_lsp_saga {
debug = false,
use_saga_diagnostic_sign = true,
-- diagnostic sign
error_sign = '',
warn_sign = '',
hint_sign = '',
infor_sign = '',
dianostic_header_icon = '',
-- code action title icon
code_action_icon = '',
code_action_prompt = {
enable = false,
sign = true,
sign_priority = 40,
virtual_text = true
},
finder_definition_icon = '',
finder_reference_icon = '',
max_preview_lines = 10,
finder_action_keys = {
open = 'o',
vsplit = 's',
split = 'i',
quit = 'q',
scroll_down = '<C-f>',
scroll_up = '<C-b>'
},
code_action_keys = {
quit = 'q',
exec = '<CR>'
},
rename_action_keys = {
quit = '<C-c>',
exec = '<CR>'
},
definition_preview_icon = '',
border_style = 'single',
rename_prompt_prefix = '',
server_filetype_map = {}
}
end
function M.lsp_conf()
local lspconf = require('lspconfig')
local on_attach = require('util').lsp_on_attach
local capabilities = vim.lsp.protocol.make_client_capabilities()
-- Add additional capabilities supported by nvim-cmp
local completionItem = capabilities.textDocument.completion.completionItem
completionItem.documentationFormat = {'markdown', 'plaintext'}
completionItem.snippetSupport = true
completionItem.preselectSupport = true
completionItem.insertReplaceSupport = true
completionItem.labelDetailsSupport = true
completionItem.deprecatedSupport = true
completionItem.commitCharactersSupport = true
completionItem.tagSupport = {valueSet = {1}}
completionItem.resolveSupport = {
properties = {
'documentation',
'detail',
'additionalTextEdits',
}
}
-- Replace the default lsp diagnostic letters with prettier symbols
vim.fn.sign_define('LspDiagnosticsSignError', {text = ''})
vim.fn.sign_define('LspDiagnosticsSignWarning', {text = ''})
vim.fn.sign_define('LspDiagnosticsSignInformation', {text = ''})
vim.fn.sign_define('LspDiagnosticsSignHint', {text = ''})
---------------------------
-- Server configurations --
---------------------------
-- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md
local servers_path = vim.fn.stdpath('data') .. '/lsp'
-- C/C++
lspconf.clangd.setup {
on_attach = on_attach,
capabilities = capabilities,
filetypes = {'c', 'cpp'},
init_options = {
usePlaceholders = true,
completeUnimported = true,
clangdFileStatus = true
},
cmd = {
'clangd',
'-j=2',
'--background-index',
'--clang-tidy',
'--completion-style=detailed',
'--pch-storage=memory',
'--header-insertion=iwyu',
'--header-insertion-decorators'
}
}
-- Lua
local lua_lib_path = {}
local lua_runtime_path = {}
-- lua_lib_path[vim.fn.expand('~/.luarocks/share/lua/5.3')] = true
-- lua_lib_path[vim.fn.expand('/usr/share/lua/5.3')] = true
lua_lib_path[os.getenv('VIMRUNTIME') .. '/lua'] = true
-- local function add(lib)
-- for _, p in pairs(vim.fn.expand(lib .. '/lua', false, true)) do
-- p = vim.loop.fs_realpath(p)
-- if p then lua_lib_path[p] = true end
-- end
-- end
-- for _, site in pairs(vim.split(vim.opt.packpath:get(), ',')) do
-- add(site .. '/pack/*/opt/*')
-- add(site .. '/pack/*/start/*')
-- end
table.insert(lua_runtime_path, 'lua/?.lua')
table.insert(lua_runtime_path, 'lua/?/init.lua')
-- table.insert(lua_runtime_path, '?.lua')
-- table.insert(lua_runtime_path, '?/?.lua')
-- table.insert(lua_runtime_path, '?/init.lua')
for lib, _ in pairs(lua_lib_path) do
table.insert(lua_runtime_path, lib .. '/?.lua')
table.insert(lua_runtime_path, lib .. '/?/init.lua')
end
lspconf.sumneko_lua.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {
servers_path .. '/sumneko_lua/bin/Linux/lua-language-server',
'-E', '-e', 'LANG=en',
servers_path .. '/sumneko_lua/main.lua'
},
settings = {
Lua = {
diagnostics = {globals = {'vim'}},
runtime = {version = 'LuaJIT', path = lua_runtime_path},
workspace = {
library = lua_lib_path,
maxPreload = 1000,
preloadFileSize = 150
},
completion = {callSnippet = 'Replace'},
hint = {enable = true},
telemetry = {enable = false}
}
}
}
-- Go
lspconf.gopls.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {servers_path .. '/gopls/gopls', '--remote=auto'},
init_options = {
usePlaceholders = true,
completeUnimported = true
}
}
-- Yaml
-- lspconf.yamlls.setup {
-- on_attach = on_attach,
-- capabilities = capabilities,
-- cmd = {servers_path .. '/yamlls/node_modules/.bin/yaml-language-server', '--stdio'},
-- settings = {
-- redhat = {telemetry = {enabled = false}},
-- yaml = {
-- format = {
-- bracketSpacing = true,
-- printWidth = 80,
-- -- proseWrap = 'always', -- default is 'preserve'
-- -- singleQuote = true,
-- -- editor.formatOnType = true
-- },
-- schemas = require('schemastore').json.schemas()
-- }
-- }
-- }
-- Ansible
lspconf.ansiblels.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {'node', servers_path .. '/ansiblels/out/server/src/server.js', '--stdio'},
settings = {
ansible = {
python = {interpreterPath = 'python3'},
executionEnvironment = {enabled = false}
}
}
}
-- Tailwind
-- lspconf.tailwindcss.setup {
-- on_attach = on_attach,
-- capabilities = capabilities,
-- cmd = {servers_path .. '/tailwindcss/node_modules/.bin/tailwindcss-language-server', '--stdio'},
-- settings = {
-- tailwindCSS = {
-- emmetCompletions = true
-- }
-- }
-- }
-- Emmet
lspconf.emmet_ls.setup {
cmd = {servers_path .. '/emmet_ls/node_modules/.bin/emmet-ls', '--stdio'},
filetypes = {
'html', 'xml', 'css', 'scss', 'sass',
'javascript', 'javascriptreact'
},
capabilities = capabilities
}
-- HTML
lspconf.html.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {servers_path .. '/vscode/node_modules/.bin/vscode-html-language-server', '--stdio'},
}
-- Eslint
lspconf.eslint.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {servers_path .. '/vscode/node_modules/.bin/vscode-eslint-language-server', '--stdio'},
filetypes = {'javascript', 'javascriptreact', 'typescript', 'typescriptreact', 'vue', 'svelte'},
handlers = {
['eslint/noConfig'] = function()
vim.notify('Unable to parse ESLint config.', vim.log.levels.WARN)
end
},
settings = {
codeAction = {
disableRuleComment = {
enable = true,
location = 'separateLine'
},
showDocumentation = {enable = true}
},
codeActionOnSave = {
enable = false, -- run ':EslintFixAll' manually
mode = 'all'
},
format = true,
nodePath = '',
onIgnoredFiles = 'off',
packageManager = 'npm',
quiet = false,
rulesCustomizations = {},
run = 'onType',
useESLintClass = false,
validate = 'on',
workingDirectory = {mode = 'auto'}
}
}
-- JSON
lspconf.jsonls.setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = {servers_path .. '/vscode/node_modules/.bin/vscode-json-language-server', '--stdio'},
settings = {
json = {
-- Schema catalog: https://www.schemastore.org/api/json/catalog.json
schemas = require('schemastore').json.schemas()
}
}
}
-- Others
local servers = {
rust_analyzer = {'rust-analyzer'},
sqls = {servers_path .. '/sqls/sqls'},
cmake = {servers_path .. '/cmake/venv/bin/cmake-language-server'},
-- bashls = {servers_path .. '/bashls/node_modules/.bin/bash-language-server', 'start'},
-- dockerls = {servers_path .. '/dockerls/node_modules/.bin/docker-langserver', '--stdio'},
cssls = {servers_path .. '/vscode/node_modules/.bin/vscode-css-language-server', '--stdio'},
pyright = {servers_path .. '/pyright/node_modules/.bin/pyright-langserver', '--stdio'},
-- vimls = {servers_path .. '/vimls/node_modules/.bin/vim-language-server', '--stdio'},
tsserver = {servers_path .. '/tsserver/node_modules/.bin/typescript-language-server', '--stdio'}
}
for server, _ in pairs(servers) do
lspconf[server].setup {
on_attach = on_attach,
capabilities = capabilities,
cmd = servers[server]
}
end
end
-- TODO: installers for the rest
-- TODO: ansible-lint
function M.null_ls_conf()
local null_ls = require('null-ls')
local linters_path = vim.fn.stdpath('data') .. '/lint'
-- Register sources
null_ls.config {
sources = {
-- Formatters --
-- null_ls.builtins.formatting.black.with {
-- command = linters_path .. '/black/venv/bin/black'
-- },
-- null_ls.builtins.formatting.codespell.with {
-- command = linters_path .. '/codespell/venv/bin/codespell'
-- },
null_ls.builtins.formatting.clang_format.with {
filetypes = {'c', 'cpp'}
},
null_ls.builtins.formatting.cmake_format.with {
command = linters_path .. '/cmake_format/venv/bin/cmake-format'
},
-- null_ls.builtins.formatting.fish_indent,
-- null_ls.builtins.formatting.fixjson.with {command = 'fixjson'},
-- null_ls.builtins.formatting.fnlfmt.with {command = 'fnlfmt'},
-- null_ls.builtins.formatting.goimports.with {command = 'goimports'},
-- null_ls.builtins.formatting.gofmt.with {command = 'gofmt'},
-- null_ls.builtins.formatting.isort.with {
-- command = linters_path .. '/isort/venv/bin/isort'
-- },
-- null_ls.builtins.formatting.nixfmt.with {command = 'nixfmt'},
-- null_ls.builtins.formatting.prettier.with {
-- command = linters_path .. '/prettier/node_modules/.bin/prettier'
-- },
-- null_ls.builtins.formatting.rustfmt.with {command = 'rustfmt'},
-- null_ls.builtins.formatting.rustywind.with {command = 'rustywind'},
-- null_ls.builtins.formatting.shfmt.with {
-- command = linters_path .. '/shfmt/shfmt'
-- },
null_ls.builtins.formatting.stylua.with {
condition = function(utils)
return utils.root_has_file('stylua.toml')
end,
command = 'stylua'
},
-- null_ls.builtins.formatting.uncrustify.with {command = 'uncrustify'},
-- null_ls.builtins.formatting.yapf.with {
-- command = linters_path .. '/yapf/venv/bin/yapf'
-- },
-- null_ls.builtins.formatting.autopep8.with {
-- command = linters_path .. '/autopep8/venv/bin/autopep8'
-- },
-- null_ls.builtins.formatting.stylelint.with {
-- command = linters_path .. '/stylelint/node_modules/.bin/stylelint'
-- },
-- Linters --
null_ls.builtins.diagnostics.shellcheck,
null_ls.builtins.diagnostics.codespell.with {
command = linters_path .. '/codespell/venv/bin/codespell'
},
null_ls.builtins.diagnostics.cspell.with {
command = linters_path .. '/cspell/node_modules/.bin/cspell'
},
-- null_ls.builtins.diagnostics.flake8.with {
-- command = linters_path .. '/flake8/venv/bin/flake8'
-- },
null_ls.builtins.diagnostics.hadolint.with {
command = vim.fn.stdpath('config') .. '/scripts/hadolint',
args = {'$FILENAME'}
},
-- null_ls.builtins.diagnostics.luacheck,
null_ls.builtins.diagnostics.cppcheck,
null_ls.builtins.diagnostics.write_good.with {
command = linters_path .. '/write_good/node_modules/.bin/write-good'
},
null_ls.builtins.diagnostics.markdownlint.with {
command = linters_path .. '/markdownlint/node_modules/.bin/markdownlint'
},
-- null_ls.builtins.diagnostics.pylint.with {
-- command = linters_path .. '/pylint/venv/bin/pylint'
-- },
null_ls.builtins.diagnostics.qmllint,
null_ls.builtins.diagnostics.selene.with {
condition = function(utils)
return utils.root_has_file('selene.toml')
end,
},
-- null_ls.builtins.diagnostics.vale.with {
-- command = linters_path .. '/vale/vale'
-- },
-- null_ls.builtins.diagnostics.vint.with {
-- command = linters_path .. '/vint/venv/bin/vint'
-- },
-- null_ls.builtins.diagnostics.stylelint.with {
-- command = linters_path .. '/stylelint/node_modules/.bin/stylelint'
-- },
-- Special --
null_ls.builtins.hover.dictionary -- get word definition from dictionaryapi.dev
}
}
local lspconf = require('lspconfig')
local on_attach = require('util').lsp_on_attach
lspconf['null-ls'].setup {
on_attach = on_attach
}
end
function M.sqls_conf()
require('sqls').setup {
picker = 'telescope'
}
end
function M.trouble_conf()
require('trouble').setup {
mode = 'lsp_workspace_diagnostics',
fold_open = '',
fold_closed = '',
action_keys = {
open_split = {'<c-h>'},
open_vsplit = {'<c-v>'},
open_tab = {'<c-t>'}
},
signs = {
error = '',
warning = '',
information = '',
hint = '',
other = ''
}
}
end
function M.comments_conf()
require('todo-comments').setup {
signs = false,
-- sign_priority = 8,
keywords = {
FIX = {
icon = '', -- icon used for the sign, and in search results
color = 'error', -- can be a hex color, or a named color (see below)
alt = {'FIXME', 'BUG', 'FIXIT', 'ISSUE'}, -- a set of other keywords that all map to this FIX keywords
-- signs = false, -- configure signs for some keywords individually
},
TODO = {icon = '', color = 'info'},
HACK = {icon = '', color = 'warning'},
WARN = {icon = '', color = 'warning', alt = {'WARNING', 'XXX'}},
PERF = {icon = '', alt = {'OPTIM', 'PERFORMANCE', 'OPTIMIZE'}},
NOTE = {icon = '', color = 'hint', alt = {'INFO'}},
},
merge_keywords = true,
highlight = {
before = '', -- 'fg' or 'bg' or empty
keyword = 'fg', -- 'fg', 'bg', 'wide' or empty. (wide is the same as bg, but will also highlight surrounding characters)
after = '', -- 'fg' or 'bg' or empty
pattern = [[.*<(KEYWORDS)\s*:]], -- pattern or table of patterns, used for highlightng (vim regex)
comments_only = true, -- uses treesitter to match keywords in comments only
max_line_len = 400, -- ignore lines longer than this
exclude = {'org'} -- list of file types to exclude highlighting
},
colors = {
error = {'LspDiagnosticsDefaultError', 'TSDanger', '#bf616a', '#e06c75'},
warning = {'LspDiagnosticsDefaultWarning', 'TSWarning', '#ebcb8b', '#e5c07b'},
info = {'LspDiagnosticsDefaultInformation', 'TSNote', '#81a1c1', '#61afef'},
hint = {'LspDiagnosticsDefaultHint', '#88c0d0', '#56b6c2'},
default = {'Normal', '#d8dee9', '#abb2bf'}
},
search = {
command = 'rg',
args = {
'--hidden',
'--color=never',
'--no-heading',
'--with-filename',
'--line-number',
'--column',
},
-- regex that will be used to match keywords.
-- don't replace the (KEYWORDS) placeholder
pattern = [[\b(KEYWORDS):]] -- ripgrep regex
-- pattern = [[\b(KEYWORDS)\b]] -- match without the extra colon. You'll likely get false positives
}
}
end
function M.outline_conf()
vim.g.symbols_outline = {
highlight_hovered_item = false,
show_guides = true,
auto_preview = true,
position = 'right',
width = 30,
show_numbers = false,
show_relative_numbers = false,
show_symbol_details = true,
preview_bg_highlight = 'NormalFloat',
keymaps = { -- Can be string or a table
close = {'<Esc>', 'q'},
goto_location = '<Cr>',
focus_location = 'o',
hover_symbol = '<C-space>',
toggle_preview = 'K',
rename_symbol = 'r',
code_actions = 'a',
},
lsp_blacklist = {},
symbol_blacklist = {},
symbols = {
File = {icon = '', hl = 'TSURI'},
Module = {icon = '', hl = 'TSNamespace'},
Namespace = {icon = '', hl = 'TSNamespace'},
Package = {icon = '', hl = 'TSNamespace'},
Class = {icon = '𝓒', hl = 'TSType'},
Method = {icon = 'ƒ', hl = 'TSMethod'},
Property = {icon = '', hl = 'TSMethod'},
Field = {icon = '', hl = 'TSField'},
Constructor = {icon = '', hl = 'TSConstructor'},
Enum = {icon = '', hl = 'TSType'},
Interface = {icon = '', hl = 'TSType'},
Function = {icon = '', hl = 'TSFunction'},
Variable = {icon = '', hl = 'TSConstant'},
Constant = {icon = '', hl = 'TSConstant'},
String = {icon = '𝓐', hl = 'TSString'},
Number = {icon = '#', hl = 'TSNumber'},
Boolean = {icon = '', hl = 'TSBoolean'},
Array = {icon = '', hl = 'TSConstant'},
Object = {icon = '⦿', hl = 'TSType'},
Key = {icon = '🔐', hl = 'TSType'},
Null = {icon = 'NULL', hl = 'TSType'},
EnumMember = {icon = '', hl = 'TSField'},
Struct = {icon = '𝓢', hl = 'TSType'},
Event = {icon = '🗲', hl = 'TSType'},
Operator = {icon = '+', hl = 'TSOperator'},
TypeParameter = {icon = '𝙏', hl = 'TSParameter'}
}
}
end
function M.dap_conf()
local dap = require('dap')
vim.fn.sign_define('DapBreakpoint', {text='', texthl='DapSignDefault'})
vim.fn.sign_define('DapLogPoint', {text='', texthl='DapSignDefault'})
vim.fn.sign_define('DapStopped', {text='', texthl='DapSignDefault'})
vim.fn.sign_define('DapBreakpointRejected', {text='', texthl='DapSignRejected'})
-- Mappings
vim.api.nvim_command('n', '<leader>dn', ':lua require("dap").continue()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dd', ':lua require("dap").disconnect()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>db', ':lua require("dap").toggle_breakpoint()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dB', ':lua require("dap").set_breakpoint(vim.fn.input("Breakpoint condition: "))<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dl', ':lua require("dap").list_breakpoints()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dc', ':lua require("dap").run_to_cursor()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dz', ':lua require("dap").run_last()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<F9>', ':lua require("dap").step_over()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dv', ':lua require("dap").step_over()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<F10>', ':lua require("dap").step_into()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>di', ':lua require("dap").step_into()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<F11>', ':lua require("dap").step_out()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>do', ':lua require("dap").step_out()<CR>', {noremap = true, silent = true})
vim.api.nvim_command('n', '<leader>dr', ':lua require("dap").repl.open()<CR>', {noremap = true, silent = true})
end
function M.dapui_conf()
local dap, dapui = require('dap'), require('dapui')
dap.listeners.after.event_initialized['dapui_config'] = function() dapui.open() end
dap.listeners.before.event_terminated['dapui_config'] = function() dapui.close() end
dap.listeners.before.event_exited['dapui_config'] = function() dapui.close() end
require('dapui').setup {
icons = {expanded = '', collapsed = ''},
mappings = {
expand = {'<CR>', '<2-LeftMouse>'},
open = 'o',
remove = 'd',
edit = 'e',
repl = 'r'
},
sidebar = {
elements = {
-- Provide as ID strings or tables with 'id' and 'size' keys
-- 'size' can be float or integer > 1
{id = 'scopes', size = 0.25},
{id = 'breakpoints', size = 0.25},
{id = 'stacks', size = 0.25},
{id = 'watches', size = 0.25},
},
size = 40,
position = 'left'
},
tray = {
elements = {'repl'},
size = 10,
position = 'bottom'
},
floating = {
max_height = nil, -- These can be integers or a float between 0 and 1.
max_width = nil, -- Floats will be treated as percentage of your screen.
border = 'single',
mappings = {
close = {'q', '<Esc>'}
}
},
windows = {indent = 1}
}
-- Mappings
vim.api.nvim_set_keymap('n', '<leader>de', ':lua require("dapui").eval()<CR>', {noremap = true, silent = true})
vim.api.nvim_set_keymap('v', '<leader>de', ':lua require("dapui").eval()<CR>', {noremap = true, silent = true})
vim.api.nvim_set_keymap('n', '<leader>df', ':lua require("dapui").float_element()<CR>', {noremap = true, silent = true})
vim.api.nvim_set_keymap('n', '<leader>dt', ':lua require("dapui").toggle()<CR>', {noremap = true, silent = true})
end
return M