LuaSnip
LuaSnip copied to clipboard
include in C will add > or "
https://user-images.githubusercontent.com/97107165/185115434-43060269-861b-4164-8360-a455682467b4.mp4
That seems to be caused by lsp.. Are you using clangd? I think it comes with an include
-snippet without this quirk
Yes, i'm using clangd, clangd completion and snippetd completion have the same problem :( , is there any ways can fix this strange problem?
Mhmm, I don't experience this issue, what args are you passing to clangd, what version is it?
lspconfig.clangd.setup {
on_attach = M.on_attach,
capabilities = M.capabilities,
single_file_support = true,
}
~/.c/n/l/LSP [ clangd --version ] 09:35:38 PM
clangd version 14.0.6
Features: linux
Platform: x86_64-pc-linux-gnu
btw, my clangd autoformat always make indent = 2, is there any ways can let it autoformat indent = 4?
Oh, if autoformat is enabled, that's probably it.
I think there's a global config somewhere, would be surprised if such stuff can't be changed in there.
Maybe clangd also respects editorconfig
Clangd is sending the completion items with the matching quote/bracket. I have tried working around this by conditionally inserting "
or >
with a match node but I would sometimes end up with single "
or >
s that were really hard to delete (e.g. when deleting the include line, and they would reappear over and over).
My current solution is expanding the snippet to #include <
.
Ahh, that makes sense too.
really hard to delete (e.g. when deleting the include line, and they would reappear over and over).
That's functionNode for you xD I think the only way out is to delete the entire snippet :/
A cool, maybe overcomplicated, way to solve this would be modifying the completion-items sent by clangd, the general approach would be similar to this, but instead of modifying snippets, the include-completion-items would have to be detected and the >/"
removed.
I hacked together
local function char_after_cursor()
local pos = require("luasnip.util.util").get_cursor_0ind()
local line = vim.api.nvim_buf_get_lines(0, pos[1], pos[1] + 1, false)
return string.sub(line[1], pos[2]+1, pos[2]+1)
end
-- ...
on_attach = function(client)
local orig_rpc_request = client.rpc.request
function client.rpc.request(method, params, handler, ...)
local orig_handler = handler
if method == 'textDocument/completion' then
handler = function(...)
local char = char_after_cursor()
if char and char == "\"" or char == ">" then
local err, result = ...
if not err and result then
local items = result.items or result
for _, item in ipairs(items) do
if item.kind == vim.lsp.protocol.CompletionItemKind.File and item.textEdit then
local text = item.textEdit.newText
if char == text:sub(-1, -1) then
item.textEdit.newText = string.sub(text, 1, -2)
end
end
end
end
end
return orig_handler(...)
end
end
return orig_rpc_request(method, params, handler, ...)
end
end,
It checks the char after the cursor for"
or >
and strips it from the completion candidates.
Nice, the check is a sensible addition :+1:
Maybe this is easier (not tested, I'm not a clangd
user)
cmp.setup({
snippet = {
expand = function(args)
local pos = vim.api.nvim_win_get_cursor(0)
local line = vim.api.nvim_buf_get_lines(0, pos[1] - 1, pos[1] , false)[1]
if vim.startswith(line, "#include") then
return args.body:sub(1, -2)
else
require('luasnip').lsp_expand(args.body)
end
end
.....
More complex preprocessing can be done there (like checking for the lsp servers that are active or the filetype), using your own snippets if the body matches a certain pattern...