From 76033c6aa92e633de968b515d3fd5f9e0447a74f Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 21:12:51 +0200 Subject: [PATCH 01/12] fix(config): add some extra LazyVim keys to lazy health --- lua/lazyvim/config/init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua index d990f94d..62b14237 100644 --- a/lua/lazyvim/config/init.lua +++ b/lua/lazyvim/config/init.lua @@ -191,6 +191,13 @@ function M.setup(opts) vim.cmd([[Lazy! load all]]) vim.cmd([[checkhealth]]) end, { desc = "Load all plugins and run :checkhealth" }) + + local health = require("lazy.health") + vim.list_extend(health.valid, { + "recommended", + "desc", + "vscode", + }) end, }) From c264253d8fd4f068c7c2ddb5ea3c63596ab5d23f Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 21:23:49 +0200 Subject: [PATCH 02/12] feat(toml): also recommend toml when theres toml files in the cwd --- lua/lazyvim/plugins/extras/lang/toml.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/lazyvim/plugins/extras/lang/toml.lua b/lua/lazyvim/plugins/extras/lang/toml.lua index 03ec5029..9dcc029d 100644 --- a/lua/lazyvim/plugins/extras/lang/toml.lua +++ b/lua/lazyvim/plugins/extras/lang/toml.lua @@ -2,6 +2,7 @@ return { recommended = function() return LazyVim.extras.wants({ ft = "toml", + root = "*.toml", }) end, { From 57a31c3920bcb9baec9a6d3915506a638b0801b8 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 21:24:23 +0200 Subject: [PATCH 03/12] fix(cmp): no need to setup native snippets with latest cmp --- lua/lazyvim/plugins/coding.lua | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lua/lazyvim/plugins/coding.lua b/lua/lazyvim/plugins/coding.lua index 9a3f674a..19f5dfff 100644 --- a/lua/lazyvim/plugins/coding.lua +++ b/lua/lazyvim/plugins/coding.lua @@ -112,11 +112,6 @@ return { { "garymjr/nvim-snippets", opts = { friendly_snippets = true } }, }, opts = function(_, opts) - opts.snippet = { - expand = function(args) - vim.snippet.expand(args.body) - end, - } table.insert(opts.sources, { name = "snippets" }) end, keys = { From 39f3ebcadf49b285d8ae06270ed0c2098e7f03bd Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 21:46:54 +0200 Subject: [PATCH 04/12] feat(cmp): move cmp autobracket support to util class --- lua/lazyvim/plugins/coding.lua | 15 ++------------- lua/lazyvim/util/cmp.lua | 19 +++++++++++++++++++ lua/lazyvim/util/init.lua | 1 + 3 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 lua/lazyvim/util/cmp.lua diff --git a/lua/lazyvim/plugins/coding.lua b/lua/lazyvim/plugins/coding.lua index 19f5dfff..6c349732 100644 --- a/lua/lazyvim/plugins/coding.lua +++ b/lua/lazyvim/plugins/coding.lua @@ -83,21 +83,10 @@ return { source.group_index = source.group_index or 1 end local cmp = require("cmp") - local Kind = cmp.lsp.CompletionItemKind cmp.setup(opts) cmp.event:on("confirm_done", function(event) - if not vim.tbl_contains(opts.auto_brackets or {}, vim.bo.filetype) then - return - 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("()", false, false, true) - vim.api.nvim_feedkeys(keys, "i", true) - end + if vim.tbl_contains(opts.auto_brackets or {}, vim.bo.filetype) then + LazyVim.cmp.auto_brackets(event.entry) end end) end, diff --git a/lua/lazyvim/util/cmp.lua b/lua/lazyvim/util/cmp.lua new file mode 100644 index 00000000..a075f0cb --- /dev/null +++ b/lua/lazyvim/util/cmp.lua @@ -0,0 +1,19 @@ +---@class lazyvim.util.cmp +local M = {} + +---@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("()", false, false, true) + vim.api.nvim_feedkeys(keys, "i", true) + end + end +end + +return M diff --git a/lua/lazyvim/util/init.lua b/lua/lazyvim/util/init.lua index 433efda8..c36ef101 100644 --- a/lua/lazyvim/util/init.lua +++ b/lua/lazyvim/util/init.lua @@ -17,6 +17,7 @@ local LazyUtil = require("lazy.core.util") ---@field json lazyvim.util.json ---@field lualine lazyvim.util.lualine ---@field mini lazyvim.util.mini +---@field cmp lazyvim.util.cmp local M = {} ---@type table From 24a2a9fb0ba60e0e7c6c8c4ee95a5db7ea0e123e Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 21:47:42 +0200 Subject: [PATCH 05/12] feat(cmp): add missing documentation to snippets when needed --- lua/lazyvim/plugins/coding.lua | 3 +++ lua/lazyvim/util/cmp.lua | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lua/lazyvim/plugins/coding.lua b/lua/lazyvim/plugins/coding.lua index 6c349732..4acd5b3b 100644 --- a/lua/lazyvim/plugins/coding.lua +++ b/lua/lazyvim/plugins/coding.lua @@ -89,6 +89,9 @@ return { LazyVim.cmp.auto_brackets(event.entry) end end) + cmp.event:on("menu_opened", function(event) + LazyVim.cmp.add_missing_snippet_docs(event.window) + end) end, }, diff --git a/lua/lazyvim/util/cmp.lua b/lua/lazyvim/util/cmp.lua index a075f0cb..037f48e6 100644 --- a/lua/lazyvim/util/cmp.lua +++ b/lua/lazyvim/util/cmp.lua @@ -16,4 +16,24 @@ function M.auto_brackets(entry) 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, item.insertText), + } + end + end + end +end + return M From 2961162ebaef96e4ffbc1e6c97dba0dc32efbbb0 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 22:46:09 +0200 Subject: [PATCH 06/12] fix(cmp): use better cmp.confirm --- lua/lazyvim/plugins/coding.lua | 15 ++------------- lua/lazyvim/util/cmp.lua | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lua/lazyvim/plugins/coding.lua b/lua/lazyvim/plugins/coding.lua index 4acd5b3b..b754eaf6 100644 --- a/lua/lazyvim/plugins/coding.lua +++ b/lua/lazyvim/plugins/coding.lua @@ -36,19 +36,8 @@ return { [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping.complete(), [""] = cmp.mapping.abort(), - [""] = function(fallback) - if cmp.core.view:visible() or vim.fn.pumvisible() == 1 then - LazyVim.create_undo() - if cmp.confirm({ select = true }) then - return - end - end - return fallback() - end, - [""] = cmp.mapping.confirm({ - behavior = cmp.ConfirmBehavior.Replace, - select = true, - }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = LazyVim.cmp.confirm(), + [""] = LazyVim.cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. [""] = function(fallback) cmp.abort() fallback() diff --git a/lua/lazyvim/util/cmp.lua b/lua/lazyvim/util/cmp.lua index 037f48e6..3343245a 100644 --- a/lua/lazyvim/util/cmp.lua +++ b/lua/lazyvim/util/cmp.lua @@ -36,4 +36,25 @@ function M.add_missing_snippet_docs(window) 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 return M From 7d72436193b3624a9198a5e57ec1bd7e90260c00 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 22:47:13 +0200 Subject: [PATCH 07/12] feat(cmp): resolve placeholders in generated missing snippet documentation --- lua/lazyvim/util/cmp.lua | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lua/lazyvim/util/cmp.lua b/lua/lazyvim/util/cmp.lua index 3343245a..64c43f0a 100644 --- a/lua/lazyvim/util/cmp.lua +++ b/lua/lazyvim/util/cmp.lua @@ -1,6 +1,23 @@ ---@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 + ---@param entry cmp.Entry function M.auto_brackets(entry) local cmp = require("cmp") @@ -29,7 +46,7 @@ function M.add_missing_snippet_docs(window) 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, item.insertText), + value = string.format("```%s\n%s\n```", vim.bo.filetype, M.snippet_resolve(item.insertText)), } end end From 97862f425997bf89f581e6aeceed9aac85d90432 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 19 May 2024 22:48:01 +0200 Subject: [PATCH 08/12] feat(cmp): better error handling and automatic fixing of snippets that fail to parse with native Neovim snippets --- lua/lazyvim/plugins/coding.lua | 5 +++++ lua/lazyvim/util/cmp.lua | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lua/lazyvim/plugins/coding.lua b/lua/lazyvim/plugins/coding.lua index b754eaf6..589e4b1c 100644 --- a/lua/lazyvim/plugins/coding.lua +++ b/lua/lazyvim/plugins/coding.lua @@ -93,6 +93,11 @@ return { { "garymjr/nvim-snippets", opts = { friendly_snippets = true } }, }, opts = function(_, opts) + opts.snippet = { + expand = function(item) + return LazyVim.cmp.expand(item.body) + end, + } table.insert(opts.sources, { name = "snippets" }) end, keys = { diff --git a/lua/lazyvim/util/cmp.lua b/lua/lazyvim/util/cmp.lua index 64c43f0a..d0e5b48f 100644 --- a/lua/lazyvim/util/cmp.lua +++ b/lua/lazyvim/util/cmp.lua @@ -18,6 +18,13 @@ function M.snippet_resolve(snippet) 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") @@ -74,4 +81,23 @@ function M.confirm(opts) 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 From 20e002f9f0e9bfdff1ffc638987fbd46b31e5f9b Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Mon, 20 May 2024 00:08:05 +0200 Subject: [PATCH 09/12] feat(lsp): properly update certain Neovim functionlity based on dynamic capabilities. See #3244. Fixes #3246 --- lua/lazyvim/plugins/lsp/init.lua | 33 ++++------- lua/lazyvim/util/lsp.lua | 97 ++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 45 deletions(-) diff --git a/lua/lazyvim/plugins/lsp/init.lua b/lua/lazyvim/plugins/lsp/init.lua index 3a6ae964..f99c997c 100644 --- a/lua/lazyvim/plugins/lsp/init.lua +++ b/lua/lazyvim/plugins/lsp/init.lua @@ -121,16 +121,8 @@ return { require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer) end) - 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() - require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer) - return ret - end + LazyVim.lsp.setup_dynamic_capability() + LazyVim.lsp.on_dynamic_capability(require("lazyvim.plugins.lsp.keymaps").on_attach) LazyVim.lsp.words.setup(opts.document_highlight) @@ -148,24 +140,19 @@ return { if vim.fn.has("nvim-0.10") == 1 then -- inlay hints if opts.inlay_hints.enabled then - LazyVim.lsp.on_attach(function(client, buffer) - if client.supports_method("textDocument/inlayHint") then - LazyVim.toggle.inlay_hints(buffer, true) - end + LazyVim.lsp.on_supports_method("textDocument/inlayHint", function(client, buffer) + LazyVim.toggle.inlay_hints(buffer, true) end) end -- code lens if opts.codelens.enabled and vim.lsp.codelens then - LazyVim.lsp.on_attach(function(client, buffer) - if client.supports_method("textDocument/codeLens") then - vim.lsp.codelens.refresh() - --- autocmd BufEnter,CursorHold,InsertLeave lua vim.lsp.codelens.refresh() - vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { - buffer = buffer, - callback = vim.lsp.codelens.refresh, - }) - end + LazyVim.lsp.on_supports_method("textDocument/codeLens", function(client, buffer) + vim.lsp.codelens.refresh() + vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { + buffer = buffer, + callback = vim.lsp.codelens.refresh, + }) end) end end diff --git a/lua/lazyvim/util/lsp.lua b/lua/lazyvim/util/lsp.lua index e2eb82de..e7a1c026 100644 --- a/lua/lazyvim/util/lsp.lua +++ b/lua/lazyvim/util/lsp.lua @@ -5,14 +5,14 @@ local M = {} ---@param opts? lsp.Client.filter function M.get_clients(opts) - local ret = {} ---@type lsp.Client[] + local ret = {} ---@type vim.lsp.Client[] if vim.lsp.get_clients then ret = vim.lsp.get_clients(opts) else ---@diagnostic disable-next-line: deprecated ret = vim.lsp.get_active_clients(opts) if opts and opts.method then - ---@param client lsp.Client + ---@param client vim.lsp.Client ret = vim.tbl_filter(function(client) return client.supports_method(opts.method, { bufnr = opts.bufnr }) end, ret) @@ -21,17 +21,66 @@ function M.get_clients(opts) return opts and opts.filter and vim.tbl_filter(opts.filter, ret) or ret end ----@param on_attach fun(client:lsp.Client, buffer) +---@param on_attach fun(client:vim.lsp.Client, buffer) function M.on_attach(on_attach) - vim.api.nvim_create_autocmd("LspAttach", { + return vim.api.nvim_create_autocmd("LspAttach", { callback = function(args) local buffer = args.buf ---@type number 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 +M._dynamic_handlers = {} ---@type fun(client:vim.lsp.Client, buffer)[] + +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 + M._dynamic_handlers = vim.tbl_filter(function(handler) + return handler(client, buffer) ~= false + end, M._dynamic_handlers) + end + return ret + end +end + +---@param fn fun(client:vim.lsp.Client, buffer) +function M.on_dynamic_capability(fn) + table.insert(M._dynamic_handlers, fn) +end + +---@type table>> +M._on_supports_method = {} + +---@param method string +---@param fn fun(client:vim.lsp.Client, buffer) +function M.on_supports_method(method, fn) + M._on_supports_method[method] = M._on_supports_method[method] or setmetatable({}, { __mode = "k" }) + + ---@param client vim.lsp.Client + local function check(client, buffer) + M._on_supports_method[method][client] = M._on_supports_method[method][client] or {} + if M._on_supports_method[method][client][buffer] then + return + end + if client.supports_method(method, { bufnr = buffer }) then + M._on_supports_method[method][client][buffer] = true + fn(client, buffer) + end + end + M.on_attach(check) + M.on_dynamic_capability(check) +end + ---@param from string ---@param to string function M.on_rename(from, to) @@ -89,12 +138,12 @@ function M.formatter(opts) end, sources = function(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) return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting") end, clients) - ---@param client lsp.Client + ---@param client vim.lsp.Client return vim.tbl_map(function(client) return client.name end, ret) @@ -143,22 +192,26 @@ function M.words.setup(opts) return handler(err, result, ctx, config) end - M.on_attach(function(client, buf) - if client.supports_method("textDocument/documentHighlight") then - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "CursorMoved", "CursorMovedI" }, { - group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true }), - buffer = buf, - callback = function(ev) - if not M.words.at() then - if ev.event:find("CursorMoved") then - vim.lsp.buf.clear_references() - else - vim.lsp.buf.document_highlight() - end + M.on_supports_method("textDocument/documentHighlight", function(client, buf) + local group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true }) + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "CursorMoved", "CursorMovedI" }, { + group = group, + buffer = buf, + callback = function(ev) + if not M.words.at() then + if ev.event:find("CursorMoved") then + vim.lsp.buf.clear_references() + else + vim.lsp.buf.document_highlight() 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 From 32f000754f8718a8ef1d16e14339bc0a3859d7eb Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Mon, 20 May 2024 00:13:18 +0200 Subject: [PATCH 10/12] docs: readme should be unix format. Fixes #3247 --- README-DE.md | 276 +++++++++++++++++++++++++-------------------------- 1 file changed, 138 insertions(+), 138 deletions(-) diff --git a/README-DE.md b/README-DE.md index f5a05985..a9522c84 100644 --- a/README-DE.md +++ b/README-DE.md @@ -1,138 +1,138 @@ -
- -
- -
- -

- Installieren - · - Konfigurieren - · - Dokumentation -

- - - -LazyVim ist ein Neovim-Setup aufgebaut auf [💤 lazy.nvim](https://github.com/folke/lazy.nvim). -Es erleichtert das Anpassen und Erweitern von Ihrer Konfiguration. -Anstatt von vorne anzufangen oder eine vorgefertigte Distro zu verwenden, gibt LazyVim das beste aus -beiden Welten - die Flexibilität Ihre Konfiguration zu verändern und einzustellen wie Sie es wollen -und die Einfachheit von einem vorgefertigten Setup. - -![image](https://user-images.githubusercontent.com/292349/213447056-92290767-ea16-430c-8727-ce994c93e9cc.png) - -![image](https://user-images.githubusercontent.com/292349/211285846-0b7bb3bf-0462-4029-b64c-4ee1d037fc1c.png) - -## ✨ Features - -- 🔥 Transformiere dein Neovim in eine komplette IDE -- 💤 Passe deine Konfiguration einfach an und erweitere diese mit [lazy.nvim](https://github.com/folke/lazy.nvim) -- 🚀 Extrem schnell -- 🧹 Logische Voreinstellungen für optionen, autocmds und keymaps -- 📦 Kommt mit einem Haufen vorkonfigurierter, ready-to-use Plugins - -## ⚡️ Vorraussetzungen - -- Neovim >= **0.8.0** (gebraucht um mit **LuaJIT** zu bauen) -- Git >= **2.19.0** (um Teil-Klone zu unterstützen) -- eine [Nerd Font](https://www.nerdfonts.com/) **_(optional)_** - -## 🚀 Einstieg - -Sie können eine Startvorlage für **LazyVim** [hier](https://github.com/LazyVim/starter) finden - -
Versuchen Sie's mit Docker - -```sh -docker run -w /root -it --rm alpine:edge sh -uelic ' - apk add git lazygit neovim ripgrep alpine-sdk --update - git clone https://github.com/LazyVim/starter ~/.config/nvim - cd ~/.config/nvim - nvim -' -``` - -
- -
Installieren von LazyVim Starter - -- Neovim Files sichern: - - ```sh - mv ~/.config/nvim ~/.config/nvim.bak - mv ~/.local/share/nvim ~/.local/share/nvim.bak - ``` - -- Den Starter Klonen: - - ```sh - git clone https://github.com/LazyVim/starter ~/.config/nvim - ``` - -- Den `.git` Folder löschen, um die Konfiguration zu einer eigenen distro hinzuzufügen: - - ```sh - rm -rf ~/.config/nvim/.git - ``` - -- Neovim starten! - - ```sh - nvim - ``` - - Refer to the comments in the files on how to customize **LazyVim**. - -
- -## 📂 Dateistruktur - -Die Dateien unter `config` werden automatisch und zur richtigen Zeit geladen, -sodass ein manuelles `require` nicht nötig ist. -**LazyVim** bringt Konfigurationsdatein mit, die **_vor_** Ihren eigenen geladen werden - -siehe [hier](https://github.com/LazyVim/LazyVim/tree/main/lua/lazyvim/config) -Sie können eigene Plugins unter `lua/plugins/` hinzufügen. Alle Dateien innerhalb -dieses Ordners werden automatisch mit [lazy.nvim](https://github.com/folke/lazy.nvim) -geladen. - -
-~/.config/nvim
-├── lua
-│   ├── config
-│   │   ├── autocmds.lua
-│   │   ├── keymaps.lua
-│   │   ├── lazy.lua
-│   │   └── options.lua
-│   └── plugins
-│       ├── spec1.lua
-│       ├── **
-│       └── spec2.lua
-└── init.toml
-
- -## ⚙️ Konfiguration - -Siehe [Dokumentation](https://lazyvim.github.io). +
+ +
+ +
+ +

+ Installieren + · + Konfigurieren + · + Dokumentation +

+ + + +LazyVim ist ein Neovim-Setup aufgebaut auf [💤 lazy.nvim](https://github.com/folke/lazy.nvim). +Es erleichtert das Anpassen und Erweitern von Ihrer Konfiguration. +Anstatt von vorne anzufangen oder eine vorgefertigte Distro zu verwenden, gibt LazyVim das beste aus +beiden Welten - die Flexibilität Ihre Konfiguration zu verändern und einzustellen wie Sie es wollen +und die Einfachheit von einem vorgefertigten Setup. + +![image](https://user-images.githubusercontent.com/292349/213447056-92290767-ea16-430c-8727-ce994c93e9cc.png) + +![image](https://user-images.githubusercontent.com/292349/211285846-0b7bb3bf-0462-4029-b64c-4ee1d037fc1c.png) + +## ✨ Features + +- 🔥 Transformiere dein Neovim in eine komplette IDE +- 💤 Passe deine Konfiguration einfach an und erweitere diese mit [lazy.nvim](https://github.com/folke/lazy.nvim) +- 🚀 Extrem schnell +- 🧹 Logische Voreinstellungen für optionen, autocmds und keymaps +- 📦 Kommt mit einem Haufen vorkonfigurierter, ready-to-use Plugins + +## ⚡️ Vorraussetzungen + +- Neovim >= **0.8.0** (gebraucht um mit **LuaJIT** zu bauen) +- Git >= **2.19.0** (um Teil-Klone zu unterstützen) +- eine [Nerd Font](https://www.nerdfonts.com/) **_(optional)_** + +## 🚀 Einstieg + +Sie können eine Startvorlage für **LazyVim** [hier](https://github.com/LazyVim/starter) finden + +
Versuchen Sie's mit Docker + +```sh +docker run -w /root -it --rm alpine:edge sh -uelic ' + apk add git lazygit neovim ripgrep alpine-sdk --update + git clone https://github.com/LazyVim/starter ~/.config/nvim + cd ~/.config/nvim + nvim +' +``` + +
+ +
Installieren von LazyVim Starter + +- Neovim Files sichern: + + ```sh + mv ~/.config/nvim ~/.config/nvim.bak + mv ~/.local/share/nvim ~/.local/share/nvim.bak + ``` + +- Den Starter Klonen: + + ```sh + git clone https://github.com/LazyVim/starter ~/.config/nvim + ``` + +- Den `.git` Folder löschen, um die Konfiguration zu einer eigenen distro hinzuzufügen: + + ```sh + rm -rf ~/.config/nvim/.git + ``` + +- Neovim starten! + + ```sh + nvim + ``` + + Refer to the comments in the files on how to customize **LazyVim**. + +
+ +## 📂 Dateistruktur + +Die Dateien unter `config` werden automatisch und zur richtigen Zeit geladen, +sodass ein manuelles `require` nicht nötig ist. +**LazyVim** bringt Konfigurationsdatein mit, die **_vor_** Ihren eigenen geladen werden - +siehe [hier](https://github.com/LazyVim/LazyVim/tree/main/lua/lazyvim/config) +Sie können eigene Plugins unter `lua/plugins/` hinzufügen. Alle Dateien innerhalb +dieses Ordners werden automatisch mit [lazy.nvim](https://github.com/folke/lazy.nvim) +geladen. + +
+~/.config/nvim
+├── lua
+│   ├── config
+│   │   ├── autocmds.lua
+│   │   ├── keymaps.lua
+│   │   ├── lazy.lua
+│   │   └── options.lua
+│   └── plugins
+│       ├── spec1.lua
+│       ├── **
+│       └── spec2.lua
+└── init.toml
+
+ +## ⚙️ Konfiguration + +Siehe [Dokumentation](https://lazyvim.github.io). From 69751cf417504cb57fef040703236bd4fd6a9a79 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Mon, 20 May 2024 00:35:52 +0200 Subject: [PATCH 11/12] refactor(lsp): refactored on_supports_method --- lua/lazyvim/util/lsp.lua | 48 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/lua/lazyvim/util/lsp.lua b/lua/lazyvim/util/lsp.lua index e7a1c026..756b1864 100644 --- a/lua/lazyvim/util/lsp.lua +++ b/lua/lazyvim/util/lsp.lua @@ -34,51 +34,53 @@ function M.on_attach(on_attach) }) end -M._dynamic_handlers = {} ---@type fun(client:vim.lsp.Client, buffer)[] - 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 - M._dynamic_handlers = vim.tbl_filter(function(handler) - return handler(client, buffer) ~= false - end, M._dynamic_handlers) + 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) -function M.on_dynamic_capability(fn) - table.insert(M._dynamic_handlers, fn) +---@param buf? number +function M.on_dynamic_capability(fn, buf) + vim.api.nvim_create_autocmd("User", { + pattern = "LspDynamicCapability", + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + local buffer = args.data.buffer ---@type number + if client and (buf == nil or buf == buffer) then + return fn(client, buffer) + end + end, + }) end ----@type table>> -M._on_supports_method = {} - ---@param method string ---@param fn fun(client:vim.lsp.Client, buffer) function M.on_supports_method(method, fn) - M._on_supports_method[method] = M._on_supports_method[method] or setmetatable({}, { __mode = "k" }) - - ---@param client vim.lsp.Client - local function check(client, buffer) - M._on_supports_method[method][client] = M._on_supports_method[method][client] or {} - if M._on_supports_method[method][client][buffer] then - return - end + M.on_attach(function(client, buffer) if client.supports_method(method, { bufnr = buffer }) then - M._on_supports_method[method][client][buffer] = true fn(client, buffer) + else + M.on_dynamic_capability(function() + if client.supports_method(method, { bufnr = buffer }) then + fn(client, buffer) + return false + end + end, buffer) end - end - M.on_attach(check) - M.on_dynamic_capability(check) + end) end ---@param from string From ac092289f506052cfdd1879f462be05075fe3081 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Mon, 20 May 2024 00:53:23 +0200 Subject: [PATCH 12/12] refactor(lsp): prevent autocmd leaks --- lua/lazyvim/util/lsp.lua | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/lua/lazyvim/util/lsp.lua b/lua/lazyvim/util/lsp.lua index 756b1864..af04b1c4 100644 --- a/lua/lazyvim/util/lsp.lua +++ b/lua/lazyvim/util/lsp.lua @@ -51,21 +51,24 @@ function M.setup_dynamic_capability() end end ----@param fn fun(client:vim.lsp.Client, buffer) ----@param buf? number -function M.on_dynamic_capability(fn, buf) - vim.api.nvim_create_autocmd("User", { +---@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 and (buf == nil or buf == buffer) then + 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) @@ -73,12 +76,22 @@ function M.on_supports_method(method, fn) if client.supports_method(method, { bufnr = buffer }) then fn(client, buffer) else - M.on_dynamic_capability(function() - if client.supports_method(method, { bufnr = buffer }) then + 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) - return false + pcall(vim.api.nvim_del_augroup_by_id, group) end - end, buffer) + 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