Merge branch 'LazyVim:main' into main

This commit is contained in:
Ibrahim Delice 2024-05-20 16:43:46 +03:00 committed by GitHub
commit 3849f3dad9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 359 additions and 211 deletions

View file

@ -191,6 +191,13 @@ function M.setup(opts)
vim.cmd([[Lazy! load all]]) vim.cmd([[Lazy! load all]])
vim.cmd([[checkhealth]]) vim.cmd([[checkhealth]])
end, { desc = "Load all plugins and run :checkhealth" }) end, { desc = "Load all plugins and run :checkhealth" })
local health = require("lazy.health")
vim.list_extend(health.valid, {
"recommended",
"desc",
"vscode",
})
end, end,
}) })

View file

@ -36,19 +36,8 @@ return {
["<C-f>"] = cmp.mapping.scroll_docs(4), ["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(), ["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(), ["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = function(fallback) ["<CR>"] = LazyVim.cmp.confirm(),
if cmp.core.view:visible() or vim.fn.pumvisible() == 1 then ["<S-CR>"] = LazyVim.cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
LazyVim.create_undo()
if cmp.confirm({ select = true }) then
return
end
end
return fallback()
end,
["<S-CR>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
select = true,
}), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
["<C-CR>"] = function(fallback) ["<C-CR>"] = function(fallback)
cmp.abort() cmp.abort()
fallback() fallback()
@ -83,23 +72,15 @@ return {
source.group_index = source.group_index or 1 source.group_index = source.group_index or 1
end end
local cmp = require("cmp") local cmp = require("cmp")
local Kind = cmp.lsp.CompletionItemKind
cmp.setup(opts) cmp.setup(opts)
cmp.event:on("confirm_done", function(event) cmp.event:on("confirm_done", function(event)
if not vim.tbl_contains(opts.auto_brackets or {}, vim.bo.filetype) then if vim.tbl_contains(opts.auto_brackets or {}, vim.bo.filetype) then
return LazyVim.cmp.auto_brackets(event.entry)
end
local entry = event.entry
local item = entry:get_completion_item()
if vim.tbl_contains({ Kind.Function, Kind.Method }, item.kind) and item.insertTextFormat ~= 2 then
local cursor = vim.api.nvim_win_get_cursor(0)
local prev_char = vim.api.nvim_buf_get_text(0, cursor[1] - 1, cursor[2], cursor[1] - 1, cursor[2] + 1, {})[1]
if prev_char ~= "(" and prev_char ~= ")" then
local keys = vim.api.nvim_replace_termcodes("()<left>", false, false, true)
vim.api.nvim_feedkeys(keys, "i", true)
end
end end
end) end)
cmp.event:on("menu_opened", function(event)
LazyVim.cmp.add_missing_snippet_docs(event.window)
end)
end, end,
}, },
@ -113,8 +94,8 @@ return {
}, },
opts = function(_, opts) opts = function(_, opts)
opts.snippet = { opts.snippet = {
expand = function(args) expand = function(item)
vim.snippet.expand(args.body) return LazyVim.cmp.expand(item.body)
end, end,
} }
table.insert(opts.sources, { name = "snippets" }) table.insert(opts.sources, { name = "snippets" })

View file

@ -2,6 +2,7 @@ return {
recommended = function() recommended = function()
return LazyVim.extras.wants({ return LazyVim.extras.wants({
ft = "toml", ft = "toml",
root = "*.toml",
}) })
end, end,
{ {

View file

@ -121,16 +121,8 @@ return {
require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer) require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer)
end) end)
local register_capability = vim.lsp.handlers["client/registerCapability"] LazyVim.lsp.setup_dynamic_capability()
LazyVim.lsp.on_dynamic_capability(require("lazyvim.plugins.lsp.keymaps").on_attach)
vim.lsp.handlers["client/registerCapability"] = function(err, res, ctx)
---@diagnostic disable-next-line: no-unknown
local ret = register_capability(err, res, ctx)
local client = vim.lsp.get_client_by_id(ctx.client_id)
local buffer = vim.api.nvim_get_current_buf()
require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer)
return ret
end
LazyVim.lsp.words.setup(opts.document_highlight) LazyVim.lsp.words.setup(opts.document_highlight)
@ -148,24 +140,19 @@ return {
if vim.fn.has("nvim-0.10") == 1 then if vim.fn.has("nvim-0.10") == 1 then
-- inlay hints -- inlay hints
if opts.inlay_hints.enabled then if opts.inlay_hints.enabled then
LazyVim.lsp.on_attach(function(client, buffer) LazyVim.lsp.on_supports_method("textDocument/inlayHint", function(client, buffer)
if client.supports_method("textDocument/inlayHint") then
LazyVim.toggle.inlay_hints(buffer, true) LazyVim.toggle.inlay_hints(buffer, true)
end
end) end)
end end
-- code lens -- code lens
if opts.codelens.enabled and vim.lsp.codelens then if opts.codelens.enabled and vim.lsp.codelens then
LazyVim.lsp.on_attach(function(client, buffer) LazyVim.lsp.on_supports_method("textDocument/codeLens", function(client, buffer)
if client.supports_method("textDocument/codeLens") then
vim.lsp.codelens.refresh() vim.lsp.codelens.refresh()
--- autocmd BufEnter,CursorHold,InsertLeave <buffer> lua vim.lsp.codelens.refresh()
vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, {
buffer = buffer, buffer = buffer,
callback = vim.lsp.codelens.refresh, callback = vim.lsp.codelens.refresh,
}) })
end
end) end)
end end
end end

