Lazy buffer creation
This commit is contained in:
17
lua/cmp/utils/buffer.lua
Normal file
17
lua/cmp/utils/buffer.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
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
|
||||
})
|
||||
|
||||
return buffer
|
||||
@@ -1,5 +1,6 @@
|
||||
local cache = require('cmp.utils.cache')
|
||||
local misc = require('cmp.utils.misc')
|
||||
local buffer = require('cmp.utils.buffer')
|
||||
|
||||
---@class cmp.WindowStyle
|
||||
---@field public relative string
|
||||
@@ -10,11 +11,9 @@ local misc = require('cmp.utils.misc')
|
||||
---@field public zindex number|nil
|
||||
|
||||
---@class cmp.Window
|
||||
---@field public buf number
|
||||
---@field public name string
|
||||
---@field public win number|nil
|
||||
---@field public sbuf1 number
|
||||
---@field public swin1 number|nil
|
||||
---@field public sbuf2 number
|
||||
---@field public swin2 number|nil
|
||||
---@field public style cmp.WindowStyle
|
||||
---@field public opt table<string, any>
|
||||
@@ -25,7 +24,7 @@ local window = {}
|
||||
---@return cmp.Window
|
||||
window.new = function()
|
||||
local self = setmetatable({}, { __index = window })
|
||||
self:ensure()
|
||||
self.name = misc.id('cmp.utils.window')
|
||||
self.win = nil
|
||||
self.swin1 = nil
|
||||
self.swin2 = nil
|
||||
@@ -36,19 +35,6 @@ window.new = function()
|
||||
return self
|
||||
end
|
||||
|
||||
---Ensure valid state.
|
||||
window.ensure = function(self)
|
||||
for _, name in ipairs({ 'buf', 'sbuf1', 'subf2' }) do
|
||||
if not (self[name] and vim.api.nvim_buf_is_valid(self[name])) then
|
||||
self[name] = vim.api.nvim_create_buf(false, true)
|
||||
end
|
||||
-- We always apply options to the buffer to support session related plugins.
|
||||
vim.api.nvim_buf_set_option(self[name], 'undolevels', -1)
|
||||
vim.api.nvim_buf_set_option(self[name], 'buftype', 'nofile')
|
||||
vim.api.nvim_buf_set_option(self[name], 'bufhidden', 'hide')
|
||||
end
|
||||
end
|
||||
|
||||
---Set window option.
|
||||
---NOTE: If the window already visible, immediately applied to it.
|
||||
---@param key string
|
||||
@@ -81,6 +67,12 @@ window.set_style = function(self, style)
|
||||
self.style.zindex = self.style.zindex or 1
|
||||
end
|
||||
|
||||
---Return buffer id.
|
||||
---@return number
|
||||
window.get_buffer = function(self)
|
||||
return buffer.ensure(self.name)
|
||||
end
|
||||
|
||||
---Open window
|
||||
---@param style cmp.WindowStyle
|
||||
window.open = function(self, style)
|
||||
@@ -99,7 +91,7 @@ window.open = function(self, style)
|
||||
else
|
||||
local s = misc.copy(self.style)
|
||||
s.noautocmd = true
|
||||
self.win = vim.api.nvim_open_win(self.buf, false, s)
|
||||
self.win = vim.api.nvim_open_win(buffer.ensure(self.name), false, s)
|
||||
for k, v in pairs(self.opt) do
|
||||
vim.api.nvim_win_set_option(self.win, k, v)
|
||||
end
|
||||
@@ -126,7 +118,7 @@ window.update = function(self)
|
||||
vim.api.nvim_win_set_config(self.swin1, style1)
|
||||
else
|
||||
style1.noautocmd = true
|
||||
self.swin1 = vim.api.nvim_open_win(self.sbuf1, false, style1)
|
||||
self.swin1 = vim.api.nvim_open_win(buffer.ensure(self.name .. 'sbuf1'), false, style1)
|
||||
vim.api.nvim_win_set_option(self.swin1, 'winhighlight', 'Normal:PmenuSbar,NormalNC:PmenuSbar,NormalFloat:PmenuSbar')
|
||||
end
|
||||
local style2 = {}
|
||||
@@ -141,7 +133,7 @@ window.update = function(self)
|
||||
vim.api.nvim_win_set_config(self.swin2, style2)
|
||||
else
|
||||
style2.noautocmd = true
|
||||
self.swin2 = vim.api.nvim_open_win(self.sbuf2, false, style2)
|
||||
self.swin2 = vim.api.nvim_open_win(buffer.ensure(self.name .. 'sbuf2'), false, style2)
|
||||
vim.api.nvim_win_set_option(self.swin2, 'winhighlight', 'Normal:PmenuThumb,NormalNC:PmenuThumb,NormalFloat:PmenuThumb')
|
||||
end
|
||||
else
|
||||
@@ -249,17 +241,17 @@ end
|
||||
---@return number
|
||||
window.get_content_height = function(self)
|
||||
if not self:option('wrap') then
|
||||
return vim.api.nvim_buf_line_count(self.buf)
|
||||
return vim.api.nvim_buf_line_count(self:get_buffer())
|
||||
end
|
||||
|
||||
return self.cache:ensure({
|
||||
'get_content_height',
|
||||
self.style.width,
|
||||
self.buf,
|
||||
vim.api.nvim_buf_get_changedtick(self.buf),
|
||||
self:get_buffer(),
|
||||
vim.api.nvim_buf_get_changedtick(self:get_buffer()),
|
||||
}, function()
|
||||
local height = 0
|
||||
for _, text in ipairs(vim.api.nvim_buf_get_lines(self.buf, 0, -1, false)) do
|
||||
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
|
||||
return height
|
||||
|
||||
@@ -89,8 +89,6 @@ custom_entries_view.redraw = function()
|
||||
end
|
||||
|
||||
custom_entries_view.open = function(self, offset, entries)
|
||||
self.entries_win:ensure()
|
||||
|
||||
self.offset = offset
|
||||
self.entries = {}
|
||||
self.column_bytes = { abbr = 0, kind = 0, menu = 0 }
|
||||
@@ -121,7 +119,7 @@ custom_entries_view.open = function(self, offset, entries)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(self.entries_win.buf, 0, -1, false, lines)
|
||||
vim.api.nvim_buf_set_lines(self.entries_win:get_buffer(), 0, -1, false, lines)
|
||||
|
||||
local width = 0
|
||||
width = width + 1
|
||||
@@ -202,7 +200,7 @@ custom_entries_view.draw = function(self)
|
||||
table.insert(texts, table.concat(text, ''))
|
||||
end
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(self.entries_win.buf, topline, botline, false, texts)
|
||||
vim.api.nvim_buf_set_lines(self.entries_win:get_buffer(), topline, botline, false, texts)
|
||||
end
|
||||
|
||||
custom_entries_view.visible = function(self)
|
||||
|
||||
@@ -22,8 +22,6 @@ end
|
||||
---@param e cmp.Entry
|
||||
---@param view cmp.WindowStyle
|
||||
docs_view.open = function(self, e, view)
|
||||
self.window:ensure()
|
||||
|
||||
local documentation = config.get().documentation
|
||||
if not documentation then
|
||||
return
|
||||
@@ -45,16 +43,16 @@ docs_view.open = function(self, e, view)
|
||||
end
|
||||
|
||||
self.entry = e
|
||||
vim.api.nvim_buf_call(self.window.buf, function()
|
||||
vim.api.nvim_buf_call(self.window:get_buffer(), function()
|
||||
vim.cmd([[syntax clear]])
|
||||
end)
|
||||
vim.lsp.util.stylize_markdown(self.window.buf, documents, {
|
||||
vim.lsp.util.stylize_markdown(self.window:get_buffer(), documents, {
|
||||
max_width = maxwidth,
|
||||
max_height = documentation.maxheight,
|
||||
})
|
||||
end
|
||||
|
||||
local width, height = vim.lsp.util._make_floating_popup_size(vim.api.nvim_buf_get_lines(self.window.buf, 0, -1, false), {
|
||||
local width, height = vim.lsp.util._make_floating_popup_size(vim.api.nvim_buf_get_lines(self.window:get_buffer(), 0, -1, false), {
|
||||
max_width = maxwidth,
|
||||
max_height = documentation.maxheight,
|
||||
})
|
||||
@@ -113,7 +111,7 @@ docs_view.scroll = function(self, delta)
|
||||
top = math.min(top, self.window:get_content_height() - info.height + 1)
|
||||
|
||||
vim.defer_fn(function()
|
||||
vim.api.nvim_buf_call(self.window.buf, function()
|
||||
vim.api.nvim_buf_call(self.window:get_buffer(), function()
|
||||
vim.api.nvim_command('normal! ' .. top .. 'zt')
|
||||
self.window:update()
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user