-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: save unused buffers in buffer pool #536
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,11 @@ local config = require('treesitter-context.config') | |
|
||
local ns = api.nvim_create_namespace('nvim-treesitter-context') | ||
|
||
--- List of buffers that are to be deleted. | ||
--- List of free buffers that can be reused. | ||
---@type integer[] | ||
local retired_buffers = {} | ||
local buffer_pool = {} | ||
|
||
local BUFFER_POOL_SIZE = 20 | ||
|
||
--- @class WindowContext | ||
--- @field context_winid integer? The context window ID. | ||
|
@@ -20,15 +22,43 @@ local retired_buffers = {} | |
local window_contexts = {} | ||
|
||
--- @return integer buf | ||
local function create_buf() | ||
local function create_or_get_buf() | ||
for index = #buffer_pool, 1, -1 do | ||
local buf = buffer_pool[index] | ||
table.remove(buffer_pool, index) | ||
if api.nvim_buf_is_valid(buf) then | ||
return buf | ||
end | ||
end | ||
|
||
local buf = api.nvim_create_buf(false, true) | ||
|
||
vim.bo[buf].undolevels = -1 | ||
vim.bo[buf].bufhidden = 'wipe' | ||
|
||
return buf | ||
end | ||
|
||
local function delete_excess_buffers() | ||
if fn.getcmdwintype() ~= '' then | ||
-- Can't delete buffers when the command-line window is open. | ||
return | ||
end | ||
|
||
local new_buffers_pool = {} --- @type integer[] | ||
|
||
for _, bufnr in ipairs(buffer_pool) do | ||
if api.nvim_buf_is_valid(bufnr) then | ||
if #new_buffers_pool < BUFFER_POOL_SIZE then | ||
table.insert(new_buffers_pool, bufnr) | ||
else | ||
api.nvim_buf_delete(bufnr, { force = true }) | ||
lewis6991 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
end | ||
end | ||
|
||
buffer_pool = new_buffers_pool | ||
end | ||
|
||
--- @param winid integer | ||
--- @param context_winid integer? | ||
--- @param width integer | ||
|
@@ -40,7 +70,7 @@ end | |
local function display_window(winid, context_winid, width, height, col, ty, hl) | ||
if not context_winid then | ||
local sep = config.separator and { config.separator, 'TreesitterContextSeparator' } or nil | ||
context_winid = api.nvim_open_win(create_buf(), false, { | ||
context_winid = api.nvim_open_win(create_or_get_buf(), false, { | ||
win = winid, | ||
relative = 'win', | ||
width = width, | ||
|
@@ -305,25 +335,11 @@ local function close(context_winid) | |
end | ||
|
||
local bufnr = api.nvim_win_get_buf(context_winid) | ||
if bufnr ~= nil then | ||
table.insert(retired_buffers, bufnr) | ||
end | ||
if api.nvim_win_is_valid(context_winid) then | ||
api.nvim_win_close(context_winid, true) | ||
end | ||
|
||
if fn.getcmdwintype() ~= '' then | ||
-- Can't delete buffers when the command-line window is open. | ||
return | ||
end | ||
|
||
-- Delete retired buffers. | ||
for _, retired_bufnr in ipairs(retired_buffers) do | ||
if api.nvim_buf_is_valid(retired_bufnr) then | ||
api.nvim_buf_delete(retired_bufnr, { force = true }) | ||
end | ||
api.nvim_win_close(context_winid, true) | ||
if bufnr ~= nil and api.nvim_buf_is_valid(bufnr) then | ||
table.insert(buffer_pool, bufnr) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that the only entry point to actually inserting a buffer into the pool is here, so can't we avoid need for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't delete buffers in-place, when the command-line window is open, see #507 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's not what is being suggested? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I understand, no. If the pool is at capacity and we don't add a buffer, we'll need to delete one. However, if the command-line window is open, we cannot proceed with the deletion. Regardless, sometimes we have to add the buffer to the pool even if the pool is full. While I could introduce another 'if' branch to handle the case when the pool if full and we are not in command-line mode, I doubt it would enhance performance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However, I'm not certain it's a good idea to check all buffers in the pool within the delete_excess_buffers function. We might just delete the last buffers in the list instead. I don't believe the buffers will become invalid without a reason. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah tricky, well the improved implementation should do though! |
||
end | ||
retired_buffers = {} | ||
delete_excess_buffers() | ||
end) | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This option deletes the buffer after the window is closed. It appears that the problem existed before multi-window support was introduced.