From 0a31d672199c0737c83f5e5a2f8bfb6b49235871 Mon Sep 17 00:00:00 2001 From: hrsh7th Date: Sun, 10 Oct 2021 13:57:37 +0900 Subject: [PATCH] Lazy buffer creation --- lua/cmp/utils/buffer.lua | 17 ++++++++++++ lua/cmp/utils/window.lua | 40 +++++++++++----------------- lua/cmp/view/custom_entries_view.lua | 6 ++--- lua/cmp/view/docs_view.lua | 10 +++---- 4 files changed, 39 insertions(+), 34 deletions(-) create mode 100644 lua/cmp/utils/buffer.lua diff --git a/lua/cmp/utils/buffer.lua b/lua/cmp/utils/buffer.lua new file mode 100644 index 0000000..56f0ac1 --- /dev/null +++ b/lua/cmp/utils/buffer.lua @@ -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 diff --git a/lua/cmp/utils/window.lua b/lua/cmp/utils/window.lua index 5e7849d..bc4a223 100644 --- a/lua/cmp/utils/window.lua +++ b/lua/cmp/utils/window.lua @@ -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 @@ -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 diff --git a/lua/cmp/view/custom_entries_view.lua b/lua/cmp/view/custom_entries_view.lua index 3f13630..54f68da 100644 --- a/lua/cmp/view/custom_entries_view.lua +++ b/lua/cmp/view/custom_entries_view.lua @@ -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) diff --git a/lua/cmp/view/docs_view.lua b/lua/cmp/view/docs_view.lua index e005903..2027992 100644 --- a/lua/cmp/view/docs_view.lua +++ b/lua/cmp/view/docs_view.lua @@ -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)