103
lua/lazyvim/util/cmp.lua Normal file
View file

@ -0,0 +1,103 @@
---@class lazyvim.util.cmp
local M = {}
---@param snippet string
---@param fn fun(placeholder:Placeholder):string
---@return string
function M.snippet_replace(snippet, fn)
return snippet:gsub("%$%b{}", function(m)
local n, name = m:match("^%${(%d+):(.+)}$")
return n and fn({ n = n, text = name }) or m
end) or snippet
end
-- This function resolves nested placeholders in a snippet.
function M.snippet_resolve(snippet)
return M.snippet_replace(snippet, function(placeholder)
return M.snippet_resolve(placeholder.text)
end):gsub("%$0", "")
end
-- This function replaces nested placeholders in a snippet with LSP placeholders.
function M.snippet_fix(snippet)
return M.snippet_replace(snippet, function(placeholder)
return "${" .. placeholder.n .. ":" .. M.snippet_resolve(placeholder.text) .. "}"
end)
end
---@param entry cmp.Entry
function M.auto_brackets(entry)
local cmp = require("cmp")
local Kind = cmp.lsp.CompletionItemKind
local item = entry:get_completion_item()
if vim.tbl_contains({ Kind.Function, Kind.Method }, item.kind) then
local cursor = vim.api.nvim_win_get_cursor(0)
local prev_char = vim.api.nvim_buf_get_text(0, cursor[1] - 1, cursor[2], cursor[1] - 1, cursor[2] + 1, {})[1]
if prev_char ~= "(" and prev_char ~= ")" then
local keys = vim.api.nvim_replace_termcodes("()<left>", false, false, true)
vim.api.nvim_feedkeys(keys, "i", true)
end
end
end
-- This function adds missing documentation to snippets.
-- The documentation is a preview of the snippet.
---@param window cmp.CustomEntriesView|cmp.NativeEntriesView
function M.add_missing_snippet_docs(window)
local cmp = require("cmp")
local Kind = cmp.lsp.CompletionItemKind
local entries = window:get_entries()
for _, entry in ipairs(entries) do
if entry:get_kind() == Kind.Snippet then
local item = entry:get_completion_item()
if not item.documentation and item.insertText then
item.documentation = {
kind = cmp.lsp.MarkupKind.Markdown,
value = string.format("```%s\n%s\n```", vim.bo.filetype, M.snippet_resolve(item.insertText)),
}
end
end
end
end
-- This is a better implementation of `cmp.confirm`:
-- * check if the completion menu is visible without waiting for running sources
-- * create an undo point before confirming
-- This function is both faster and more reliable.
---@param opts? {select: boolean, behavior: cmp.ConfirmBehavior}
function M.confirm(opts)
local cmp = require("cmp")
opts = vim.tbl_extend("force", {
select = true,
behavior = cmp.ConfirmBehavior.Insert,
}, opts or {})
return function(fallback)
if cmp.core.view:visible() or vim.fn.pumvisible() == 1 then
LazyVim.create_undo()
if cmp.confirm(opts) then
return
end
end
return fallback()
end
end
function M.expand(snippet)
local ok = pcall(vim.snippet.expand, snippet)
if not ok then
local fixed = M.snippet_fix(snippet)
ok = pcall(vim.snippet.expand, fixed)
local msg = ok and "Failed to parse snippet,\nbut was able to fix it automatically." or "Failed to parse snippet."
LazyVim[ok and "warn" or "error"](
([[%s
```%s
%s
```]]):format(msg, vim.bo.filetype, snippet),
{ title = "vim.snippet" }
)
end
end
return M

View file

@ -17,6 +17,7 @@ local LazyUtil = require("lazy.core.util")
---@field json lazyvim.util.json ---@field json lazyvim.util.json
---@field lualine lazyvim.util.lualine ---@field lualine lazyvim.util.lualine
---@field mini lazyvim.util.mini ---@field mini lazyvim.util.mini
---@field cmp lazyvim.util.cmp
local M = {} local M = {}
---@type table<string, string|string[]> ---@type table<string, string|string[]>

View file

