Skip to content

Commit a67af93

Browse files
committed
feat(filter): add show_diags_only_under_cursor option. Fixes #156
1 parent 63dd87d commit a67af93

5 files changed

Lines changed: 87 additions & 17 deletions

File tree

.beads/issues.jsonl

Whitespace-only changes.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ require("tiny-inline-diagnostic").setup({
198198
-- Show all diagnostics on the current cursor line, not just those under the cursor
199199
show_all_diags_on_cursorline = false,
200200

201+
-- Only show diagnostics when the cursor is directly over them, no fallback to line diagnostics
202+
show_diags_only_under_cursor = false,
203+
201204
-- Display related diagnostics from LSP relatedInformation
202205
show_related = {
203206
enabled = true, -- Enable displaying related diagnostics

lua/tiny-inline-diagnostic/filter.lua

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ function M.at_position(opts, diagnostics, line, col)
3737
return diag.lnum == line and col >= diag.col and col <= diag.end_col
3838
end, diagnostics)
3939

40-
return #current_pos_diags > 0 and current_pos_diags or diags_on_line
40+
if opts.options.show_diags_only_under_cursor then
41+
return current_pos_diags
42+
else
43+
return #current_pos_diags > 0 and current_pos_diags or diags_on_line
44+
end
4145
end
4246

4347
---@param related_info table
@@ -82,6 +86,28 @@ local function extract_related_diagnostics(diag, max_count)
8286
return related
8387
end
8488

89+
---@param opts table
90+
---@param diagnostics table
91+
---@return table
92+
local function add_related_diagnostics(opts, diagnostics)
93+
if not opts.options.show_related or not opts.options.show_related.enabled then
94+
return diagnostics
95+
end
96+
97+
local result = {}
98+
local max_count = opts.options.show_related.max_count or 3
99+
100+
for _, diag in ipairs(diagnostics) do
101+
table.insert(result, diag)
102+
if has_related_info(diag) then
103+
local related = extract_related_diagnostics(diag, max_count)
104+
vim.list_extend(result, related)
105+
end
106+
end
107+
108+
return result
109+
end
110+
85111
---@param opts table
86112
---@param buf number
87113
---@param diagnostics table
@@ -101,22 +127,7 @@ function M.under_cursor(opts, buf, diagnostics)
101127

102128
filtered_diags = M.by_severity(opts, filtered_diags)
103129

104-
if not opts.options.show_related or not opts.options.show_related.enabled then
105-
return filtered_diags
106-
end
107-
108-
local result = {}
109-
local max_count = opts.options.show_related.max_count or 3
110-
111-
for _, diag in ipairs(filtered_diags) do
112-
table.insert(result, diag)
113-
if has_related_info(diag) then
114-
local related = extract_related_diagnostics(diag, max_count)
115-
vim.list_extend(result, related)
116-
end
117-
end
118-
119-
return result
130+
return add_related_diagnostics(opts, filtered_diags)
120131
end
121132

122133
---@param opts table
@@ -128,6 +139,22 @@ function M.for_display(opts, bufnr, diagnostics)
128139
return M.under_cursor(opts, bufnr, diagnostics)
129140
end
130141

142+
if opts.options.show_diags_only_under_cursor then
143+
local cursor_pos = vim.api.nvim_win_get_cursor(0)
144+
local current_line = cursor_pos[1] - 1
145+
146+
local under_cursor_on_line = M.at_position(opts, diagnostics, current_line, cursor_pos[2])
147+
148+
local other_diags = vim.tbl_filter(function(diag)
149+
return diag.lnum ~= current_line
150+
end, diagnostics)
151+
152+
local result = vim.list_extend({}, under_cursor_on_line)
153+
vim.list_extend(result, other_diags)
154+
result = M.by_severity(opts, result)
155+
return add_related_diagnostics(opts, result)
156+
end
157+
131158
if opts.options.multilines.always_show then
132159
local under_cursor = M.under_cursor(opts, bufnr, diagnostics)
133160
local multiline_diags = diagnostics

lua/tiny-inline-diagnostic/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ local default_config = {
5050
severity = nil,
5151
},
5252
show_all_diags_on_cursorline = false,
53+
show_diags_only_under_cursor = false,
5354
enable_on_insert = false,
5455
enable_on_select = false,
5556
format = nil,

tests/test_filter.lua

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ T["at_position"]["returns line diagnostics when cursor not in range"] = function
5656
MiniTest.expect.equality(#result, 2)
5757
end
5858

59+
T["at_position"]["returns empty when show_diags_only_under_cursor enabled and cursor not in range"] = function()
60+
local diagnostics = {
61+
H.make_diagnostic({ lnum = 5, col = 10, end_col = 20 }),
62+
H.make_diagnostic({ lnum = 5, col = 30, end_col = 40 }),
63+
}
64+
65+
local result = filter.at_position({ options = { show_diags_only_under_cursor = true } }, diagnostics, 5, 0)
66+
MiniTest.expect.equality(#result, 0)
67+
end
68+
5969
T["under_cursor"] = MiniTest.new_set()
6070

6171
T["under_cursor"]["returns empty for invalid buffer"] = function()
@@ -276,4 +286,33 @@ T["for_display"]["filters by multilines.severity when always_show is false"] = f
276286
end)
277287
end
278288

289+
T["for_display"]["show_diags_only_under_cursor with multilines shows under cursor on current line and all on other lines"] = function()
290+
H.with_win_buf({ "line1", "line2", "line3" }, { 2, 0 }, nil, function(buf)
291+
local diagnostics = {
292+
H.make_diagnostic({ lnum = 0, col = 0, end_col = 5 }), -- line 1
293+
H.make_diagnostic({ lnum = 0, col = 10, end_col = 15 }), -- line 1, not under cursor
294+
H.make_diagnostic({ lnum = 1, col = 0, end_col = 5 }), -- line 2 (current line)
295+
H.make_diagnostic({ lnum = 2, col = 0, end_col = 5 }), -- line 3
296+
}
297+
298+
local result = filter.for_display({
299+
options = {
300+
multilines = { enabled = true },
301+
show_diags_only_under_cursor = true,
302+
},
303+
}, buf, diagnostics)
304+
305+
-- Should show: all from line 1 (other line), 1 diag from line 2 (under cursor), 1 from line 3
306+
MiniTest.expect.equality(#result, 4)
307+
-- Check that we have diagnostics from all lines
308+
local lines = {}
309+
for _, diag in ipairs(result) do
310+
lines[diag.lnum] = (lines[diag.lnum] or 0) + 1
311+
end
312+
MiniTest.expect.equality(lines[0], 2) -- line 1
313+
MiniTest.expect.equality(lines[1], 1) -- line 2 (current)
314+
MiniTest.expect.equality(lines[2], 1) -- line 3
315+
end)
316+
end
317+
279318
return T

0 commit comments

Comments
 (0)