feat: refactor lsp configs and drop nvim-cmp
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
local lsp = require("lsp")
|
||||
local util = require("util")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
filetypes = {
|
||||
"sh",
|
||||
"bash",
|
||||
"zsh",
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
vim.keymap.set("n", "<leader>lf", function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = { "shfmt", "-s", "-i", "4", "-" },
|
||||
output = "stdout",
|
||||
})
|
||||
end, { buffer = bufnr })
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
local Linter = require("linter")
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
filetypes = {
|
||||
"c",
|
||||
"cpp",
|
||||
},
|
||||
cmd = {
|
||||
"clangd",
|
||||
"--clang-tidy",
|
||||
"--enable-config",
|
||||
-- Fix for errors in files outside of project
|
||||
-- https://clangd.llvm.org/faq#how-do-i-fix-errors-i-get-when-opening-headers-outside-of-my-project-directory
|
||||
"--compile-commands-dir=build",
|
||||
},
|
||||
single_file_support = true,
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
Linter.add(bufnr, {
|
||||
cmd = {
|
||||
"clang-tidy",
|
||||
"-p=build",
|
||||
"--quiet",
|
||||
"--checks=-*,"
|
||||
.. "clang-analyzer-*,"
|
||||
.. "-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,"
|
||||
.. "-clang-analyzer-security.insecureAPI.strcpy",
|
||||
"%file%",
|
||||
},
|
||||
events = { "BufWritePost" },
|
||||
clear_events = { "TextChanged", "TextChangedI" },
|
||||
stdin = false,
|
||||
stdout = true,
|
||||
pattern = "^.+:(%d+):(%d+): (%w+): (.*) %[(.*)%]$",
|
||||
groups = { "lnum", "col", "severity", "message", "code" },
|
||||
source = "clang-tidy",
|
||||
severity_map = {
|
||||
error = vim.diagnostic.severity.ERROR,
|
||||
warning = vim.diagnostic.severity.WARN,
|
||||
note = vim.diagnostic.severity.HINT,
|
||||
},
|
||||
zero_idx_col = true,
|
||||
zero_idx_lnum = true,
|
||||
ignore_stderr = true,
|
||||
})
|
||||
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"gs",
|
||||
vim.cmd.LspClangdSwitchSourceHeader,
|
||||
{ buffer = bufnr }
|
||||
)
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
init_options = {
|
||||
buildDirectory = "build",
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
local lsp = require("lsp")
|
||||
local util = require("util")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
settings = {
|
||||
gopls = {
|
||||
staticcheck = true,
|
||||
semanticTokens = true,
|
||||
},
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
vim.keymap.set("n", "<leader>lf", function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"golines",
|
||||
"-m",
|
||||
"80",
|
||||
"--shorten-comments",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
vim.lsp.buf.format({ async = true })
|
||||
end, { buffer = bufnr })
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
local Linter = require("linter")
|
||||
local lsp = require("lsp")
|
||||
local util = require("util")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
settings = {
|
||||
intelephense = {
|
||||
environment = {
|
||||
phpVersion = "8.4",
|
||||
},
|
||||
format = {
|
||||
enable = true,
|
||||
braces = "psr12",
|
||||
},
|
||||
},
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
Linter.add(bufnr, {
|
||||
cmd = {
|
||||
"phpcs",
|
||||
"--standard=PSR12",
|
||||
"--report=emacs",
|
||||
"-s",
|
||||
"-q",
|
||||
"-",
|
||||
},
|
||||
stdin = true,
|
||||
stdout = true,
|
||||
pattern = "^.+:(%d+):(%d+): (%w+) %- (.*) %((.*)%)$",
|
||||
groups = { "lnum", "col", "severity", "message", "code" },
|
||||
source = "phpcs",
|
||||
severity_map = {
|
||||
error = vim.diagnostic.severity.ERROR,
|
||||
warning = vim.diagnostic.severity.WARN,
|
||||
},
|
||||
zero_idx_col = true,
|
||||
zero_idx_lnum = true,
|
||||
})
|
||||
|
||||
vim.keymap.set("n", "<leader>lf", function()
|
||||
vim.lsp.buf.format()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"php-cs-fixer",
|
||||
"fix",
|
||||
"%file%",
|
||||
"--quiet",
|
||||
},
|
||||
output = "in_place",
|
||||
ignore_stderr = true,
|
||||
env = { PHP_CS_FIXER_IGNORE_ENV = "1" },
|
||||
})
|
||||
end, { buffer = bufnr })
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
init_options = {
|
||||
completion = {
|
||||
disableSnippets = true,
|
||||
},
|
||||
diagnostics = {
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
init_options = {
|
||||
settings = {
|
||||
xml = {
|
||||
format = {
|
||||
enabled = true, -- is able to format document
|
||||
splitAttributes = true, -- each attribute is formatted onto new line
|
||||
joinCDATALines = false, -- normalize content inside CDATA
|
||||
joinCommentLines = false, -- normalize content inside comments
|
||||
formatComments = true, -- keep comment in relative position
|
||||
joinContentLines = false, -- normalize content inside elements
|
||||
spaceBeforeEmptyCloseLine = true, -- insert whitespace before self closing tag end bracket
|
||||
},
|
||||
validation = {
|
||||
noGrammar = "ignore",
|
||||
enabled = true,
|
||||
schema = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
local lsp = require("lsp")
|
||||
local util = require("util")
|
||||
|
||||
local lua_library_paths = {
|
||||
vim.env.VIMRUNTIME,
|
||||
}
|
||||
for _, plugin in ipairs(require("lazy").plugins()) do
|
||||
table.insert(lua_library_paths, plugin.dir)
|
||||
end
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
settings = {
|
||||
Lua = {
|
||||
completion = { showWord = "Disable" },
|
||||
runtime = {
|
||||
version = "LuaJIT",
|
||||
path = {
|
||||
"lua/?.lua",
|
||||
"lua/?/init.lua",
|
||||
},
|
||||
pathStrict = true,
|
||||
},
|
||||
workspace = {
|
||||
library = lua_library_paths,
|
||||
checkThirdParty = false,
|
||||
},
|
||||
hint = {
|
||||
enable = false,
|
||||
arrayIndex = "Disable",
|
||||
await = true,
|
||||
paramName = "All",
|
||||
paramType = true,
|
||||
semicolon = "Disable",
|
||||
setType = true,
|
||||
},
|
||||
telemetry = { enable = false },
|
||||
},
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
vim.keymap.set("n", "<leader>lf", function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"stylua",
|
||||
"--stdin-filepath",
|
||||
"%file%",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
auto_indent = true,
|
||||
})
|
||||
end, { buffer = bufnr })
|
||||
|
||||
vim.keymap.set("x", "<leader>lf", function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"stylua",
|
||||
"--range-start",
|
||||
"%byte_start%",
|
||||
"--range-end",
|
||||
"%byte_end%",
|
||||
"--stdin-filepath",
|
||||
"%file%",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
end, { buffer = bufnr })
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
settings = {
|
||||
others = {
|
||||
disableInlayHints = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
settings = {
|
||||
python = {
|
||||
analysis = {
|
||||
autoSearchPaths = true,
|
||||
diagnosticMode = "openFilesOnly",
|
||||
useLibraryCodeForTypes = true,
|
||||
typeCheckingMode = "strict",
|
||||
stubPath = "stubs",
|
||||
},
|
||||
},
|
||||
pyright = {
|
||||
disableLanguageServices = false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
local lsp = require("lsp")
|
||||
local util = require("util")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
vim.keymap.set("n", "<leader>lf", function()
|
||||
vim.lsp.buf.format()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"ruff",
|
||||
"check",
|
||||
"--stdin-filename=%file%",
|
||||
"--select=I",
|
||||
"--fix",
|
||||
"--quiet",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
end, { buffer = bufnr })
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = function(client, bufnr)
|
||||
lsp.on_attach(client, bufnr)
|
||||
|
||||
local handler_name = "textDocument/publishDiagnostics"
|
||||
local default_handler = client.handlers[handler_name]
|
||||
or vim.lsp.handlers[handler_name]
|
||||
client.handlers[handler_name] = function(err, result, context, config)
|
||||
if result and result.diagnostics then
|
||||
result.diagnostics = vim.tbl_filter(function(diagnostic)
|
||||
return diagnostic.severity < vim.diagnostic.severity.HINT
|
||||
end, result.diagnostics)
|
||||
end
|
||||
|
||||
default_handler(err, result, context, config)
|
||||
end
|
||||
end,
|
||||
settings = {
|
||||
["rust-analyzer"] = {
|
||||
check = {
|
||||
command = "clippy",
|
||||
extraArgs = {
|
||||
"--",
|
||||
"-Wclippy::pedantic",
|
||||
},
|
||||
},
|
||||
diagnostics = {
|
||||
styleLints = {
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
imports = {
|
||||
prefix = "self",
|
||||
},
|
||||
inlayHints = {
|
||||
chainingHints = {
|
||||
enable = false,
|
||||
},
|
||||
parameterHints = {
|
||||
enable = false,
|
||||
},
|
||||
typeHints = {
|
||||
enable = false,
|
||||
},
|
||||
},
|
||||
rustfmt = {
|
||||
extraArgs = { "+nightly" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
on_attach = lsp.on_attach,
|
||||
settings = {
|
||||
zls = {
|
||||
warn_style = true,
|
||||
highlight_global_var_declarations = true,
|
||||
inlay_hints_show_variable_type_hints = false,
|
||||
inlay_hints_show_struct_literal_field_type = false,
|
||||
inlay_hints_show_parameter_name = false,
|
||||
inlay_hints_show_builtin = false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,29 +1,22 @@
|
||||
---@type fun(name: string, cfg: vim.lsp.Config)
|
||||
vim.lsp.config = vim.lsp.config
|
||||
|
||||
local log = require("log")
|
||||
local util = require("util")
|
||||
|
||||
---@class ow.lsp.Keymap
|
||||
---@field mode string|string[]
|
||||
---@field lhs string
|
||||
---@field rhs string|function
|
||||
---@field opts? vim.keymap.set.Opts
|
||||
local M = {}
|
||||
|
||||
local Keymap = {}
|
||||
M.diagnostic_signs = {
|
||||
text = {
|
||||
[vim.diagnostic.severity.ERROR] = "E",
|
||||
[vim.diagnostic.severity.WARN] = "W",
|
||||
[vim.diagnostic.severity.INFO] = "I",
|
||||
[vim.diagnostic.severity.HINT] = "H",
|
||||
},
|
||||
}
|
||||
|
||||
---@param bufnr integer
|
||||
---@param keymaps ow.lsp.Keymap[]
|
||||
function Keymap.set(bufnr, keymaps)
|
||||
for _, keymap in ipairs(keymaps) do
|
||||
keymap.opts = vim.tbl_extend(
|
||||
"force",
|
||||
keymap.opts or {},
|
||||
{ buffer = bufnr, remap = true }
|
||||
)
|
||||
vim.keymap.set(keymap.mode, keymap.lhs, keymap.rhs, keymap.opts)
|
||||
end
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
function Keymap.set_defaults(bufnr)
|
||||
---@type ow.lsp.Keymap[]
|
||||
local function set_keymaps(bufnr)
|
||||
local keymaps = {
|
||||
{ mode = { "n" }, lhs = "<leader>df", rhs = vim.diagnostic.open_float },
|
||||
{
|
||||
@@ -63,7 +56,11 @@ function Keymap.set_defaults(bufnr)
|
||||
lhs = "<C-h>",
|
||||
rhs = vim.lsp.buf.document_highlight,
|
||||
},
|
||||
{ mode = { "n", "x" }, lhs = "<leader>lf", rhs = vim.lsp.buf.format },
|
||||
{
|
||||
mode = { "n", "x" },
|
||||
lhs = "<leader>lf",
|
||||
rhs = vim.lsp.buf.format,
|
||||
},
|
||||
{
|
||||
mode = { "n" },
|
||||
lhs = "<leader>ld",
|
||||
@@ -105,7 +102,100 @@ function Keymap.set_defaults(bufnr)
|
||||
})
|
||||
end
|
||||
|
||||
Keymap.set(bufnr, keymaps)
|
||||
for _, keymap in ipairs(keymaps) do
|
||||
keymap.opts =
|
||||
vim.tbl_extend("keep", keymap.opts or {}, { buffer = bufnr })
|
||||
vim.keymap.set(keymap.mode, keymap.lhs, keymap.rhs, keymap.opts)
|
||||
end
|
||||
end
|
||||
|
||||
return Keymap
|
||||
--- Load a JSON file and return a parsed table merged with settings
|
||||
---@param path string
|
||||
---@param settings? table
|
||||
---@return table?
|
||||
local function with_file(path, settings)
|
||||
local file = io.open(path, "r")
|
||||
if not file then
|
||||
return
|
||||
end
|
||||
|
||||
local json = file:read("*all")
|
||||
file:close()
|
||||
local ok, resp = pcall(
|
||||
vim.json.decode,
|
||||
json,
|
||||
{ luanil = { object = true, array = true } }
|
||||
)
|
||||
if not ok then
|
||||
log.warning("Failed to parse json file %s: %s", path, resp)
|
||||
return
|
||||
end
|
||||
|
||||
return vim.tbl_deep_extend("force", settings or {}, resp)
|
||||
end
|
||||
|
||||
function M.on_attach(client, bufnr)
|
||||
set_keymaps(bufnr)
|
||||
|
||||
client.settings = with_file(
|
||||
string.format(".%s.json", client.name),
|
||||
client.settings
|
||||
) or client.settings
|
||||
|
||||
if client:supports_method("textDocument/completion") then
|
||||
vim.lsp.completion.enable(true, client.id, bufnr, {
|
||||
autotrigger = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
vim.diagnostic.config({
|
||||
underline = true,
|
||||
signs = M.diagnostic_signs,
|
||||
virtual_text = false,
|
||||
float = {
|
||||
show_header = false,
|
||||
source = true,
|
||||
border = "rounded",
|
||||
focusable = true,
|
||||
format = function(diagnostic)
|
||||
return string.format("%s", diagnostic.message)
|
||||
end,
|
||||
width = 80,
|
||||
},
|
||||
update_in_insert = false,
|
||||
severity_sort = true,
|
||||
jump = {
|
||||
float = true,
|
||||
wrap = false,
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.enable({
|
||||
"bashls",
|
||||
"clangd",
|
||||
"cmake",
|
||||
"gopls",
|
||||
-- "hyprls",
|
||||
"intelephense",
|
||||
-- "jedi_language_server",
|
||||
"lemminx",
|
||||
"lua_ls",
|
||||
"mesonlsp",
|
||||
-- "phpactor",
|
||||
-- "pyrefly",
|
||||
"pyright",
|
||||
"ruff",
|
||||
"rust_analyzer",
|
||||
"zls",
|
||||
})
|
||||
|
||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
vim.lsp.config("*", {
|
||||
capabilities = capabilities,
|
||||
on_attach = M.on_attach,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,540 +0,0 @@
|
||||
---@type fun(name: string, cfg: vim.lsp.Config)
|
||||
vim.lsp.config = vim.lsp.config
|
||||
|
||||
local Keymap = require("lsp.keymap")
|
||||
local Linter = require("lsp.linter")
|
||||
local log = require("log")
|
||||
local util = require("util")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.diagnostic_signs = {
|
||||
text = {
|
||||
[vim.diagnostic.severity.ERROR] = "E",
|
||||
[vim.diagnostic.severity.WARN] = "W",
|
||||
[vim.diagnostic.severity.INFO] = "I",
|
||||
[vim.diagnostic.severity.HINT] = "H",
|
||||
},
|
||||
}
|
||||
|
||||
---@param server string
|
||||
---@param fn? fun(client: vim.lsp.Client, bufnr: integer)
|
||||
---@return fun(client: vim.lsp.Client, bufnr: integer)
|
||||
function M.with_defaults(server, fn)
|
||||
local default_cb = vim.lsp.config[server].on_attach
|
||||
return function(client, bufnr)
|
||||
if default_cb then
|
||||
default_cb(client, bufnr)
|
||||
end
|
||||
|
||||
Keymap.set_defaults(bufnr)
|
||||
|
||||
-- For document highlight
|
||||
vim.cmd.highlight({ "link LspReferenceRead Visual", bang = true })
|
||||
vim.cmd.highlight({ "link LspReferenceText Visual", bang = true })
|
||||
vim.cmd.highlight({ "link LspReferenceWrite Visual", bang = true })
|
||||
|
||||
client.settings = M.with_file(
|
||||
string.format(".%s.json", client.name),
|
||||
client.settings
|
||||
) or client.settings
|
||||
|
||||
if fn then
|
||||
fn(client, bufnr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Load a JSON file and return a parsed table merged with settings
|
||||
---@param path string
|
||||
---@param settings? table
|
||||
---@return table?
|
||||
function M.with_file(path, settings)
|
||||
local file = io.open(path, "r")
|
||||
if not file then
|
||||
return
|
||||
end
|
||||
|
||||
local json = file:read("*all")
|
||||
file:close()
|
||||
local ok, resp = pcall(
|
||||
vim.json.decode,
|
||||
json,
|
||||
{ luanil = { object = true, array = true } }
|
||||
)
|
||||
if not ok then
|
||||
log.warning("Failed to parse json file %s: %s", path, resp)
|
||||
return
|
||||
end
|
||||
|
||||
return vim.tbl_deep_extend("force", settings or {}, resp)
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
vim.diagnostic.config({
|
||||
underline = true,
|
||||
signs = M.diagnostic_signs,
|
||||
virtual_text = false,
|
||||
float = {
|
||||
show_header = false,
|
||||
source = true,
|
||||
border = "rounded",
|
||||
focusable = true,
|
||||
format = function(diagnostic)
|
||||
return string.format("%s", diagnostic.message)
|
||||
end,
|
||||
width = 80,
|
||||
},
|
||||
update_in_insert = false,
|
||||
severity_sort = true,
|
||||
jump = {
|
||||
float = true,
|
||||
wrap = false,
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.enable({
|
||||
"bashls",
|
||||
"clangd",
|
||||
"cmake",
|
||||
"gopls",
|
||||
"hyprls",
|
||||
"intelephense",
|
||||
-- "jedi_language_server",
|
||||
"lemminx",
|
||||
"lua_ls",
|
||||
"mesonlsp",
|
||||
-- "phpactor",
|
||||
-- "pyrefly",
|
||||
"pyright",
|
||||
"ruff",
|
||||
"rust_analyzer",
|
||||
"zls",
|
||||
})
|
||||
|
||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
local cmp_nvim_lsp = util.try_require("cmp_nvim_lsp")
|
||||
if cmp_nvim_lsp then
|
||||
capabilities = vim.tbl_deep_extend(
|
||||
"force",
|
||||
capabilities,
|
||||
cmp_nvim_lsp.default_capabilities()
|
||||
)
|
||||
end
|
||||
|
||||
vim.lsp.config("*", {
|
||||
on_attach = M.with_defaults("*"),
|
||||
capabilities = capabilities,
|
||||
})
|
||||
|
||||
vim.lsp.config("bashls", {
|
||||
filetypes = {
|
||||
"sh",
|
||||
"bash",
|
||||
"zsh",
|
||||
},
|
||||
on_attach = M.with_defaults("bashls", function(_, bufnr)
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = { "shfmt", "-s", "-i", "4", "-" },
|
||||
output = "stdout",
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("clangd", {
|
||||
filetypes = {
|
||||
"c",
|
||||
"cpp",
|
||||
},
|
||||
cmd = {
|
||||
"clangd",
|
||||
"--clang-tidy",
|
||||
"--enable-config",
|
||||
-- Fix for errors in files outside of project
|
||||
-- https://clangd.llvm.org/faq#how-do-i-fix-errors-i-get-when-opening-headers-outside-of-my-project-directory
|
||||
"--compile-commands-dir=build",
|
||||
},
|
||||
single_file_support = true,
|
||||
on_attach = M.with_defaults("clangd", function(_, bufnr)
|
||||
Linter.add(bufnr, {
|
||||
cmd = {
|
||||
"clang-tidy",
|
||||
"-p=build",
|
||||
"--quiet",
|
||||
"--checks=-*,"
|
||||
.. "clang-analyzer-*,"
|
||||
.. "-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,"
|
||||
.. "-clang-analyzer-security.insecureAPI.strcpy",
|
||||
"%file%",
|
||||
},
|
||||
events = { "BufWritePost" },
|
||||
clear_events = { "TextChanged", "TextChangedI" },
|
||||
stdin = false,
|
||||
stdout = true,
|
||||
pattern = "^.+:(%d+):(%d+): (%w+): (.*) %[(.*)%]$",
|
||||
groups = { "lnum", "col", "severity", "message", "code" },
|
||||
source = "clang-tidy",
|
||||
severity_map = {
|
||||
error = vim.diagnostic.severity.ERROR,
|
||||
warning = vim.diagnostic.severity.WARN,
|
||||
note = vim.diagnostic.severity.HINT,
|
||||
},
|
||||
zero_idx_col = true,
|
||||
zero_idx_lnum = true,
|
||||
ignore_stderr = true,
|
||||
})
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "gs",
|
||||
rhs = vim.cmd.LspClangdSwitchSourceHeader,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("cmake", {
|
||||
init_options = {
|
||||
buildDirectory = "build",
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("gopls", {
|
||||
settings = {
|
||||
gopls = {
|
||||
staticcheck = true,
|
||||
semanticTokens = true,
|
||||
},
|
||||
},
|
||||
on_attach = M.with_defaults("gopls", function(_, bufnr)
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"golines",
|
||||
"-m",
|
||||
"80",
|
||||
"--shorten-comments",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
vim.lsp.buf.format({ async = true })
|
||||
end,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("intelephense", {
|
||||
settings = {
|
||||
intelephense = {
|
||||
environment = {
|
||||
phpVersion = "8.4",
|
||||
},
|
||||
format = {
|
||||
enable = true,
|
||||
braces = "psr12",
|
||||
},
|
||||
},
|
||||
},
|
||||
on_attach = M.with_defaults("intelephense", function(_, bufnr)
|
||||
Linter.add(bufnr, {
|
||||
cmd = {
|
||||
"phpcs",
|
||||
"--standard=PSR12",
|
||||
"--report=emacs",
|
||||
"-s",
|
||||
"-q",
|
||||
"-",
|
||||
},
|
||||
stdin = true,
|
||||
stdout = true,
|
||||
pattern = "^.+:(%d+):(%d+): (%w+) %- (.*) %((.*)%)$",
|
||||
groups = { "lnum", "col", "severity", "message", "code" },
|
||||
source = "phpcs",
|
||||
severity_map = {
|
||||
error = vim.diagnostic.severity.ERROR,
|
||||
warning = vim.diagnostic.severity.WARN,
|
||||
},
|
||||
zero_idx_col = true,
|
||||
zero_idx_lnum = true,
|
||||
})
|
||||
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
vim.lsp.buf.format()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"php-cs-fixer",
|
||||
"fix",
|
||||
"%file%",
|
||||
"--quiet",
|
||||
},
|
||||
output = "in_place",
|
||||
ignore_stderr = true,
|
||||
env = { PHP_CS_FIXER_IGNORE_ENV = "1" },
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("jedi_language_server", {
|
||||
init_options = {
|
||||
completion = {
|
||||
disableSnippets = true,
|
||||
},
|
||||
diagnostics = {
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("lemminx", {
|
||||
init_options = {
|
||||
settings = {
|
||||
xml = {
|
||||
format = {
|
||||
enabled = true, -- is able to format document
|
||||
splitAttributes = true, -- each attribute is formatted onto new line
|
||||
joinCDATALines = false, -- normalize content inside CDATA
|
||||
joinCommentLines = false, -- normalize content inside comments
|
||||
formatComments = true, -- keep comment in relative position
|
||||
joinContentLines = false, -- normalize content inside elements
|
||||
spaceBeforeEmptyCloseLine = true, -- insert whitespace before self closing tag end bracket
|
||||
},
|
||||
validation = {
|
||||
noGrammar = "ignore",
|
||||
enabled = true,
|
||||
schema = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
local lua_library_paths = {
|
||||
vim.env.VIMRUNTIME,
|
||||
}
|
||||
for _, plugin in ipairs(require("lazy").plugins()) do
|
||||
table.insert(lua_library_paths, plugin.dir)
|
||||
end
|
||||
|
||||
vim.lsp.config("lua_ls", {
|
||||
settings = {
|
||||
Lua = {
|
||||
completion = { showWord = "Disable" },
|
||||
runtime = {
|
||||
version = "LuaJIT",
|
||||
path = {
|
||||
"lua/?.lua",
|
||||
"lua/?/init.lua",
|
||||
},
|
||||
pathStrict = true,
|
||||
},
|
||||
workspace = {
|
||||
library = lua_library_paths,
|
||||
checkThirdParty = false,
|
||||
},
|
||||
hint = {
|
||||
enable = false,
|
||||
arrayIndex = "Disable",
|
||||
await = true,
|
||||
paramName = "All",
|
||||
paramType = true,
|
||||
semicolon = "Disable",
|
||||
setType = true,
|
||||
},
|
||||
telemetry = { enable = false },
|
||||
},
|
||||
},
|
||||
on_attach = M.with_defaults("lua_ls", function(_, bufnr)
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"stylua",
|
||||
"--stdin-filepath",
|
||||
"%file%",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
auto_indent = true,
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
mode = "x",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"stylua",
|
||||
"--range-start",
|
||||
"%byte_start%",
|
||||
"--range-end",
|
||||
"%byte_end%",
|
||||
"--stdin-filepath",
|
||||
"%file%",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("mesonlsp", {
|
||||
on_attach = M.with_defaults("mesonlsp"),
|
||||
settings = {
|
||||
others = {
|
||||
disableInlayHints = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("pyright", {
|
||||
-- Handled in ruff instead
|
||||
-- on_attach = M.with_defaults("pyright"),
|
||||
settings = {
|
||||
python = {
|
||||
analysis = {
|
||||
autoSearchPaths = true,
|
||||
diagnosticMode = "openFilesOnly",
|
||||
useLibraryCodeForTypes = true,
|
||||
typeCheckingMode = "strict",
|
||||
stubPath = "stubs",
|
||||
},
|
||||
},
|
||||
pyright = {
|
||||
disableLanguageServices = false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("ruff", {
|
||||
on_attach = M.with_defaults("ruff", function(_, bufnr)
|
||||
Keymap.set(bufnr, {
|
||||
{
|
||||
mode = "n",
|
||||
lhs = "<leader>lf",
|
||||
rhs = function()
|
||||
vim.lsp.buf.format()
|
||||
util.format({
|
||||
buf = bufnr,
|
||||
cmd = {
|
||||
"ruff",
|
||||
"check",
|
||||
"--stdin-filename=%file%",
|
||||
"--select=I",
|
||||
"--fix",
|
||||
"--quiet",
|
||||
"-",
|
||||
},
|
||||
output = "stdout",
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
end),
|
||||
})
|
||||
|
||||
vim.lsp.config("rust_analyzer", {
|
||||
on_attach = M.with_defaults("rust_analyzer", function(client)
|
||||
local handler_name = "textDocument/publishDiagnostics"
|
||||
local default_handler = client.handlers[handler_name]
|
||||
or vim.lsp.handlers[handler_name]
|
||||
client.handlers[handler_name] = function(
|
||||
err,
|
||||
result,
|
||||
context,
|
||||
config
|
||||
)
|
||||
if result and result.diagnostics then
|
||||
result.diagnostics = vim.tbl_filter(function(diagnostic)
|
||||
return diagnostic.severity
|
||||
< vim.diagnostic.severity.HINT
|
||||
end, result.diagnostics)
|
||||
end
|
||||
|
||||
default_handler(err, result, context, config)
|
||||
end
|
||||
end),
|
||||
settings = {
|
||||
["rust-analyzer"] = {
|
||||
check = {
|
||||
command = "clippy",
|
||||
extraArgs = {
|
||||
"--",
|
||||
"-Wclippy::pedantic",
|
||||
},
|
||||
},
|
||||
diagnostics = {
|
||||
styleLints = {
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
imports = {
|
||||
prefix = "self",
|
||||
},
|
||||
inlayHints = {
|
||||
chainingHints = {
|
||||
enable = false,
|
||||
},
|
||||
parameterHints = {
|
||||
enable = false,
|
||||
},
|
||||
typeHints = {
|
||||
enable = false,
|
||||
},
|
||||
},
|
||||
rustfmt = {
|
||||
extraArgs = { "+nightly" },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("zls", {
|
||||
on_attach = M.with_defaults("zls"),
|
||||
settings = {
|
||||
zls = {
|
||||
warn_style = true,
|
||||
highlight_global_var_declarations = true,
|
||||
inlay_hints_show_variable_type_hints = false,
|
||||
inlay_hints_show_struct_literal_field_type = false,
|
||||
inlay_hints_show_parameter_name = false,
|
||||
inlay_hints_show_builtin = false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("pyrefly", {})
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,232 +0,0 @@
|
||||
-- https://github.com/hrsh7th/nvim-cmp
|
||||
|
||||
local word_pattern = "[%w_.]"
|
||||
|
||||
local function has_words_before()
|
||||
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(word_pattern)
|
||||
~= nil
|
||||
end
|
||||
|
||||
local function has_words_after()
|
||||
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 + 1, col + 1)
|
||||
:match(word_pattern)
|
||||
~= nil
|
||||
end
|
||||
|
||||
---@type LazyPluginSpec
|
||||
return {
|
||||
"hrsh7th/nvim-cmp",
|
||||
dependencies = {
|
||||
"saadparwaiz1/cmp_luasnip",
|
||||
"hrsh7th/cmp-path",
|
||||
"hrsh7th/cmp-cmdline",
|
||||
"hrsh7th/cmp-nvim-lsp",
|
||||
{
|
||||
"L3MON4D3/LuaSnip",
|
||||
config = function()
|
||||
require("luasnip.loaders.from_vscode").lazy_load()
|
||||
end,
|
||||
build = (
|
||||
require("util").os_name ~= "Windows_NT"
|
||||
and "make install_jsregexp"
|
||||
or nil
|
||||
),
|
||||
version = "2.*",
|
||||
dependencies = { "rafamadriz/friendly-snippets" },
|
||||
},
|
||||
{
|
||||
"onsails/lspkind.nvim",
|
||||
config = function()
|
||||
require("lspkind").init()
|
||||
end,
|
||||
},
|
||||
"teramako/cmp-cmdline-prompt.nvim",
|
||||
},
|
||||
config = function()
|
||||
local cmp = require("cmp")
|
||||
local luasnip = require("luasnip")
|
||||
local lspkind = require("lspkind")
|
||||
|
||||
---@type cmp.ConfigSchema
|
||||
local opts = {
|
||||
-- enabled = function()
|
||||
-- return has_words_before()
|
||||
-- end,
|
||||
preselect = "None",
|
||||
completion = {
|
||||
autocomplete = { "InsertEnter", "TextChanged" },
|
||||
keyword_length = 1,
|
||||
},
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
luasnip.lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
formatting = {
|
||||
format = function(entry, vim_item)
|
||||
vim_item = lspkind.cmp_format({
|
||||
mode = "symbol",
|
||||
maxwidth = 50,
|
||||
ellipsis_char = "...",
|
||||
before = function(_, item)
|
||||
item.dup = 0 -- remove duplicates, see nvim-cmp #511
|
||||
return item
|
||||
end,
|
||||
})(entry, vim_item)
|
||||
|
||||
return vim_item
|
||||
end,
|
||||
},
|
||||
|
||||
mapping = {
|
||||
["<tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item({
|
||||
behavior = cmp.SelectBehavior.Select,
|
||||
})
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<S-tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item({
|
||||
behavior = cmp.SelectBehavior.Select,
|
||||
})
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<C-n>"] = cmp.mapping.select_next_item({
|
||||
behavior = cmp.SelectBehavior.Select,
|
||||
}),
|
||||
["<C-p>"] = cmp.mapping.select_prev_item({
|
||||
behavior = cmp.SelectBehavior.Select,
|
||||
}),
|
||||
["<CR>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() and cmp.get_active_entry() then
|
||||
cmp.confirm({
|
||||
select = false,
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
})
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<C-y>"] = cmp.mapping.confirm({
|
||||
select = true,
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
}),
|
||||
["<C-x><C-o>"] = cmp.mapping.complete(),
|
||||
["<C-l>"] = function(fallback)
|
||||
if luasnip.locally_jumpable(1) then
|
||||
luasnip.jump(1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
["<C-h>"] = function(fallback)
|
||||
if luasnip.locally_jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
},
|
||||
sources = {
|
||||
{ name = "nvim_lsp" },
|
||||
{ name = "luasnip" },
|
||||
{ name = "orgmode" },
|
||||
{ name = "path" },
|
||||
},
|
||||
window = {
|
||||
completion = cmp.config.window.bordered({
|
||||
border = "none",
|
||||
winhighlight = "Normal:Pmenu,CursorLine:PmenuSel,Search:None",
|
||||
zindex = 1001,
|
||||
scrolloff = 0,
|
||||
col_offset = 0,
|
||||
side_padding = 1,
|
||||
scrollbar = true,
|
||||
}),
|
||||
documentation = cmp.config.window.bordered({
|
||||
border = "rounded",
|
||||
winhighlight = "CursorLine:Visual,Search:None",
|
||||
zindex = 1001,
|
||||
max_height = 80,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
cmp.setup(opts)
|
||||
cmp.setup.cmdline("/", {
|
||||
mapping = cmp.mapping.preset.cmdline(),
|
||||
sources = { { name = "buffer" } },
|
||||
})
|
||||
cmp.setup.cmdline(":", {
|
||||
mapping = cmp.mapping.preset.cmdline(),
|
||||
sources = cmp.config.sources({ { name = "path" } }, {
|
||||
{
|
||||
name = "cmdline",
|
||||
option = { ignore_cmds = { "!" } },
|
||||
},
|
||||
}),
|
||||
})
|
||||
-- for cmdline `input()` prompt
|
||||
-- see: `:help getcmdtype()`
|
||||
cmp.setup.cmdline("@", {
|
||||
mapping = cmp.mapping.preset.cmdline(),
|
||||
sources = cmp.config.sources({
|
||||
{
|
||||
name = "cmdline-prompt",
|
||||
---@type prompt.Option
|
||||
option = {
|
||||
kinds = {
|
||||
file = cmp.lsp.CompletionItemKind.File,
|
||||
dir = {
|
||||
kind = cmp.lsp.CompletionItemKind.Folder,
|
||||
hl_group = "CmpItemKindEnum",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
formatting = {
|
||||
fields = { "kind", "abbr", "menu" },
|
||||
format = function(entry, vim_item)
|
||||
local item = entry.completion_item
|
||||
if entry.source.name == "cmdline-prompt" then
|
||||
vim_item.kind = cmp.lsp.CompletionItemKind[item.kind]
|
||||
local kind =
|
||||
lspkind.cmp_format({ mode = "symbol_text" })(
|
||||
entry,
|
||||
vim_item
|
||||
)
|
||||
local strings =
|
||||
vim.split(kind.kind, "%s", { trimempty = true })
|
||||
kind.kind = " " .. (strings[1] or "")
|
||||
kind.menu = " ("
|
||||
.. (item.data.completion_type or "")
|
||||
.. ")"
|
||||
kind.menu_hl_group = kind.kind_hl_group
|
||||
return kind
|
||||
else
|
||||
return vim_item
|
||||
end
|
||||
end,
|
||||
},
|
||||
})
|
||||
end,
|
||||
}
|
||||
Reference in New Issue
Block a user