Fix rendering of wide characters in the custom completion window (#641)
This commit is contained in:
@@ -1,17 +1,30 @@
|
||||
local buffer = {}
|
||||
|
||||
buffer.ensure = setmetatable({
|
||||
cache = {},
|
||||
}, {
|
||||
__call = function(self, name)
|
||||
if not (self.cache[name] and vim.api.nvim_buf_is_valid(self.cache[name])) then
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile')
|
||||
vim.api.nvim_buf_set_option(buf, 'bufhidden', 'hide')
|
||||
self.cache[name] = buf
|
||||
end
|
||||
return self.cache[name]
|
||||
end,
|
||||
})
|
||||
buffer.cache = {}
|
||||
|
||||
---@return number buf
|
||||
buffer.get = function(name)
|
||||
local buf = buffer.cache[name]
|
||||
if buf and vim.api.nvim_buf_is_valid(buf) then
|
||||
return buf
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
---@return number buf
|
||||
---@return boolean created_new
|
||||
buffer.ensure = function(name)
|
||||
local created_new = false
|
||||
local buf = buffer.get(name)
|
||||
if not buf then
|
||||
created_new = true
|
||||
buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile')
|
||||
vim.api.nvim_buf_set_option(buf, 'bufhidden', 'hide')
|
||||
buffer.cache[name] = buf
|
||||
end
|
||||
return buf, created_new
|
||||
end
|
||||
|
||||
return buffer
|
||||
|
||||
@@ -18,6 +18,7 @@ local api = require('cmp.utils.api')
|
||||
---@field public swin2 number|nil
|
||||
---@field public style cmp.WindowStyle
|
||||
---@field public opt table<string, any>
|
||||
---@field public buffer_opt table<string, any>
|
||||
---@field public cache cmp.Cache
|
||||
local window = {}
|
||||
|
||||
@@ -32,6 +33,7 @@ window.new = function()
|
||||
self.style = {}
|
||||
self.cache = cache.new()
|
||||
self.opt = {}
|
||||
self.buffer_opt = {}
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -54,6 +56,26 @@ window.option = function(self, key, value)
|
||||
end
|
||||
end
|
||||
|
||||
---Set buffer option.
|
||||
---NOTE: If the buffer already visible, immediately applied to it.
|
||||
---@param key string
|
||||
---@param value any
|
||||
window.buffer_option = function(self, key, value)
|
||||
if vim.fn.exists('+' .. key) == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if value == nil then
|
||||
return self.buffer_opt[key]
|
||||
end
|
||||
|
||||
self.buffer_opt[key] = value
|
||||
local existing_buf = buffer.get(self.name)
|
||||
if existing_buf then
|
||||
vim.api.nvim_buf_set_option(existing_buf, key, value)
|
||||
end
|
||||
end
|
||||
|
||||
---Set style.
|
||||
---@param style cmp.WindowStyle
|
||||
window.set_style = function(self, style)
|
||||
@@ -70,7 +92,13 @@ end
|
||||
---Return buffer id.
|
||||
---@return number
|
||||
window.get_buffer = function(self)
|
||||
return buffer.ensure(self.name)
|
||||
local buf, created_new = buffer.ensure(self.name)
|
||||
if created_new then
|
||||
for k, v in pairs(self.buffer_opt) do
|
||||
vim.api.nvim_buf_set_option(buf, k, v)
|
||||
end
|
||||
end
|
||||
return buf
|
||||
end
|
||||
|
||||
---Open window
|
||||
@@ -89,7 +117,7 @@ window.open = function(self, style)
|
||||
else
|
||||
local s = misc.copy(self.style)
|
||||
s.noautocmd = true
|
||||
self.win = vim.api.nvim_open_win(buffer.ensure(self.name), false, s)
|
||||
self.win = vim.api.nvim_open_win(self:get_buffer(), false, s)
|
||||
for k, v in pairs(self.opt) do
|
||||
vim.api.nvim_win_set_option(self.win, k, v)
|
||||
end
|
||||
@@ -251,9 +279,14 @@ window.get_content_height = function(self)
|
||||
vim.api.nvim_buf_get_changedtick(self:get_buffer()),
|
||||
}, function()
|
||||
local height = 0
|
||||
for _, text in ipairs(vim.api.nvim_buf_get_lines(self:get_buffer(), 0, -1, false)) do
|
||||
height = height + math.ceil(math.max(1, vim.str_utfindex(text)) / self.style.width)
|
||||
end
|
||||
local buf = self:get_buffer()
|
||||
-- The result of vim.fn.strdisplaywidth depends on the buffer it was called
|
||||
-- in (see comment in cmp.Entry.get_view).
|
||||
vim.api.nvim_buf_call(buf, function()
|
||||
for _, text in ipairs(vim.api.nvim_buf_get_lines(buf, 0, -1, false)) do
|
||||
height = height + math.ceil(math.max(1, vim.fn.strdisplaywidth(text)) / self.style.width)
|
||||
end
|
||||
end)
|
||||
return height
|
||||
end)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user