diff --git a/lua/blink/cmp/completion/windows/ghost_text.lua b/lua/blink/cmp/completion/windows/ghost_text.lua index 2869e951..1d7e898c 100644 --- a/lua/blink/cmp/completion/windows/ghost_text.lua +++ b/lua/blink/cmp/completion/windows/ghost_text.lua @@ -71,7 +71,8 @@ function ghost_text.draw_preview(bufnr) if ghost_text.selected_item.insertTextFormat == vim.lsp.protocol.InsertTextFormat.Snippet then local expanded_snippet = snippets_utils.safe_parse(text_edit.newText) - text_edit.newText = expanded_snippet and tostring(expanded_snippet) or text_edit.newText + text_edit.newText = expanded_snippet and snippets_utils.add_identation(tostring(expanded_snippet)) + or text_edit.newText end local display_lines = vim.split(get_still_untyped_text(text_edit), '\n', { plain = true }) or {} diff --git a/lua/blink/cmp/sources/snippets/utils.lua b/lua/blink/cmp/sources/snippets/utils.lua index f0903b77..563a27c4 100644 --- a/lua/blink/cmp/sources/snippets/utils.lua +++ b/lua/blink/cmp/sources/snippets/utils.lua @@ -65,6 +65,37 @@ function utils.read_snippet(snippet, fallback) return snippets end +local function text_to_lines(text) + text = type(text) == 'string' and { text } or text + --- @cast text string[] + return vim.split(table.concat(text), '\n', { plain = true }) +end + +-- Add the current line's identation for a snippet raw text, +-- which is abtained by calling tostring(snippet). +---@param text string +function utils.add_identation(text) + local base_indent = vim.api.nvim_get_current_line():match('^%s*') or '' + local snippet_lines = text_to_lines(text) + + local shiftwidth = vim.fn.shiftwidth() + local curbuf = vim.api.nvim_get_current_buf() + local expandtab = vim.bo[curbuf].expandtab + + local lines = {} --- @type string[] + for i, line in ipairs(snippet_lines) do + -- Replace tabs by spaces. + if expandtab then + line = line:gsub('\t', (' '):rep(shiftwidth)) --- @type string + end + -- Add the base indentation. + if i > 1 then line = base_indent .. line end + lines[#lines + 1] = line + end + + return table.concat(lines, '\n') +end + function utils.get_tab_stops(snippet) local expanded_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(snippet) if not expanded_snippet then return end