Support import completion
This commit is contained in:
@@ -109,14 +109,17 @@ entry.get_word = function(self)
|
|||||||
local word
|
local word
|
||||||
if misc.safe(self:get_completion_item().textEdit) then
|
if misc.safe(self:get_completion_item().textEdit) then
|
||||||
word = str.trim(self:get_completion_item().textEdit.newText)
|
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)
|
||||||
|
end
|
||||||
local overwrite = self:get_overwrite()
|
local overwrite = self:get_overwrite()
|
||||||
if 0 < overwrite[2] or self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then
|
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))
|
word = str.get_word(word, string.byte(self.context.cursor_after_line, 1), overwrite[1] or 0)
|
||||||
end
|
end
|
||||||
elseif misc.safe(self:get_completion_item().insertText) then
|
elseif misc.safe(self:get_completion_item().insertText) then
|
||||||
word = str.trim(self:get_completion_item().insertText)
|
word = str.trim(self:get_completion_item().insertText)
|
||||||
if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then
|
if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then
|
||||||
word = str.get_word(word)
|
word = str.get_word(vim.lsp.util.parse_snippet(word))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
word = str.trim(self:get_completion_item().label)
|
word = str.trim(self:get_completion_item().label)
|
||||||
@@ -151,20 +154,6 @@ entry.get_filter_text = function(self)
|
|||||||
else
|
else
|
||||||
word = str.trim(self:get_completion_item().label)
|
word = str.trim(self:get_completion_item().label)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @see https://github.com/clangd/clangd/issues/815
|
|
||||||
if misc.safe(self:get_completion_item().textEdit) then
|
|
||||||
local diff = self.source_offset - self:get_offset()
|
|
||||||
if diff > 0 then
|
|
||||||
if char.is_symbol(string.byte(self.context.cursor_line, self:get_offset())) then
|
|
||||||
local prefix = string.sub(self.context.cursor_line, self:get_offset(), self:get_offset() + diff)
|
|
||||||
if string.find(word, prefix, 1, true) ~= 1 then
|
|
||||||
word = prefix .. word
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return word
|
return word
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -351,11 +340,31 @@ end
|
|||||||
---@return { score: number, matches: table[] }
|
---@return { score: number, matches: table[] }
|
||||||
entry.match = function(self, input)
|
entry.match = function(self, input)
|
||||||
return self.match_cache:ensure({ input, self.resolved_completion_item and 1 or 0 }, function()
|
return self.match_cache:ensure({ input, self.resolved_completion_item and 1 or 0 }, function()
|
||||||
local score, matches, _
|
local filter_text = self:get_filter_text()
|
||||||
score, matches = matcher.match(input, self:get_filter_text(), { self:get_word(), self:get_completion_item().label })
|
|
||||||
if self:get_filter_text() ~= self:get_completion_item().label then
|
local score, matches
|
||||||
|
score, matches = matcher.match(input, filter_text, { self:get_word(), self:get_completion_item().label })
|
||||||
|
|
||||||
|
-- Support the language server that doesn't respect VSCode's behaviors.
|
||||||
|
if score == 0 then
|
||||||
|
if misc.safe(self:get_completion_item().textEdit) 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)
|
||||||
|
local accept = false
|
||||||
|
accept = accept or string.match(prefix, '^[^%a]+$')
|
||||||
|
accept = accept or string.find(self:get_completion_item().textEdit.newText, prefix, 1, true)
|
||||||
|
if accept then
|
||||||
|
score, matches = matcher.match(input, prefix .. filter_text, { self:get_word(), self:get_completion_item().label })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if filter_text ~= self:get_completion_item().label then
|
||||||
_, matches = matcher.match(input, self:get_completion_item().label, { self:get_word() })
|
_, matches = matcher.match(input, self:get_completion_item().label, { self:get_word() })
|
||||||
end
|
end
|
||||||
|
|
||||||
return { score = score, matches = matches }
|
return { score = score, matches = matches }
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ describe('entry', function()
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.are.equal(e:get_vim_item(4).word, '->foo')
|
assert.are.equal(e:get_vim_item(4).word, '->foo')
|
||||||
assert.are.equal(e:get_filter_text(), '.foo')
|
assert.are.equal(e:get_filter_text(), 'foo')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('[typescript-language-server] 1', function()
|
it('[typescript-language-server] 1', function()
|
||||||
|
|||||||
@@ -106,33 +106,36 @@ end
|
|||||||
|
|
||||||
---get_word
|
---get_word
|
||||||
---@param text string
|
---@param text string
|
||||||
|
---@param stop_char number
|
||||||
|
---@param min_length number
|
||||||
---@return string
|
---@return string
|
||||||
str.get_word = function(text, stop_char)
|
str.get_word = function(text, stop_char, min_length)
|
||||||
|
min_length = min_length or 0
|
||||||
|
|
||||||
local has_alnum = false
|
local has_alnum = false
|
||||||
local stack = {}
|
local stack = {}
|
||||||
local word = {}
|
local word = {}
|
||||||
|
local add = function(c)
|
||||||
|
table.insert(word, string.char(c))
|
||||||
|
if stack[#stack] == c then
|
||||||
|
table.remove(stack, #stack)
|
||||||
|
else
|
||||||
|
if PAIRS[c] then
|
||||||
|
table.insert(stack, c)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
for i = 1, #text do
|
for i = 1, #text do
|
||||||
local c = string.byte(text, i, i)
|
local c = string.byte(text, i, i)
|
||||||
if not INVALIDS[c] then
|
if #word < min_length then
|
||||||
if PAIRS[c] then
|
|
||||||
table.insert(stack, c)
|
|
||||||
end
|
|
||||||
table.insert(word, string.char(c))
|
table.insert(word, string.char(c))
|
||||||
|
elseif not INVALIDS[c] then
|
||||||
|
add(c)
|
||||||
has_alnum = has_alnum or char.is_alnum(c)
|
has_alnum = has_alnum or char.is_alnum(c)
|
||||||
elseif not has_alnum then
|
elseif not has_alnum then
|
||||||
if PAIRS[c] then
|
add(c)
|
||||||
table.insert(stack, c)
|
|
||||||
end
|
|
||||||
table.insert(word, string.char(c))
|
|
||||||
elseif #stack ~= 0 then
|
elseif #stack ~= 0 then
|
||||||
table.insert(word, string.char(c))
|
add(c)
|
||||||
if stack[#stack] == c then
|
|
||||||
table.remove(stack, #stack)
|
|
||||||
else
|
|
||||||
if PAIRS[c] then
|
|
||||||
table.insert(stack, c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if has_alnum and #stack == 0 then
|
if has_alnum and #stack == 0 then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ describe('utils.str', function()
|
|||||||
assert.are.equal(str.get_word('"devDependencies":', string.byte('"')), '"devDependencies')
|
assert.are.equal(str.get_word('"devDependencies":', string.byte('"')), '"devDependencies')
|
||||||
assert.are.equal(str.get_word('"devDependencies": ${1},', string.byte('"')), '"devDependencies')
|
assert.are.equal(str.get_word('"devDependencies": ${1},', string.byte('"')), '"devDependencies')
|
||||||
assert.are.equal(str.get_word('#[cfg(test)]'), '#[cfg(test)]')
|
assert.are.equal(str.get_word('#[cfg(test)]'), '#[cfg(test)]')
|
||||||
|
assert.are.equal(str.get_word('import { GetStaticProps$1 } from "next";', nil, 9), 'import { GetStaticProps')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('strikethrough', function()
|
it('strikethrough', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user