Skip to content

Commit 2cf21ff

Browse files
committed
fix(snippets): filter out incompatible builtin snippets
Skip early incompatible builtin snippets using LSP grammar. Closes #2028
1 parent 230ccf8 commit 2cf21ff

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

lua/blink/cmp/sources/snippets/utils.lua

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,35 @@ function utils.safe_parse(input)
3838
return parsed
3939
end
4040

41+
---@param body string|string[]
42+
---@return string|string[]|nil
43+
function utils.parse_body(body)
44+
if type(body) == 'table' then body = table.concat(body, '\n') end
45+
46+
-- TODO: Try to fix them, whenever it's possible
47+
48+
-- Escape \ in options
49+
body = body:gsub(
50+
'(%${%d+|)(.-)(|})',
51+
function(start, options, ending) return start .. options:gsub('\\', '\\\\') .. ending end
52+
)
53+
54+
-- Now validate the snippet, discard if parsing fails
55+
if not utils.safe_parse(body) then return nil end
56+
57+
if body:find('\n') then body = vim.split(body, '\n', { plain = true }) end
58+
59+
return body
60+
end
61+
4162
---@type fun(snippet: blink.cmp.Snippet, fallback: string): table
4263
function utils.read_snippet(snippet, fallback)
4364
local snippets = {}
4465
local prefix = snippet.prefix or fallback
4566
local description = snippet.description or fallback
46-
local body = snippet.body
67+
68+
local body = utils.parse_body(snippet.body)
69+
if body == nil then return {} end
4770

4871
if type(description) == 'table' then description = vim.fn.join(description, '') end
4972

@@ -90,25 +113,4 @@ function utils.add_current_line_indentation(text)
90113
return table.concat(lines, '\n')
91114
end
92115

93-
function utils.get_tab_stops(snippet)
94-
local expanded_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(snippet)
95-
if not expanded_snippet then return end
96-
97-
local tabstops = {}
98-
local grammar = require('vim.lsp._snippet_grammar')
99-
local line = 1
100-
local character = 1
101-
for _, child in ipairs(expanded_snippet.data.children) do
102-
local lines = tostring(child) == '' and {} or vim.split(tostring(child), '\n')
103-
line = line + math.max(#lines - 1, 0)
104-
character = #lines == 0 and character or #lines > 1 and #lines[#lines] or (character + #lines[#lines])
105-
if child.type == grammar.NodeType.Placeholder or child.type == grammar.NodeType.Tabstop then
106-
table.insert(tabstops, { index = child.data.tabstop, line = line, character = character })
107-
end
108-
end
109-
110-
table.sort(tabstops, function(a, b) return a.index < b.index end)
111-
return tabstops
112-
end
113-
114116
return utils

0 commit comments

Comments
 (0)