Skip to content

Commit b9e3033

Browse files
feat: save unused buffers in buffer pool (#536)
* feat: save unused buffers in buffer pool * fix: codestyle Co-authored-by: Lewis Russell <[email protected]> * fix: address review comments * fix: don't check all buffers in the pool every time the context is closed --------- Co-authored-by: Lewis Russell <[email protected]>
1 parent 9ff7a5e commit b9e3033

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

lua/treesitter-context/render.lua

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ local config = require('treesitter-context.config')
66

77
local ns = api.nvim_create_namespace('nvim-treesitter-context')
88

9-
--- List of buffers that are to be deleted.
9+
--- List of free buffers that can be reused.
1010
---@type integer[]
11-
local retired_buffers = {}
11+
local buffer_pool = {}
12+
13+
local MAX_BUFFER_POOL_SIZE = 20
1214

1315
--- @class WindowContext
1416
--- @field context_winid integer? The context window ID.
@@ -20,15 +22,35 @@ local retired_buffers = {}
2022
local window_contexts = {}
2123

2224
--- @return integer buf
23-
local function create_buf()
25+
local function create_or_get_buf()
26+
for index = #buffer_pool, 1, -1 do
27+
local buf = table.remove(buffer_pool, index)
28+
if api.nvim_buf_is_valid(buf) then
29+
return buf
30+
end
31+
end
32+
2433
local buf = api.nvim_create_buf(false, true)
2534

2635
vim.bo[buf].undolevels = -1
27-
vim.bo[buf].bufhidden = 'wipe'
2836

2937
return buf
3038
end
3139

40+
local function delete_excess_buffers()
41+
if fn.getcmdwintype() ~= '' then
42+
-- Can't delete buffers when the command-line window is open.
43+
return
44+
end
45+
46+
while #buffer_pool > MAX_BUFFER_POOL_SIZE do
47+
local buf = table.remove(buffer_pool, #buffer_pool)
48+
if api.nvim_buf_is_valid(buf) then
49+
api.nvim_buf_delete(buf, { force = true })
50+
end
51+
end
52+
end
53+
3254
--- @param winid integer
3355
--- @param context_winid integer?
3456
--- @param width integer
@@ -40,7 +62,7 @@ end
4062
local function display_window(winid, context_winid, width, height, col, ty, hl)
4163
if not context_winid then
4264
local sep = config.separator and { config.separator, 'TreesitterContextSeparator' } or nil
43-
context_winid = api.nvim_open_win(create_buf(), false, {
65+
context_winid = api.nvim_open_win(create_or_get_buf(), false, {
4466
win = winid,
4567
relative = 'win',
4668
width = width,
@@ -305,25 +327,13 @@ local function close(context_winid)
305327
end
306328

307329
local bufnr = api.nvim_win_get_buf(context_winid)
308-
if bufnr ~= nil then
309-
table.insert(retired_buffers, bufnr)
310-
end
311-
if api.nvim_win_is_valid(context_winid) then
312-
api.nvim_win_close(context_winid, true)
313-
end
314-
315-
if fn.getcmdwintype() ~= '' then
316-
-- Can't delete buffers when the command-line window is open.
317-
return
318-
end
319-
320-
-- Delete retired buffers.
321-
for _, retired_bufnr in ipairs(retired_buffers) do
322-
if api.nvim_buf_is_valid(retired_bufnr) then
323-
api.nvim_buf_delete(retired_bufnr, { force = true })
324-
end
330+
api.nvim_win_close(context_winid, true)
331+
if bufnr ~= nil and api.nvim_buf_is_valid(bufnr) then
332+
-- We can't delete the buffer in-place if the pool is full and the command-line window is open.
333+
-- Instead, add the buffer to the pool and let delete_excess_buffers() address this situation.
334+
table.insert(buffer_pool, bufnr)
325335
end
326-
retired_buffers = {}
336+
delete_excess_buffers()
327337
end)
328338
end
329339

0 commit comments

Comments
 (0)