Skip to content

Commit d3e8701

Browse files
committed
feat: place cursor at first tab stop on snippet preview
1 parent 7f5a3d9 commit d3e8701

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

lua/blink/cmp/accept/preview.lua

+16-6
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,30 @@ local function preview(item, previous_text_edit)
33
local text_edits_lib = require('blink.cmp.accept.text-edits')
44
local text_edit = text_edits_lib.get_from_item(item)
55

6+
-- with auto_insert, we may have to undo the previous preview
7+
if previous_text_edit ~= nil then text_edit.range = text_edits_lib.get_undo_text_edit_range(previous_text_edit) end
8+
69
-- for snippets, expand them with the default property names
10+
local cursor_pos = {
11+
text_edit.range.start.line + 1,
12+
text_edit.range.start.character + #text_edit.newText,
13+
}
714
if item.insertTextFormat == vim.lsp.protocol.InsertTextFormat.Snippet then
815
local expanded_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(text_edit.newText)
916
text_edit.newText = expanded_snippet and tostring(expanded_snippet) or text_edit.newText
10-
end
1117

12-
if previous_text_edit ~= nil then text_edit.range = text_edits_lib.get_undo_text_edit_range(previous_text_edit) end
18+
-- place the cursor at the first tab stop
19+
local tabstops = require('blink.cmp.sources.snippets.utils').get_tab_stops(text_edit.newText)
20+
if tabstops and #tabstops > 0 then
21+
cursor_pos[1] = text_edit.range.start.line + tabstops[1].line
22+
cursor_pos[2] = text_edit.range.start.character + tabstops[1].character
23+
end
24+
end
1325

1426
text_edits_lib.apply_text_edits(item.client_id, { text_edit })
15-
vim.api.nvim_win_set_cursor(0, {
16-
text_edit.range.start.line + 1,
17-
text_edit.range.start.character + #text_edit.newText,
18-
})
27+
vim.api.nvim_win_set_cursor(0, cursor_pos)
1928

29+
-- return so that it can be undone in the future
2030
return text_edit
2131
end
2232

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

+23
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,27 @@ function utils.read_snippet(snippet, fallback)
5858
return snippets
5959
end
6060

61+
function utils.get_tab_stops(snippet)
62+
local expanded_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(snippet)
63+
if not expanded_snippet then return end
64+
65+
local tabstops = {}
66+
local grammar = require('vim.lsp._snippet_grammar')
67+
local line = 1
68+
local character = 1
69+
for _, child in ipairs(expanded_snippet.data.children) do
70+
local lines = tostring(child) == '' and {} or vim.split(tostring(child), '\n')
71+
line = line + math.max(#lines - 1, 0)
72+
character = #lines == 0 and character or #lines > 1 and #lines[#lines] or (character + #lines[#lines])
73+
vim.print('Line: ' .. line .. ' Character: ' .. character)
74+
if child.type == grammar.NodeType.Placeholder or child.type == grammar.NodeType.Tabstop then
75+
vim.print(child)
76+
table.insert(tabstops, { index = child.data.tabstop, line = line, character = character })
77+
end
78+
end
79+
80+
table.sort(tabstops, function(a, b) return a.index < b.index end)
81+
return tabstops
82+
end
83+
6184
return utils

0 commit comments

Comments
 (0)