summaryrefslogtreecommitdiffstats
path: root/.config/nvim/plugin/50-completion.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/nvim/plugin/50-completion.lua')
-rw-r--r--.config/nvim/plugin/50-completion.lua139
1 files changed, 0 insertions, 139 deletions
diff --git a/.config/nvim/plugin/50-completion.lua b/.config/nvim/plugin/50-completion.lua
index 620d9bd..caf749d 100644
--- a/.config/nvim/plugin/50-completion.lua
+++ b/.config/nvim/plugin/50-completion.lua
@@ -36,145 +36,6 @@ vim.keymap.set({ "i", "s" }, "<C-p>", function()
end, { expr = true })
------------------------------------------------------------------------------------------------------------------------
--- Snippet expansion fallback
-------------------------------------------------------------------------------------------------------------------------
--- Work around Neovim's snippet grammar rejecting placeholder defaults that mix text with nested tabstops (e.g. lua_ls's
--- `${1:pairs(${2:t})}`): the `any_or_text` rule matches a single node, not a `(any + text)^1` sequence. On parse failure,
--- strip the snippet markup and insert it as plain text instead of throwing. Remove once fixed upstream.
--- The `@as table` cast retypes the module here so overriding `expand` isn't flagged as a duplicate field set.
-local snippet = vim.snippet --[[@as table]]
-local orig_expand = snippet.expand
-
--- Reduce LSP snippet syntax to plain text: keep placeholder/variable defaults, the first choice, drop bare tabstops.
-local function strip_snippet(s)
- local prev
- repeat
- prev = s
- s = s:gsub("%$(%b{})", function(group)
- local body = group:sub(2, -2)
- local choice = body:match("^%d+|(.*)|$")
- if choice then
- return (choice:gsub(",.*$", "")) -- first choice
- end
- local default = body:match("^[%w_]+:(.*)$")
- if default then
- return default -- ${n:default} / ${VAR:default}
- end
- return "" -- bare ${n} / ${VAR}
- end)
- until s == prev
- s = s:gsub("%$[%w_]+", "") -- bare $n / $VAR
- s = s:gsub("\\([%$}{|,\\])", "%1") -- unescape
- return s
-end
-
-local function insert_plain(text)
- local win = vim.api.nvim_get_current_win()
- local row, col = unpack(vim.api.nvim_win_get_cursor(win))
- local indent = vim.api.nvim_get_current_line():match("^%s*") or ""
- local lines = vim.split(text, "\n", { plain = true })
- for i = 2, #lines do
- lines[i] = indent .. lines[i]
- end
- vim.api.nvim_buf_set_text(0, row - 1, col, row - 1, col, lines)
- local last = #lines
- local new_row = row - 1 + (last - 1)
- local new_col = last == 1 and col + #lines[1] or #lines[last]
- vim.api.nvim_win_set_cursor(win, { new_row + 1, new_col })
-end
-
-snippet.expand = function(input)
- local ok = pcall(orig_expand, input)
- if not ok then
- insert_plain(strip_snippet(input))
- vim.notify(
- "Snippet parse failed, inserted as plain text: " .. vim.inspect(input),
- vim.log.levels.WARN
- )
- end
-end
-
-------------------------------------------------------------------------------------------------------------------------
--- Snippet completion source
-------------------------------------------------------------------------------------------------------------------------
--- Exposes `vim.b.snippets` (trigger word -> LSP snippet body) as a 'complete' function source. A filetype opts in from
--- its ftplugin by setting `vim.b.snippets`, pointing 'completefunc' at this function, and appending "F" to 'complete'.
--- Must be a global so `v:lua` can reach it; see `:help complete-functions` and `:help v:lua-call`.
-
--- Render a snippet to preview text: resolve placeholders and their mirrors to the placeholder's default value.
-local function render_snippet(s)
- local defaults = {}
- for n, d in s:gmatch("%${(%d+):([^{}]*)}") do
- defaults[n] = d
- end
- local prev
- repeat
- prev = s
- s = s:gsub("%$(%b{})", function(group)
- local body = group:sub(2, -2)
- local choice = body:match("^%d+|(.*)|$")
- if choice then
- return (choice:gsub(",.*$", "")) -- first choice
- end
- local default = body:match("^[%w_]+:(.*)$")
- if default then
- return default -- ${n:default} / ${VAR:default}
- end
- return defaults[body] or "" -- ${n} / ${VAR}
- end)
- until s == prev
- s = s:gsub("%$(%d+)", function(n)
- return defaults[n] or "" -- $n mirror
- end)
- s = s:gsub("%$[%w_]+", "") -- bare $VAR
- s = s:gsub("\\([%$}{|,\\])", "%1") -- unescape
- return s
-end
-
-function _G.dotfiles_snippet_source(findstart, base)
- local snippets = vim.b.snippets or {}
- local line = vim.api.nvim_get_current_line()
- local col = vim.api.nvim_win_get_cursor(0)[2]
- if findstart == 1 then
- -- Walk back over trigger characters to find the range the match replaces.
- local start = col
- while start > 0 and line:sub(start, start):match("[%w_]") do
- start = start - 1
- end
- return start
- end
- local items = {}
- for trigger, body in pairs(snippets) do
- if vim.startswith(trigger, base) then
- items[#items + 1] = {
- word = trigger,
- kind = "Snippet",
- menu = "[snippet]",
- info = render_snippet(body),
- user_data = { snippet = body },
- }
- end
- end
- return items
-end
-
--- Expand the snippet once one of the items above is accepted (its trigger word is inserted first, so remove it).
-vim.api.nvim_create_autocmd("CompleteDone", {
- desc = "Expand accepted snippet completion",
- group = vim.g.dotfiles.augroup,
- callback = function()
- local item = vim.v.completed_item
- local data = item.user_data
- if type(data) ~= "table" or not data.snippet then
- return
- end
- local row, col = unpack(vim.api.nvim_win_get_cursor(0))
- vim.api.nvim_buf_set_text(0, row - 1, col - #item.word, row - 1, col, { "" })
- vim.snippet.expand(data.snippet)
- end,
-})
-
-------------------------------------------------------------------------------------------------------------------------
-- Command-line mode completion
------------------------------------------------------------------------------------------------------------------------
-- See `:help cmdline-completion` and `:help cmdline-autocompletion`