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 cache = require('cmp.utils.cache')
|
||||||
local misc = require('cmp.utils.misc')
|
local misc = require('cmp.utils.misc')
|
||||||
|
local buffer = require('cmp.utils.buffer')
|
||||||
|
|
||||||
---@class cmp.WindowStyle
|
---@class cmp.WindowStyle
|
||||||
---@field public relative string
|
---@field public relative string
|
||||||
@@ -10,11 +11,9 @@ local misc = require('cmp.utils.misc')
|
|||||||
---@field public zindex number|nil
|
---@field public zindex number|nil
|
||||||
|
|
||||||
---@class cmp.Window
|
---@class cmp.Window
|
||||||
---@field public buf number
|
---@field public name string
|
||||||
---@field public win number|nil
|
---@field public win number|nil
|
||||||
---@field public sbuf1 number
|
|
||||||
---@field public swin1 number|nil
|
---@field public swin1 number|nil
|
||||||
---@field public sbuf2 number
|
|
||||||
---@field public swin2 number|nil
|
---@field public swin2 number|nil
|
||||||
---@field public style cmp.WindowStyle
|
---@field public style cmp.WindowStyle
|
||||||
---@field public opt table<string, any>
|
---@field public opt table<string, any>
|
||||||
@@ -25,7 +24,7 @@ local window = {}
|
|||||||
---@return cmp.Window
|
---@return cmp.Window
|
||||||
window.new = function()
|
window.new = function()
|
||||||
local self = setmetatable({}, { __index = window })
|
local self = setmetatable({}, { __index = window })
|
||||||
self:ensure()
|
self.name = misc.id('cmp.utils.window')
|
||||||
self.win = nil
|
self.win = nil
|
||||||
self.swin1 = nil
|
self.swin1 = nil
|
||||||
self.swin2 = nil
|
self.swin2 = nil
|
||||||
@@ -36,19 +35,6 @@ window.new = function()
|
|||||||
return self
|
return self
|
||||||
end
|
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.
|
---Set window option.
|
||||||
---NOTE: If the window already visible, immediately applied to it.
|
---NOTE: If the window already visible, immediately applied to it.
|
||||||
---@param key string
|
---@param key string
|
||||||
@@ -81,6 +67,12 @@ window.set_style = function(self, style)
|
|||||||
self.style.zindex = self.style.zindex or 1
|
self.style.zindex = self.style.zindex or 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Return buffer id.
|
||||||
|
---@return number
|
||||||
|
window.get_buffer = function(self)
|
||||||
|
return buffer.ensure(self.name)
|
||||||
|
end
|
||||||
|
|
||||||
---Open window
|
---Open window
|
||||||
---@param style cmp.WindowStyle
|
---@param style cmp.WindowStyle
|
||||||
window.open = function(self, style)
|
window.open = function(self, style)
|
||||||
@@ -99,7 +91,7 @@ window.open = function(self, style)
|
|||||||
else
|
else
|
||||||
local s = misc.copy(self.style)
|
local s = misc.copy(self.style)
|
||||||
s.noautocmd = true
|
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
|
for k, v in pairs(self.opt) do
|
||||||
vim.api.nvim_win_set_option(self.win, k, v)
|
vim.api.nvim_win_set_option(self.win, k, v)
|
||||||
end
|
end
|
||||||
@@ -126,7 +118,7 @@ window.update = function(self)
|
|||||||
vim.api.nvim_win_set_config(self.swin1, style1)
|
vim.api.nvim_win_set_config(self.swin1, style1)
|
||||||
else
|
else
|
||||||
style1.noautocmd = true
|
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')
|
vim.api.nvim_win_set_option(self.swin1, 'winhighlight', 'Normal:PmenuSbar,NormalNC:PmenuSbar,NormalFloat:PmenuSbar')
|
||||||
end
|
end
|
||||||
local style2 = {}
|
local style2 = {}
|
||||||
@@ -141,7 +133,7 @@ window.update = function(self)
|
|||||||
vim.api.nvim_win_set_config(self.swin2, style2)
|
vim.api.nvim_win_set_config(self.swin2, style2)
|
||||||
else
|
else
|
||||||
style2.noautocmd = true
|
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')
|
vim.api.nvim_win_set_option(self.swin2, 'winhighlight', 'Normal:PmenuThumb,NormalNC:PmenuThumb,NormalFloat:PmenuThumb')
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -249,17 +241,17 @@ end
|
|||||||
---@return number
|
---@return number
|
||||||
window.get_content_height = function(self)
|
window.get_content_height = function(self)
|
||||||
if not self:option('wrap') then
|
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
|
end
|
||||||
|
|
||||||
return self.cache:ensure({
|
return self.cache:ensure({
|
||||||
'get_content_height',
|
'get_content_height',
|
||||||
self.style.width,
|
self.style.width,
|
||||||
self.buf,
|
self:get_buffer(),
|
||||||
vim.api.nvim_buf_get_changedtick(self.buf),
|
vim.api.nvim_buf_get_changedtick(self:get_buffer()),
|
||||||
}, function()
|
}, function()
|
||||||
local height = 0
|
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)
|
height = height + math.ceil(math.max(1, vim.str_utfindex(text)) / self.style.width)
|
||||||
end
|
end
|
||||||
return height
|
return height
|
||||||
|
|||||||
@@ -89,8 +89,6 @@ custom_entries_view.redraw = function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
custom_entries_view.open = function(self, offset, entries)
|
custom_entries_view.open = function(self, offset, entries)
|
||||||
self.entries_win:ensure()
|
|
||||||
|
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.entries = {}
|
self.entries = {}
|
||||||
self.column_bytes = { abbr = 0, kind = 0, menu = 0 }
|
self.column_bytes = { abbr = 0, kind = 0, menu = 0 }
|
||||||
@@ -121,7 +119,7 @@ custom_entries_view.open = function(self, offset, entries)
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
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
|
local width = 0
|
||||||
width = width + 1
|
width = width + 1
|
||||||
@@ -202,7 +200,7 @@ custom_entries_view.draw = function(self)
|
|||||||
table.insert(texts, table.concat(text, ''))
|
table.insert(texts, table.concat(text, ''))
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
custom_entries_view.visible = function(self)
|
custom_entries_view.visible = function(self)
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ end
|
|||||||
---@param e cmp.Entry
|
---@param e cmp.Entry
|
||||||
---@param view cmp.WindowStyle
|
---@param view cmp.WindowStyle
|
||||||
docs_view.open = function(self, e, view)
|
docs_view.open = function(self, e, view)
|
||||||
self.window:ensure()
|
|
||||||
|
|
||||||
local documentation = config.get().documentation
|
local documentation = config.get().documentation
|
||||||
if not documentation then
|
if not documentation then
|
||||||
return
|
return
|
||||||
@@ -45,16 +43,16 @@ docs_view.open = function(self, e, view)
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.entry = e
|
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]])
|
vim.cmd([[syntax clear]])
|
||||||
end)
|
end)
|
||||||
vim.lsp.util.stylize_markdown(self.window.buf, documents, {
|
vim.lsp.util.stylize_markdown(self.window:get_buffer(), documents, {
|
||||||
max_width = maxwidth,
|
max_width = maxwidth,
|
||||||
max_height = documentation.maxheight,
|
max_height = documentation.maxheight,
|
||||||
})
|
})
|
||||||
end
|
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_width = maxwidth,
|
||||||
max_height = documentation.maxheight,
|
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)
|
top = math.min(top, self.window:get_content_height() - info.height + 1)
|
||||||
|
|
||||||
vim.defer_fn(function()
|
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')
|
vim.api.nvim_command('normal! ' .. top .. 'zt')
|
||||||
self.window:update()
|
self.window:update()
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user