diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua index 93a5616..b314585 100644 --- a/lua/cmp/entry.lua +++ b/lua/cmp/entry.lua @@ -107,7 +107,7 @@ entry.get_word = function(self) end local word - if misc.safe(self:get_completion_item().textEdit) then + if misc.safe(self:get_completion_item().textEdit) and not misc.empty(self:get_completion_item().textEdit.newText) then word = str.trim(self:get_completion_item().textEdit.newText) if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = vim.lsp.util.parse_snippet(word) @@ -116,7 +116,7 @@ entry.get_word = function(self) if 0 < overwrite[2] or self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = str.get_word(word, string.byte(self.context.cursor_after_line, 1), overwrite[1] or 0) end - elseif misc.safe(self:get_completion_item().insertText) then + elseif not misc.empty(self:get_completion_item().insertText) then word = str.trim(self:get_completion_item().insertText) if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = str.get_word(vim.lsp.util.parse_snippet(word)) @@ -362,7 +362,7 @@ entry.match = function(self, input, matching_config) -- Support the language server that doesn't respect VSCode's behaviors. if score == 0 then - if misc.safe(self:get_completion_item().textEdit) then + if misc.safe(self:get_completion_item().textEdit) and not misc.empty(self:get_completion_item().textEdit.newText) then local diff = self.source_offset - self:get_offset() if diff > 0 then local prefix = string.sub(self.context.cursor_line, self:get_offset(), self:get_offset() + diff) diff --git a/lua/cmp/entry_spec.lua b/lua/cmp/entry_spec.lua index 61f6fb8..ce9933a 100644 --- a/lua/cmp/entry_spec.lua +++ b/lua/cmp/entry_spec.lua @@ -264,6 +264,58 @@ describe('entry', function() assert.are.equal(e:get_filter_text(), '$this') end) + it('[odin-language-server] 1', function() + local state = spec.state('\t\t', 1, 4) + + -- press g + state.input('s') + local e = entry.new(state.manual(), state.source(), { + additionalTextEdits = {}, + command = { + arguments = {}, + command = '', + title = '', + }, + deprecated = false, + detail = 'string', + documentation = '', + insertText = '', + insertTextFormat = 1, + kind = 14, + label = 'string', + tags = {}, + }) + assert.are.equal(e:get_vim_item(e:get_offset()).word, 'string') + end) + + it('[ansiblels] 1', function() + local state = spec.state('\t\t', 1, 4) + + -- press g + state.input('s') + local e = entry.new(state.manual(), state.source(), { + detail = 'ansible.builtin', + filterText = 'blockinfile ansible.builtin.blockinfile', + kind = 7, + label = 'blockinfile', + sortText = '2_blockinfile', + textEdit = { + newText = '', + range = { + ['end'] = { + character = 7, + line = 15, + }, + start = { + character = 6, + line = 15, + }, + }, + }, + }) + assert.are.equal(e:get_vim_item(e:get_offset()).word, 'blockinfile') + end) + it('[#47] word should not contain \\n character', function() local state = spec.state('', 1, 1) diff --git a/lua/cmp/utils/misc.lua b/lua/cmp/utils/misc.lua index f2c3bbd..7409827 100644 --- a/lua/cmp/utils/misc.lua +++ b/lua/cmp/utils/misc.lua @@ -29,6 +29,28 @@ misc.concat = function(list1, list2) return new_list end +---Return the valu is empty or not. +---@param v any +---@return boolean +misc.empty = function(v) + if not v then + return true + end + if v == vim.NIL then + return true + end + if type(v) == 'string' and v == '' then + return true + end + if type(v) == 'table' and vim.tbl_isempty(v) then + return true + end + if type(v) == 'number' and v == 0 then + return true + end + return false +end + ---The symbol to remove key in misc.merge. misc.none = vim.NIL