Open BlueDruddigon opened 1 year ago
Here is my config of lsp with lazy.nvim package manager
return {
-- lspconfig
{
"neovim/nvim-lspconfig",
dependencies = {
{ "folke/neoconf.nvim", cmd = "Neoconf", config = true },
{ "folke/neodev.nvim", opts = { experimental = { pathStrict = true } } },
"mason.nvim",
"williamboman/mason-lspconfig.nvim",
{
"tamago324/nlsp-settings.nvim",
cmd = "LspSettings",
lazy = true,
opts = {
config_home = vim.fn.stdpath("config") .. "/lsp-settings",
local_settings_dir = ".lsp-settings",
local_settings_root_markers_fallback = { ".git" },
append_default_schemas = true,
loader = "json",
},
},
{ "b0o/SchemaStore.nvim", lazy = true },
"nvim-navic",
},
opts = {
-- options for vim.diagnostic.config()
diagnostics = {
underline = true,
update_in_insert = false,
virtual_text = { spacing = 4, prefix = "●" },
severity_sort = true,
},
-- lsp servers
servers = {
jsonls = {},
lua_ls = {
settings = {
Lua = {
telemetry = { enable = false },
runtime = { version = "LuaJIT" },
diagnostics = { globals = { "vim" } },
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
},
},
},
-- python
jedi = {},
-- js, jsx, ts, tsx
tsserver = {},
cssls = {},
tailwindcss = {},
astro = {},
},
},
config = function(_, opts)
-- setup format on save
local format_on_save = function(buf)
vim.lsp.buf.format({
bufnr = buf,
timeout_ms = 2000,
filter = function(client)
return client.name == "null-ls"
end,
})
end
-- on attach
local navic = require("nvim-navic")
local augroup_format = vim.api.nvim_create_augroup("LspFormatting", {})
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
callback = function(args)
local bufnr = args.buf
local client = vim.lsp.get_client_by_id(args.data.client_id)
-- enable completion triggered by <c-x><c-o>
vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc"
-- navic lsp symbol
if client.server_capabilities.documentSymbolProvider then
navic.attach(client, bufnr)
end
-- keymappings
local buf_opts = { buffer = bufnr }
vim.keymap.set("n", "gd", vim.lsp.buf.definition, buf_opts)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, buf_opts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, buf_opts)
vim.keymap.set("n", "gI", vim.lsp.buf.implementation, buf_opts)
vim.keymap.set("n", "gr", vim.lsp.buf.references, buf_opts)
vim.keymap.set("n", "<leader>D", vim.lsp.buf.type_definition, buf_opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, buf_opts)
if client.supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({ group = augroup_format, buffer = bufnr })
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup_format,
buffer = bufnr,
callback = function()
format_on_save(bufnr)
end,
})
end
end,
})
-- diagnostics
for name, icon in pairs(require("user.icons").diagnostics) do
name = "DiagnosticSign" .. name
vim.fn.sign_define(name, { text = icon, texthl = name, numhl = "" })
end
vim.diagnostic.config(opts.diagnostics)
local servers = opts.servers
local capabilities = require("cmp_nvim_lsp").default_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = {
"documentation",
"detail",
"additionalTextEdits",
},
}
local function setup(server)
local server_opts = {}
if server == "jsonls" then
server_opts = vim.tbl_deep_extend("force", {
capabilities = vim.deepcopy(capabilities),
settings = {
json = {
schemas = require("schemastore").json.schemas(),
format = { enable = true },
validate = { enable = true },
},
},
}, servers["jsonls"])
else
server_opts = vim.tbl_deep_extend("force", {
capabilities = vim.deepcopy(capabilities),
}, servers[server] or {})
end
require("lspconfig")[server].setup(server_opts)
end
-- get all the servers that are available through mason-lspconfig
local have_mason, mslp = pcall(require, "mason-lspconfig")
local all_mslp_servers = {}
if have_mason then
all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package)
end
local ensure_installed = {}
for server, server_opts in pairs(servers) do
setup(server)
if vim.tbl_contains(all_mslp_servers, server) then
ensure_installed[#ensure_installed + 1] = server
end
end
if have_mason then
mslp.setup({ ensure_installed = ensure_installed })
mslp.setup_handlers({ setup })
end
end,
},
-- formatters
{
"jose-elias-alvarez/null-ls.nvim",
event = { "BufReadPre", "BufNewFile" },
lazy = true,
opts = function()
local nls = require("null-ls")
return {
sources = {
-- python
nls.builtins.diagnostics.pylint,
nls.builtins.diagnostics.flake8,
nls.builtins.formatting.isort,
nls.builtins.formatting.yapf,
nls.builtins.formatting.autopep8,
-- lua
nls.builtins.formatting.stylua,
-- js, jsx, ts, tsx
nls.builtins.diagnostics.eslint,
nls.builtins.formatting.prettierd,
-- markdown
nls.builtins.diagnostics.write_good,
nls.builtins.code_actions.cspell,
nls.builtins.code_actions.proselint,
},
}
end,
},
-- cmdline tools and lsp servers
{
"williamboman/mason.nvim",
opts = {
ensure_installed = {
-- lua
"stylua",
-- python
"pylint",
"flake8",
"yapf",
"isort",
"autopep8",
-- markdown
"write-good",
"cspell",
"proselint",
-- js, jsx, ts, tsx
"eslint-lsp",
"prettierd",
},
pip = {
upgrade_pip = true,
},
},
config = function(_, opts)
require("mason").setup(opts)
local mr = require("mason-registry")
local function ensure_installed()
for _, tool in ipairs(opts.ensure_installed) do
local p = mr.get_package(tool)
if not p:is_installed() then
p:install()
end
end
end
if mr.refresh then
mr.refresh(ensure_installed)
else
ensure_installed()
end
end,
},
}
And here is my config of completion
return {
-- snippets
{
"L3MON4D3/LuaSnip",
event = "InsertEnter",
dependencies = {
"rafamadriz/friendly-snippets",
},
config = function()
local user_snippets = vim.fn.stdpath("config") .. "/snippets"
require("luasnip.loaders.from_vscode").lazy_load({ paths = user_snippets })
end,
},
-- auto completion
{
"hrsh7th/nvim-cmp",
version = false,
event = "InsertEnter",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
"saadparwaiz1/cmp_luasnip",
},
opts = function()
local luasnip = require("luasnip")
local cmp = require("cmp")
local has_word_before = function()
unpack = unpack or table.unpack
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0
and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
return {
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
sources = {
{ name = "luasnip" },
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "path" },
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
formatting = {
fields = { "kind", "abbr", "menu" },
format = function(entry, item)
item.kind = require("user.icons").kinds[item.kind]
item.menu = ({
nvim_lsp = "[LSP]",
path = "[Path]",
luasnip = "[Snippet]",
buffer = "[Buffer]",
})[entry.source.name]
item.dup = ({
nvim_lsp = 0,
path = 1,
luasnip = 1,
buffer = 1,
})[entry.source.name]
return item
end,
},
mapping = cmp.mapping.preset.insert({
["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "c" }),
["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "c" }),
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
elseif has_word_before() then
cmp.complete()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
}
end,
},
}
I'm currently using latest release version of neovim (0.9.0)
I'm follow up this channel to setup lsp servers and completion with
nvim-lspconfig
,mason-lspconfig.nvim
,mason.nvim
andnvim-cmp
comes up withcmp-nvim-lsp
.The LSP server i've setup is pyright. Current behavior is, when i type down
isin
, expected byisinstance
builtin function in python. but the completion item suggest thenp.isinf
in the first place in completion menu.Expected behavior is how to filter out the completion item depends on which user typed, such as the completion items start with
isin
in the previous examples.