Closed Rishabh672003 closed 1 week ago
This appears to be an issue with the built-in snippet expansion and text edit utils. Do you mind reporting this upstream and referencing this issue? Reproducible via:
vim.snippet.expand('test(${1:ing})')
vim.lsp.util.apply_text_edits({
{
range = { start = { line = 0, character = 0 }, ['end'] = { line = 0, character = 0 } },
newText = 'hello world\n',
},
}, vim.api.nvim_get_current_buf(), 'utf-16')
@Saghen I have exams these days so really busy, will do it later when i have time
this doesnt happen with the builtin snippets expansion of the latest nightly
https://github.com/user-attachments/assets/79f625c0-b5dc-4270-861e-4e9b158235a2
@Saghen wait it still happens with nightly with blink.cmp, sorry if my previous comment was misleading
nvim -v : NVIM v0.11.0-dev-1045+gb922b7d6d
https://github.com/user-attachments/assets/9f7233cd-c434-4ab0-802a-fc78101c6b24
doesnt happen with default <C-x><C-o>
style snippets
https://github.com/user-attachments/assets/7e57803c-8fcd-48c3-80de-9ff395aacd1e
@Saghen I don't believe this is an issue with core. The problem here is that snippets should be expanded after text edits have been applied. I haven't debugged this plugin carefully but it seems that this accept
function applies additional text edits after expanding the snippet, hence the bug.
I would suggest taking a look at core's on_complete_done
function here for a reference on how to handle snippet expansion.
Yep, we apply additional text edits after because often times they must resolved from the LSP. I plan to add prefetching but there will still be cases where we have to wait on the LSP. But in general, I'm not sure I understand why the order should matter here, especially since other plugins could be adding lines after expansion triggers. You can reproduce this issue by adding any additional line to the buffer after the snippet expansion triggers.
vim.snippet.expand('test(${1:ing})')
vim.api.nvim_buf_set_lines(0, 0, 0, false, { 'hello world' })
Deferring the function prevents the issue
vim.snippet.expand('test(${1:ing})')
vim.defer_fn(function()
vim.api.nvim_buf_set_lines(0, 0, 0, false, { 'hello world' })
end, 100)
Yep, we apply additional text edits after because often times they must resolved from the LSP.
Yeah I know how LSP completion works. If you look at the function that I linked, the built-in completion implementation also has support for resolving text edits later and it still expands the snippet afterwards.
Also note that both built-in completion and nvim-cmp
(when using vim.snippet
) don't have the original problem described here, and so if other completion plugins using vim.snippet
don't have the bug, I think blink.cmp
is the one doing something incorrect.
vim.snippet.expand('test(${1:ing})')
vim.api.nvim_buf_set_lines(0, 0, 0, false, { 'hello world' })
Regarding this example, I dare to say this is by design. Snippet expansion starts a snippet session that depends on cursor movement and text insertion to update the relevant tabstops. I wouldn't be surprised if there's a timing problem with nvim_buf_set_lines
moving the cursor invalidating the state of the snippet session.
I'm happy to reopen the issue in Neovim and let other maintainers weigh in on whether this is something we should fix, but I believe that's a different problem and unrelated to the original bug in this issue.
@MariaSolOs Didn't mean to be disrespectful, sorry if it came off that way
@Rishabh672003 Resolved in https://github.com/Saghen/blink.cmp/commit/3927128e712806c22c20487ef0a1ed885bfec292 by always resolving before applying and prefetching.
I'll continue watching that neovim issue as I'd still like to fallback to resolving lazily if possible
last thing @Saghen can you make a new release please would make upgrading so much easier for me on mini.deps
@MariaSolOs Didn't mean to be disrespectful, sorry if it came off that way
Not at all. I also apologize if I sounded passive-aggressive (we're all passionate editor tinkerers 😅). I think this is a great plugin and I definitely want to make sure that the right code is fixed :)
As seen in the video, the insert starts at the wrong place because the completion has auto-import the header file.
https://github.com/user-attachments/assets/173a472d-b3ed-4693-bd48-b81ae4832f5d
My cofig: