Lazy buffer creation

This commit is contained in:
hrsh7th
2021-10-10 13:57:37 +09:00
parent d901dae302
commit 0a31d67219
4 changed files with 39 additions and 34 deletions

17
lua/cmp/utils/buffer.lua Normal file
View 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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)