From d7210453f6824d8d7aa3bb9bc2fb78df5413c1fc Mon Sep 17 00:00:00 2001 From: xzb <2598514867@qq.com> Date: Wed, 8 Jan 2025 00:02:35 +0800 Subject: [PATCH 1/2] fix(ghost_text): ensure multiline indent is correct --- .../cmp/completion/windows/ghost_text.lua | 3 +- lua/blink/cmp/sources/snippets/utils.lua | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) 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 From c0f8a8924642708965d51f1cfa5588f6131898bb Mon Sep 17 00:00:00 2001 From: Liam Dyer Date: Wed, 8 Jan 2025 11:03:51 -0500 Subject: [PATCH 2/2] refactor: misc cleanup --- .../cmp/completion/windows/ghost_text.lua | 2 +- lua/blink/cmp/sources/snippets/utils.lua | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/lua/blink/cmp/completion/windows/ghost_text.lua b/lua/blink/cmp/completion/windows/ghost_text.lua index 1d7e898c..c94f9a74 100644 --- a/lua/blink/cmp/completion/windows/ghost_text.lua +++ b/lua/blink/cmp/completion/windows/ghost_text.lua @@ -71,7 +71,7 @@ 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 snippets_utils.add_identation(tostring(expanded_snippet)) + text_edit.newText = expanded_snippet and snippets_utils.add_current_line_indentation(tostring(expanded_snippet)) or text_edit.newText end diff --git a/lua/blink/cmp/sources/snippets/utils.lua b/lua/blink/cmp/sources/snippets/utils.lua index 563a27c4..a8eea099 100644 --- a/lua/blink/cmp/sources/snippets/utils.lua +++ b/lua/blink/cmp/sources/snippets/utils.lua @@ -65,18 +65,12 @@ 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). +-- Add the current line's identation to all but the first line of +-- the provided text ---@param text string -function utils.add_identation(text) +function utils.add_current_line_indentation(text) local base_indent = vim.api.nvim_get_current_line():match('^%s*') or '' - local snippet_lines = text_to_lines(text) + local snippet_lines = vim.split(text, '\n', { plain = true }) local shiftwidth = vim.fn.shiftwidth() local curbuf = vim.api.nvim_get_current_buf() @@ -84,11 +78,11 @@ function utils.add_identation(text) local lines = {} --- @type string[] for i, line in ipairs(snippet_lines) do - -- Replace tabs by spaces. + -- Replace tabs with spaces if expandtab then line = line:gsub('\t', (' '):rep(shiftwidth)) --- @type string end - -- Add the base indentation. + -- Add the base indentation if i > 1 then line = base_indent .. line end lines[#lines + 1] = line end