Skip to content

Commit fa78e2b

Browse files
committed
fix: force hl update on diagnostics and LSP
Not a complete fix, but should solve most issues. Also only copy extmarks from the `nvim.*` namespace. Fixes #509
1 parent bf87eaa commit fa78e2b

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

lua/treesitter-context.lua

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ local function cannot_open(winid)
8787
end
8888

8989
--- @param winid integer
90-
local update_win = throttle_by_id(function(winid)
90+
--- @param force_hl_update? boolean
91+
local update_win = throttle_by_id(function(winid, force_hl_update)
9192
-- Remove leaked contexts firstly.
9293
-- Contexts may sometimes leak due to reasons like the use of 'noautocmd'.
9394
-- In these cases, affected windows might remain visible, and even ToggleContext
@@ -114,14 +115,19 @@ local update_win = throttle_by_id(function(winid)
114115
return
115116
end
116117

117-
Render.open(winid, context_ranges, assert(context_lines))
118+
Render.open(winid, context_ranges, assert(context_lines), force_hl_update)
118119
end)
119120

120121
local multiwindow_events = {
121122
WinResized = true,
122123
User = true,
123124
}
124125

126+
local force_hl_events = {
127+
DiagnosticChanged = true,
128+
LspRequest = true,
129+
}
130+
125131
--- @param event? string
126132
local function update(event)
127133
-- Resizing a single window may cause many resizes in different windows,
@@ -130,7 +136,7 @@ local function update(event)
130136
or { api.nvim_get_current_win() }
131137

132138
for _, win in ipairs(wins) do
133-
update_win(win)
139+
update_win(win, force_hl_events[event])
134140
end
135141
end
136142

@@ -226,15 +232,13 @@ function M.enable()
226232
autocmd('User', au_close, { pattern = 'SessionSavePre' })
227233
autocmd('User', au_update, { pattern = 'SessionSavePost' })
228234

229-
if vim.fn.has('nvim-0.10') == 1 then
230-
autocmd('LspRequest', function(args)
231-
if is_semantic_tokens_request(args.data.request) then
232-
vim.schedule(function()
233-
au_update(args)
234-
end)
235-
end
236-
end)
237-
end
235+
autocmd('LspRequest', function(args)
236+
if is_semantic_tokens_request(args.data.request) then
237+
vim.schedule(function()
238+
au_update(args)
239+
end)
240+
end
241+
end)
238242

239243
update()
240244

lua/treesitter-context/render.lua

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,21 @@ local function copy_extmarks(bufnr, ctx_bufnr, contexts)
397397
{ details = true }
398398
)
399399

400+
local namespaces = {} --- @type table<integer, true>
401+
for nm, id in pairs(api.nvim_get_namespaces()) do
402+
-- Only copy extmarks from core as they are the only ones we can update
403+
-- reliably.
404+
if vim.startswith(nm, 'nvim.') then
405+
namespaces[id] = true
406+
end
407+
end
408+
409+
--- @param e vim.api.keyset.get_extmark_item
410+
extmarks = vim.tbl_filter(function(e)
411+
local opts = e[4] --[[@as vim.api.keyset.extmark_details]]
412+
return namespaces[opts.ns_id]
413+
end, extmarks)
414+
400415
for _, m in ipairs(extmarks) do
401416
local id, row, col = m[1], m[2], m[3]
402417
local opts = m[4] --[[@as vim.api.keyset.extmark_details]]
@@ -452,7 +467,8 @@ local M = {}
452467
--- @param winid integer
453468
--- @param ctx_ranges Range4[]
454469
--- @param ctx_lines string[]
455-
function M.open(winid, ctx_ranges, ctx_lines)
470+
--- @param force_hl_update? boolean
471+
function M.open(winid, ctx_ranges, ctx_lines, force_hl_update)
456472
local bufnr = api.nvim_win_get_buf(winid)
457473
local gutter_width = get_gutter_width(winid)
458474
local win_width = math.max(1, api.nvim_win_get_width(winid) - gutter_width)
@@ -499,16 +515,16 @@ function M.open(winid, ctx_ranges, ctx_lines)
499515

500516
local ctx_bufnr = api.nvim_win_get_buf(window_context.context_winid)
501517

502-
if not set_lines(ctx_bufnr, ctx_lines) then
503-
-- Context didn't change, can return here
504-
return
505-
end
518+
local changed = set_lines(ctx_bufnr, ctx_lines)
506519

507-
api.nvim_buf_clear_namespace(ctx_bufnr, -1, 0, -1)
508-
highlight_contexts(bufnr, ctx_bufnr, ctx_ranges)
509-
copy_extmarks(bufnr, ctx_bufnr, ctx_ranges)
510-
highlight_bottom(ctx_bufnr, win_height - 1, 'TreesitterContextBottom')
511-
horizontal_scroll_contexts(winid, window_context.context_winid)
520+
if changed or force_hl_update then
521+
-- Update highlights
522+
api.nvim_buf_clear_namespace(ctx_bufnr, -1, 0, -1)
523+
highlight_contexts(bufnr, ctx_bufnr, ctx_ranges)
524+
copy_extmarks(bufnr, ctx_bufnr, ctx_ranges)
525+
highlight_bottom(ctx_bufnr, win_height - 1, 'TreesitterContextBottom')
526+
horizontal_scroll_contexts(winid, window_context.context_winid)
527+
end
512528
end
513529

514530
--- @param exclude_winids integer[] The only window for which the context should be displayed.

0 commit comments

Comments
 (0)