fix(ghost_text): generate it using chars instead of bytes (#471)
Previously if the completion entry text had a multibyte character the ghostly text renderd improperly, for example: The cursor position is "|" 1. In this case the ghost text was spliting a multibyte character. entry: comunicación prev: comunicacio|<b3>n now: comunicacio|n 2. In this case the multibyte character was before meking the index wrong, therefore presenting an extra character of the entry as ghost text. entry: árbol prev: arbol|l now: arbol| With this changes the calculation for the bytes to show is done based on characters avoiding both of the issues above.
This commit is contained in:
@@ -26,19 +26,15 @@ ghost_text_view.new = function()
|
||||
return
|
||||
end
|
||||
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
if string.sub(vim.api.nvim_get_current_line(), cursor[2] + 1) ~= '' then
|
||||
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
if string.sub(line, col + 1) ~= '' then
|
||||
return
|
||||
end
|
||||
|
||||
local diff = 1 + cursor[2] - self.entry:get_offset()
|
||||
local text = self.entry:get_insert_text()
|
||||
if self.entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then
|
||||
text = vim.lsp.util.parse_snippet(text)
|
||||
end
|
||||
text = string.sub(str.oneline(text), diff + 1)
|
||||
local text = self.text_gen(self, line, col)
|
||||
if #text > 0 then
|
||||
vim.api.nvim_buf_set_extmark(0, ghost_text_view.ns, cursor[1] - 1, cursor[2], {
|
||||
vim.api.nvim_buf_set_extmark(0, ghost_text_view.ns, row - 1, col, {
|
||||
right_gravity = false,
|
||||
virt_text = { { text, c.hl_group or 'Comment' } },
|
||||
virt_text_pos = 'overlay',
|
||||
@@ -51,6 +47,30 @@ ghost_text_view.new = function()
|
||||
return self
|
||||
end
|
||||
|
||||
---Generate the ghost text
|
||||
--- This function calculates the bytes of the entry to display calculating the number
|
||||
--- of character differences instead of just byte difference.
|
||||
ghost_text_view.text_gen = function(self, line, cursor_col)
|
||||
local word = self.entry:get_insert_text()
|
||||
if self.entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then
|
||||
word = vim.lsp.util.parse_snippet(word)
|
||||
end
|
||||
word = str.oneline(word)
|
||||
local word_clen = vim.str_utfindex(word)
|
||||
local cword = string.sub(line, self.entry:get_offset(), cursor_col)
|
||||
local cword_clen = vim.str_utfindex(cword)
|
||||
-- Number of characters from entry text (word) to be displayed as ghost thext
|
||||
local nchars = word_clen - cword_clen
|
||||
-- Missing characters to complete the entry text
|
||||
local text
|
||||
if nchars > 0 then
|
||||
text = string.sub(word, vim.str_byteindex(word, word_clen - nchars) + 1)
|
||||
else
|
||||
text = ""
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
---Show ghost text
|
||||
---@param e cmp.Entry
|
||||
ghost_text_view.show = function(self, e)
|
||||
|
||||
Reference in New Issue
Block a user