Sanchayan Maity
be02b5ead7
nvim-compe has been deprecated. While we tried to make it a few days without any completion support, in javascript/typescript could not get the default omnicompletion to work at all. It is possible that this could be due to nvim-lsp-ts-utils/null-ls but who is gonna debug. Also tried MUcomplete but it just would not work. There are open issues on this. See https://github.com/neovim/neovim/issues/12390 and also https://github.com/lifepillar/vim-mucomplete/issues/179. So here we are with nvim-cmp. Some observations in comparison to compe before. Using buffer completion seems not possible as most of the times LSP completion items then do not turn up. Do not know if this is server specific but at least it is the case with Rust. compe seemed better performance wise especially in tsserver and considering the buffer problem mentioned above. Also, even with vsnip added as the completion source can't seem to get any snippet specific completions working. Could have ditched all completion support if I did not have to use tsserver but need it for work currently. So we will stick to enabling this and hopefully it improves in future. Fuck nodejs, javascript and typescript. For references see, https://github.com/kristijanhusak/neovim-config https://github.com/sQVe/dotfiles/tree/master/config/nvim
309 lines
11 KiB
Lua
309 lines
11 KiB
Lua
local nvim_lsp = require('lspconfig')
|
|
local protocol = require('vim.lsp.protocol')
|
|
local signature = require('lsp_signature')
|
|
local ts_utils = require("nvim-lsp-ts-utils")
|
|
local null_ls = require("null-ls")
|
|
local util = require("lspconfig/util")
|
|
|
|
-- https://github.com/neovim/nvim-lspconfig/wiki/User-contributed-tips
|
|
function format_range_operator()
|
|
local old_func = vim.go.operatorfunc
|
|
_G.op_func_formatting = function()
|
|
local start = vim.api.nvim_buf_get_mark(0, '[')
|
|
local finish = vim.api.nvim_buf_get_mark(0, ']')
|
|
vim.lsp.buf.range_formatting({}, start, finish)
|
|
vim.go.operatorfunc = old_func
|
|
_G.op_func_formatting = nil
|
|
end
|
|
vim.go.operatorfunc = 'v:lua.op_func_formatting'
|
|
vim.api.nvim_feedkeys('g@', 'n', false)
|
|
end
|
|
|
|
local function preview_location_callback(_, result)
|
|
if result == nil or vim.tbl_isempty(result) then
|
|
return nil
|
|
end
|
|
vim.lsp.util.preview_location(result[1])
|
|
end
|
|
|
|
function PeekDefinition()
|
|
local params = vim.lsp.util.make_position_params()
|
|
return vim.lsp.buf_request(0, 'textDocument/definition', params, preview_location_callback)
|
|
end
|
|
|
|
local on_attach = function(client, bufnr)
|
|
signature.on_attach({
|
|
bind = true,
|
|
hint_enable = true,
|
|
hint_prefix = "🐼 ",
|
|
hint_scheme = "String",
|
|
handler_opts = { border = "single" },
|
|
decorator = {"`", "`"}
|
|
})
|
|
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
|
|
|
|
if client.config.flags then
|
|
client.config.flags.allow_incremental_sync = true
|
|
client.config.flags.debounce_text_changes = 500
|
|
end
|
|
|
|
local opts = { noremap=true, silent=true }
|
|
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd' , '<cmd>lua vim.lsp.buf.definition()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD' , '<cmd>lua vim.lsp.buf.declaration()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<Leader>k', '<cmd>lua vim.lsp.buf.hover()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr' , '<cmd>lua vim.lsp.buf.references()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ga' , '<cmd>lua vim.lsp.buf.code_action()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi' , '<cmd>lua vim.lsp.buf.implementation()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>' , '<cmd>lua vim.lsp.buf.type_definition()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '1gd' , '<cmd>lua vim.lsp.buf.document_symbol()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '1gD' , '<cmd>lua vim.lsp.buf.workspace_symbol()<CR>', opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gR' , '<cmd>lua vim.lsp.buf.rename()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'pd' , '<cmd>lua PeekDefinition()<CR>' , opts)
|
|
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev { wrap = false }<CR>', opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next { wrap = false }<CR>', opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', '[D', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', ']D', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'do', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', ',d', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>' , opts)
|
|
|
|
if client.resolved_capabilities.document_range_formatting then
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'x', 'gq', '<cmd>lua format_range_operator()<CR>', opts)
|
|
end
|
|
if client.resolved_capabilities.document_formatting then
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gq', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)
|
|
end
|
|
|
|
if client.resolved_capabilities.code_lens then
|
|
vim.api.nvim_buf_set_keymap(bufnr, "n", "gl", "<cmd>lua vim.lsp.codelens.run()<CR>", opts)
|
|
vim.api.nvim_command [[autocmd CursorHold,CursorHoldI,InsertLeave <buffer> lua vim.lsp.codelens.refresh()]]
|
|
end
|
|
|
|
protocol.CompletionItemKind = {
|
|
' '; -- text
|
|
' '; -- method
|
|
' '; -- function
|
|
'全'; -- ctor
|
|
' '; -- field
|
|
' '; -- variable
|
|
' '; -- class
|
|
' '; -- interface
|
|
' '; -- module
|
|
' '; -- property
|
|
' '; -- unit
|
|
' '; -- value
|
|
'螺'; -- enum
|
|
' '; -- keyword
|
|
' '; -- snippet
|
|
' '; -- color
|
|
' '; -- file
|
|
' '; -- reference
|
|
' '; -- folder
|
|
' '; -- enum member
|
|
' '; -- constant
|
|
' '; -- struct
|
|
' '; -- event
|
|
'璉'; -- operator
|
|
' '; -- type parameter
|
|
}
|
|
|
|
if client.name == 'tsserver' then
|
|
-- Disable tsserver formatting as we plan on formatting via null-ls
|
|
client.resolved_capabilities.document_formatting = false
|
|
client.resolved_capabilities.document_range_formatting = false
|
|
|
|
ts_utils.setup {
|
|
debug = false,
|
|
disable_commands = false,
|
|
enable_import_on_completion = false,
|
|
|
|
import_all_timeout = 5000,
|
|
import_all_scan_buffers = 100,
|
|
import_all_select_source = false,
|
|
import_all_priorities = {
|
|
buffers = 4, -- loaded buffer names
|
|
buffer_content = 3, -- loaded buffer content
|
|
local_files = 2, -- git files or files with relative path markers
|
|
same_file = 1, -- add to existing import statement
|
|
},
|
|
|
|
eslint_enable_code_actions = true,
|
|
eslint_bin = "eslint",
|
|
eslint_enable_disable_comments = true,
|
|
eslint_enable_diagnostics = true,
|
|
eslint_config_fallback = nil,
|
|
eslint_show_rule_id = false,
|
|
|
|
enable_formatting = true,
|
|
formatter = "prettier",
|
|
formatter_config_fallback = nil,
|
|
|
|
update_imports_on_move = false,
|
|
require_confirmation_on_move = false,
|
|
watch_dir = nil,
|
|
|
|
filter_out_diagnostics_by_severity = {},
|
|
filter_out_diagnostics_by_code = {},
|
|
}
|
|
|
|
ts_utils.setup_client(client)
|
|
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'go', ':TSLspOrganize<CR>' , opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gf', ':TSLspFixCurrent<CR>', opts)
|
|
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gI', ':TSLspImportAll<CR>' , opts)
|
|
end
|
|
|
|
vim.cmd [[autocmd CursorHold,CursorHoldI <buffer> lua require'nvim-lightbulb'.update_lightbulb()]]
|
|
end
|
|
|
|
function set_snippet_capabilities()
|
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
|
|
|
capabilities.textDocument.completion.completionItem.snippetSupport = true
|
|
capabilities.textDocument.completion.completionItem.resolveSupport = {
|
|
properties = {
|
|
'documentation',
|
|
'detail',
|
|
'additionalTextEdits',
|
|
}
|
|
}
|
|
return require('cmp_nvim_lsp').update_capabilities(capabilities)
|
|
end
|
|
|
|
-- This should be called only once, so cannot be in on_attach as earlier.
|
|
-- See https://github.com/jose-elias-alvarez/null-ls.nvim/issues/38
|
|
-- Required by nvim-lsp-ts-utils to provide ESLint code actions, diagnostics
|
|
-- and formatting.
|
|
null_ls.config {}
|
|
nvim_lsp["null-ls"].setup {}
|
|
|
|
local servers = { 'hls', 'pylsp', 'tsserver' }
|
|
for _, lsp in ipairs(servers) do
|
|
nvim_lsp[lsp].setup {
|
|
on_attach = on_attach,
|
|
capabilities = set_snippet_capabilities(),
|
|
}
|
|
end
|
|
|
|
nvim_lsp.clangd.setup {
|
|
on_attach = on_attach,
|
|
capabilities = set_snippet_capabilities(),
|
|
default_config = {
|
|
cmd = { "clangd", "--background-index", "--pch-storage=memory", "--clang-tidy", "--suggest-missing-includes" },
|
|
filetypes = { 'c', 'cpp' },
|
|
root_dir = function(fname)
|
|
-- We specify build/compile_commands.json as that is where the compile_commands.json
|
|
-- gets generated automatically for meson projects.
|
|
local root_pattern = util.root_pattern('build/compile_commands.json', 'compile_commands.json', 'compile_flags.txt', '.git')
|
|
local filename = util.path.is_absolute(fname) and fname or util.path.join(vim.loop.cwd(), fname)
|
|
return root_pattern(filename) or util.path.dirname(filename)
|
|
end,
|
|
}
|
|
}
|
|
|
|
local rust_tool_opts = {
|
|
tools = {
|
|
autoSetHints = true,
|
|
hover_with_actions = false,
|
|
runnables = { use_telescope = false },
|
|
debuggables = { use_telescope = false },
|
|
inlay_hints = {
|
|
only_current_line = false,
|
|
only_current_line_autocmd = "CursorHold",
|
|
show_parameter_hints = true,
|
|
parameter_hints_prefix = "<- ",
|
|
other_hints_prefix = "=> ",
|
|
other_hints_prefix = "",
|
|
highlight = "Hint",
|
|
},
|
|
hover_actions = {
|
|
auto_focus = true
|
|
},
|
|
crate_graph = {
|
|
backend = "svg",
|
|
output = "crates_graph.svg",
|
|
full = false,
|
|
}
|
|
},
|
|
server = {
|
|
on_attach = on_attach,
|
|
capabilities = set_snippet_capabilities(),
|
|
settings = {
|
|
["rust-analyzer"] = {
|
|
checkOnSave = {
|
|
command = "clippy"
|
|
},
|
|
}
|
|
}
|
|
},
|
|
}
|
|
|
|
require('rust-tools').setup(rust_tool_opts)
|
|
|
|
-- See https://github.com/sumneko/lua-language-server/wiki/Setting-without-VSCode#neovim-with-built-in-lsp-client
|
|
-- on why we do this library thing
|
|
-- Idea taken from https://gist.github.com/folke/fe5d28423ea5380929c3f7ce674c41d8
|
|
local library = {}
|
|
local function add_to_library(lib_path)
|
|
for _, p in pairs(vim.fn.expand(lib_path, false, true)) do
|
|
p = vim.loop.fs_realpath(p)
|
|
library[p] = true
|
|
end
|
|
end
|
|
|
|
local function add_libraries()
|
|
local cwd = vim.fn.getcwd()
|
|
if string.find(cwd, "neovim") then
|
|
add_to_library("$VIMRUNTIME")
|
|
elseif string.find(cwd, "dotfiles") then
|
|
add_to_library("$VIMRUNTIME")
|
|
add_to_library("~/.config/nvim")
|
|
add_to_library("~/.local/share/nvim/site/pack/packer/opt/*")
|
|
add_to_library("~/.local/share/nvim/site/pack/packer/start/*")
|
|
else
|
|
add_to_library(cwd .. "/*")
|
|
end
|
|
end
|
|
|
|
local function determine_lua_version()
|
|
local cwd = vim.fn.getcwd()
|
|
if string.find(cwd, "neovim") or string.find(cwd, "dotfiles") then
|
|
return "LuaJIT"
|
|
else
|
|
return "Lua 5.4"
|
|
end
|
|
end
|
|
|
|
add_libraries()
|
|
|
|
local runtime_path = vim.split(package.path, ';')
|
|
table.insert(runtime_path, "lua/?.lua")
|
|
table.insert(runtime_path, "lua/?/init.lua")
|
|
|
|
nvim_lsp.sumneko_lua.setup {
|
|
cmd = { "/usr/bin/lua-language-server" };
|
|
on_attach = on_attach,
|
|
capabilities = set_snippet_capabilities(),
|
|
settings = {
|
|
Lua = {
|
|
runtime = {
|
|
version = determine_lua_version(),
|
|
path = runtime_path,
|
|
},
|
|
completion = { callSnippet = "Both" },
|
|
diagnostics = {
|
|
globals = {'vim'},
|
|
},
|
|
workspace = {
|
|
library = library,
|
|
maxPreload = 2000,
|
|
preloadFileSize = 50000
|
|
},
|
|
telemetry = {
|
|
enable = false,
|
|
},
|
|
},
|
|
},
|
|
}
|