@ -5,14 +5,14 @@ local M = {}
---@param opts? lsp.Client.filter ---@param opts? lsp.Client.filter
function M.get_clients(opts) function M.get_clients(opts)
local ret = {} ---@type lsp.Client[] local ret = {} ---@type vim.lsp.Client[]
if vim.lsp.get_clients then if vim.lsp.get_clients then
ret = vim.lsp.get_clients(opts) ret = vim.lsp.get_clients(opts)
else else
---@diagnostic disable-next-line: deprecated ---@diagnostic disable-next-line: deprecated
ret = vim.lsp.get_active_clients(opts) ret = vim.lsp.get_active_clients(opts)
if opts and opts.method then if opts and opts.method then
---@param client lsp.Client ---@param client vim.lsp.Client
ret = vim.tbl_filter(function(client) ret = vim.tbl_filter(function(client)
return client.supports_method(opts.method, { bufnr = opts.bufnr }) return client.supports_method(opts.method, { bufnr = opts.bufnr })
end, ret) end, ret)
@ -21,17 +21,81 @@ function M.get_clients(opts)
return opts and opts.filter and vim.tbl_filter(opts.filter, ret) or ret return opts and opts.filter and vim.tbl_filter(opts.filter, ret) or ret
end end
---@param on_attach fun(client:lsp.Client, buffer) ---@param on_attach fun(client:vim.lsp.Client, buffer)
function M.on_attach(on_attach) function M.on_attach(on_attach)
vim.api.nvim_create_autocmd("LspAttach", { return vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args) callback = function(args)
local buffer = args.buf ---@type number local buffer = args.buf ---@type number
local client = vim.lsp.get_client_by_id(args.data.client_id) local client = vim.lsp.get_client_by_id(args.data.client_id)
on_attach(client, buffer) if client then
return on_attach(client, buffer)
end
end, end,
}) })
end end
function M.setup_dynamic_capability()
local register_capability = vim.lsp.handlers["client/registerCapability"]
vim.lsp.handlers["client/registerCapability"] = function(err, res, ctx)
---@diagnostic disable-next-line: no-unknown
local ret = register_capability(err, res, ctx)
local client = vim.lsp.get_client_by_id(ctx.client_id)
local buffer = vim.api.nvim_get_current_buf()
if client then
vim.api.nvim_exec_autocmds("User", {
pattern = "LspDynamicCapability",
data = { client_id = client.id, buffer = buffer },
})
end
return ret
end
end
---@param fn fun(client:vim.lsp.Client, buffer):boolean?
---@param opts? {group?: integer}
function M.on_dynamic_capability(fn, opts)
return vim.api.nvim_create_autocmd("User", {
pattern = "LspDynamicCapability",
group = opts and opts.group or nil,
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
local buffer = args.data.buffer ---@type number
if client then
return fn(client, buffer)
end
end,
})
end
M._on_supports_method_id = 0
---@param method string
---@param fn fun(client:vim.lsp.Client, buffer)
function M.on_supports_method(method, fn)
M.on_attach(function(client, buffer)
if client.supports_method(method, { bufnr = buffer }) then
fn(client, buffer)
else
M._on_supports_method_id = M._on_supports_method_id + 1
local id = M._on_supports_method_id
local group = vim.api.nvim_create_augroup("on_supports_method_" .. id, { clear = true })
M.on_dynamic_capability(function(c, b)
if c == client and b == buffer and client.supports_method(method, { bufnr = buffer }) then
fn(client, buffer)
pcall(vim.api.nvim_del_augroup_by_id, group)
end
end, { group = group })
vim.api.nvim_create_autocmd({ "LspDetach", "BufDelete" }, {
group = group,
buffer = buffer,
callback = function()
pcall(vim.api.nvim_del_augroup_by_id, group)
end,
})
end
end)
end
---@param from string ---@param from string
---@param to string ---@param to string
function M.on_rename(from, to) function M.on_rename(from, to)
@ -89,12 +153,12 @@ function M.formatter(opts)
end, end,
sources = function(buf) sources = function(buf)
local clients = M.get_clients(LazyVim.merge({}, filter, { bufnr = buf })) local clients = M.get_clients(LazyVim.merge({}, filter, { bufnr = buf }))
---@param client lsp.Client ---@param client vim.lsp.Client
local ret = vim.tbl_filter(function(client) local ret = vim.tbl_filter(function(client)
return client.supports_method("textDocument/formatting") return client.supports_method("textDocument/formatting")
or client.supports_method("textDocument/rangeFormatting") or client.supports_method("textDocument/rangeFormatting")
end, clients) end, clients)
---@param client lsp.Client ---@param client vim.lsp.Client
return vim.tbl_map(function(client) return vim.tbl_map(function(client)
return client.name return client.name
end, ret) end, ret)
@ -143,10 +207,10 @@ function M.words.setup(opts)
return handler(err, result, ctx, config) return handler(err, result, ctx, config)
end end
M.on_attach(function(client, buf) M.on_supports_method("textDocument/documentHighlight", function(client, buf)
if client.supports_method("textDocument/documentHighlight") then local group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true })
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "CursorMoved", "CursorMovedI" }, { vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "CursorMoved", "CursorMovedI" }, {
group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true }), group = group,
buffer = buf, buffer = buf,
callback = function(ev) callback = function(ev)
if not M.words.at() then if not M.words.at() then
@ -158,7 +222,11 @@ function M.words.setup(opts)
end end
end, end,
}) })
end vim.api.nvim_create_autocmd("LspDetach", {
callback = function()
vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true })
end,
})
end) end)
end end