Sanchayan Maity
b95a14b8d1
47b1578
did not actually fix it. We need to keep using 'gq' but actually
correctly specify whether we want normal or visual mode. Also disable
range formatting explicitly for tsserver.
307 lines
11 KiB
Lua
307 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 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,
|
|
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,
|
|
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,
|
|
},
|
|
},
|
|
},
|
|
}
|