Skip to content

Commit 3adfad5

Browse files
committed
refactor: general tidy up
- Remove `getcmdwintype()` check in Render.close(). Check is already done in `close()` which was added with multiwindow support. Should no longer be needed higher up. - Combine `Render.close_other_contexts()` and `Render.close_leaked_contexts()` into `Render.close_contexts()`. - Remove unnecessary tables in `is_after()`. - Inline `delete_excess_buffers()`. - Collapse some code. - Rename `update_single_context()` to `update_win()`. - Fix typing of config module.
1 parent 436f65e commit 3adfad5

File tree

4 files changed

+65
-105
lines changed

4 files changed

+65
-105
lines changed

lua/treesitter-context.lua

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,14 @@ local attached = {} --- @type table<integer,true>
7474

7575
--- @param args table
7676
local function au_close(args)
77-
if args.event == 'WinClosed' then
78-
-- Closing current window instead of intended window may lead to context window flickering.
79-
Render.close(tonumber(args.match))
80-
else
81-
Render.close(api.nvim_get_current_win())
82-
end
77+
-- Closing current window instead of intended window may lead to context window flickering.
78+
local winid = args.event == 'WinClosed' and tonumber(args.match) or api.nvim_get_current_win()
79+
Render.close(winid)
8380
end
8481

85-
--- @param bufnr integer
8682
--- @param winid integer
87-
local function cannot_open(bufnr, winid)
83+
local function cannot_open(winid)
84+
local bufnr = api.nvim_win_get_buf(winid)
8885
return not attached[bufnr]
8986
or vim.bo[bufnr].filetype == ''
9087
or vim.bo[bufnr].buftype ~= ''
@@ -93,28 +90,28 @@ local function cannot_open(bufnr, winid)
9390
end
9491

9592
--- @param winid integer
96-
local update_single_context = throttle_by_id(function(winid)
93+
local update_win = throttle_by_id(function(winid)
9794
-- Remove leaked contexts firstly.
98-
local current_win = api.nvim_get_current_win()
99-
if config.multiwindow then
100-
Render.close_leaked_contexts()
101-
else
102-
Render.close_other_contexts(current_win)
103-
end
95+
-- Contexts may sometimes leak due to reasons like the use of 'noautocmd'.
96+
-- In these cases, affected windows might remain visible, and even ToggleContext
97+
-- won't resolve the issue, as contexts are identified using parent windows.
98+
-- Therefore, it's essential to occasionally perform garbage collection to
99+
-- clean up these leaked contexts.
100+
Render.close_contexts(config.multiwindow and api.nvim_list_wins() or { winid })
104101

105102
-- Since the update is performed asynchronously, the window may be closed at this moment.
106103
-- Therefore, we need to check if it is still valid.
107104
if not api.nvim_win_is_valid(winid) or vim.fn.getcmdtype() ~= '' then
108105
return
109106
end
110107

111-
local bufnr = api.nvim_win_get_buf(winid)
112-
113-
if cannot_open(bufnr, winid) or not config.multiwindow and winid ~= current_win then
108+
if cannot_open(winid) or not config.multiwindow and winid ~= api.nvim_get_current_win() then
114109
Render.close(winid)
115110
return
116111
end
117112

113+
local bufnr = api.nvim_win_get_buf(winid)
114+
118115
local context_ranges, context_lines = require('treesitter-context.context').get(bufnr, winid)
119116
all_contexts[bufnr] = context_ranges
120117

@@ -133,14 +130,13 @@ local multiwindow_events = {
133130

134131
--- @param event? string
135132
local function update(event)
136-
if config.multiwindow and multiwindow_events[event] then
137-
-- Resizing a single window may cause many resizes in different windows,
138-
-- so it is necessary to iterate over all windows when a WinResized event is received.
139-
for _, winid in pairs(api.nvim_list_wins()) do
140-
update_single_context(winid)
141-
end
142-
else
143-
update_single_context(api.nvim_get_current_win())
133+
-- Resizing a single window may cause many resizes in different windows,
134+
-- so it is necessary to iterate over all windows when a WinResized event is received.
135+
local wins = (config.multiwindow and multiwindow_events[event]) and api.nvim_list_wins()
136+
or { api.nvim_get_current_win() }
137+
138+
for _, win in ipairs(wins) do
139+
update_win(win)
144140
end
145141
end
146142

@@ -295,6 +291,7 @@ local did_init = false
295291
function M.setup(options)
296292
-- NB: setup may be called several times.
297293
if options then
294+
--- @diagnostic disable-next-line: undefined-field
298295
config.update(options)
299296
end
300297

lua/treesitter-context/config.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,10 @@ function M.update(cfg)
6868
config = vim.tbl_deep_extend('force', config, cfg)
6969
end
7070

71-
--- @type TSContext.Config
7271
setmetatable(M, {
7372
__index = function(_, k)
7473
return config[k]
7574
end,
7675
})
7776

78-
return M
77+
return M --[[@as TSContext.Config]]

lua/treesitter-context/context.lua

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,17 @@ end
5151
local function max_lines_from_string(winid, percent)
5252
local win_height = api.nvim_win_get_height(winid)
5353
local percent_s = percent:match('^(%d+)%%$')
54-
local percent = percent_s and tonumber(percent_s, 10) or 0
55-
return math.ceil((percent / 100.0) * win_height)
54+
local percent1 = percent_s and tonumber(percent_s, 10) or 0
55+
return math.ceil((percent1 / 100) * win_height)
5656
end
5757

5858
--- @param winid integer
5959
--- @return integer
6060
local function calc_max_lines(winid)
61-
local max_lines --- @type integer
61+
local max_lines = config.max_lines
6262

63-
if type(config.max_lines) == 'string' then
64-
max_lines = max_lines_from_string(winid, config.max_lines)
65-
else
66-
max_lines = config.max_lines --- @type integer
63+
if type(max_lines) == 'string' then
64+
max_lines = max_lines_from_string(winid, max_lines)
6765
end
6866

6967
-- ensure we never have zero as max lines

lua/treesitter-context/render.lua

Lines changed: 36 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,6 @@ local function create_or_get_buf()
3737
return buf
3838
end
3939

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-
5440
--- @param winid integer
5541
--- @param context_winid integer?
5642
--- @param width integer
@@ -138,11 +124,13 @@ local function get_hl(buf_query, capture)
138124
end
139125

140126
--- Is a position a after another position b?
141-
--- @param a [integer, integer] [row, col]
142-
--- @param b [integer, integer] [row, col]
127+
--- @param arow integer
128+
--- @param acol integer
129+
--- @param brow integer
130+
--- @param bcol integer
143131
--- @return boolean
144-
local function is_after(a, b)
145-
return a[1] > b[1] or (a[1] == b[1] and a[2] > b[2])
132+
local function is_after(arow, acol, brow, bcol)
133+
return arow > brow or (arow == brow and acol > bcol)
146134
end
147135

148136
--- @param bufnr integer
@@ -182,10 +170,10 @@ local function highlight_contexts(bufnr, ctx_bufnr, contexts)
182170
local nsrow, nscol, nerow, necol = range[1], range[2], range[4], range[5]
183171

184172
if nsrow >= start_row then
185-
if is_after({ nsrow, nscol }, { end_row, end_col }) then
173+
if is_after(nsrow, nscol, end_row, end_col) then
186174
-- Node range begins after the context range, skip it
187175
break
188-
elseif is_after({ nerow, necol }, { end_row, end_col }) then
176+
elseif is_after(nerow, necol, end_row, end_col) then
189177
-- Node range extends beyond the context range, clip it
190178
nerow, necol = end_row, end_col
191179
end
@@ -355,18 +343,28 @@ end
355343
--- @param context_winid? integer
356344
local function close(context_winid)
357345
vim.schedule(function()
358-
if context_winid == nil or not api.nvim_win_is_valid(context_winid) then
346+
if not context_winid or not api.nvim_win_is_valid(context_winid) then
359347
return
360348
end
361349

362350
local bufnr = api.nvim_win_get_buf(context_winid)
363351
api.nvim_win_close(context_winid, true)
364-
if bufnr ~= nil and api.nvim_buf_is_valid(bufnr) then
365-
-- We can't delete the buffer in-place if the pool is full and the command-line window is open.
366-
-- Instead, add the buffer to the pool and let delete_excess_buffers() address this situation.
367-
table.insert(buffer_pool, bufnr)
352+
353+
-- Add the buffer back to the pool for reuse.
354+
if bufnr and api.nvim_buf_is_valid(bufnr) then
355+
buffer_pool[#buffer_pool + 1] = bufnr
356+
end
357+
358+
-- Delete excess buffers in the pool.
359+
-- Can't delete buffers when the command-line window is open.
360+
if fn.getcmdwintype() == '' then
361+
while #buffer_pool > MAX_BUFFER_POOL_SIZE do
362+
local buf = table.remove(buffer_pool, #buffer_pool)
363+
if api.nvim_buf_is_valid(buf) then
364+
api.nvim_buf_delete(buf, { force = true })
365+
end
366+
end
368367
end
369-
delete_excess_buffers()
370368
end)
371369
end
372370

@@ -400,18 +398,15 @@ local function copy_extmarks(bufnr, ctx_bufnr, contexts)
400398
)
401399

402400
for _, m in ipairs(extmarks) do
403-
local id = m[1]
404-
local row = m[2]
405-
local col = m[3] --[[@as integer]]
401+
local id, row, col = m[1], m[2], m[3]
406402
local opts = m[4] --[[@as vim.api.keyset.extmark_details]]
407-
408403
local start_row = offset + (row - ctx_srow)
409404

410405
local end_row --- @type integer?
411406
local end_col = opts.end_col
412407
local mend_row = opts.end_row
413408
if mend_row then
414-
if is_after({ mend_row, end_col }, { ctx_erow, ctx_ecol }) then
409+
if is_after(mend_row, assert(end_col), ctx_erow, ctx_ecol) then
415410
mend_row = ctx_erow
416411
end_col = ctx_ecol
417412
end
@@ -454,34 +449,6 @@ end
454449

455450
local M = {}
456451

457-
-- Contexts may sometimes leak due to reasons like the use of 'noautocmd'.
458-
-- In these cases, affected windows might remain visible, and even ToggleContext
459-
-- won't resolve the issue, as contexts are identified using parent windows.
460-
-- Therefore, it's essential to occasionally perform garbage collection to
461-
-- clean up these leaked contexts.
462-
function M.close_leaked_contexts()
463-
local all_wins = api.nvim_list_wins()
464-
465-
for parent_winid, window_context in pairs(window_contexts) do
466-
if not vim.tbl_contains(all_wins, parent_winid) then
467-
close(window_context.context_winid)
468-
close(window_context.gutter_winid)
469-
window_contexts[parent_winid] = nil
470-
end
471-
end
472-
end
473-
474-
--- @param winid integer The only window for which the context should be displayed.
475-
function M.close_other_contexts(winid)
476-
for parent_winid, window_context in pairs(window_contexts) do
477-
if parent_winid ~= winid then
478-
close(window_context.context_winid)
479-
close(window_context.gutter_winid)
480-
window_contexts[parent_winid] = nil
481-
end
482-
end
483-
end
484-
485452
--- @param bufnr integer
486453
--- @param winid integer
487454
--- @param ctx_ranges Range4[]
@@ -544,24 +511,23 @@ function M.open(bufnr, winid, ctx_ranges, ctx_lines)
544511
horizontal_scroll_contexts(winid, window_context.context_winid)
545512
end
546513

547-
--- @param winid? integer
548-
function M.close(winid)
549-
-- Can't close other windows when the command-line window is open
550-
if fn.getcmdwintype() ~= '' then
551-
return
552-
end
553-
554-
if winid == nil then
555-
return
514+
--- @param exclude_winids integer[] The only window for which the context should be displayed.
515+
function M.close_contexts(exclude_winids)
516+
for winid in pairs(window_contexts) do
517+
if not vim.tbl_contains(exclude_winids, winid) then
518+
M.close(winid)
519+
end
556520
end
521+
end
557522

523+
--- @param winid integer
524+
function M.close(winid)
558525
local window_context = window_contexts[winid]
559526
if window_context then
560527
close(window_context.context_winid)
561528
close(window_context.gutter_winid)
529+
window_contexts[winid] = nil
562530
end
563-
564-
window_contexts[winid] = nil
565531
end
566532

567533
return M

0 commit comments

Comments
 (0)