Skip to content

Commit 1153bcc

Browse files
authored
Feature: respect vim.diagnostic.config.severity_sort (#1511)
* try sorting diagnostic severity * improve severity sort * sort by severity, line and col * make sorting async * fix floating pane
1 parent 13b3cdc commit 1153bcc

2 files changed

Lines changed: 83 additions & 20 deletions

File tree

lua/lspsaga/codeaction/preview.lua

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ local preview_buf, preview_winid
9090
---create a preview window according given window
9191
---default is under the given window
9292
local function create_preview_win(content, main_winid)
93+
-- Get the configuration of the main window
9394
local win_conf = api.nvim_win_get_config(main_winid)
9495
local opt = {
9596
relative = win_conf.relative,
@@ -98,45 +99,75 @@ local function create_preview_win(content, main_winid)
9899
anchor = win_conf.anchor,
99100
focusable = false,
100101
}
102+
103+
-- Determine content width and apply constraints
101104
local content_width = util.get_max_content_length(content)
102105
local max_win_width = api.nvim_win_get_width(win_conf.win)
103-
if content_width < win_conf.width then
104-
opt.width = win_conf.width
105-
else
106-
opt.width = math.min(max_win_width, content_width)
107-
end
106+
opt.width = math.min(max_win_width, math.max(content_width, win_conf.width))
107+
108+
-- Get dimensions of the main window
108109
local winheight = api.nvim_win_get_height(win_conf.win)
109110
local margin = config.ui.border == 'none' and 0 or 2
110111
local north = win_conf.anchor:sub(1, 1) == 'N'
111112
local row = util.is_ten and win_conf.row or win_conf.row[false]
112-
local valid_top_height = north and row - 1 or row - win_conf.height - margin - 1
113-
local valid_bot_height = north and winheight - row - win_conf.height - margin
114-
or winheight - row - margin
113+
114+
-- Calculate available space above (valid_top_height) and below (valid_bot_height)
115+
local valid_top_height = math.max(0, row - margin)
116+
local valid_bot_height = north and (winheight - row - win_conf.height - margin)
117+
or (winheight - row - margin)
118+
119+
-- Determine the preview window height
115120
local new_win_height = #content + margin
116-
-- action is NW under cursor and top is enough to show preview
117-
local east_or_west = win_conf.anchor:sub(2, 2)
118121
new_win_height = math.min(new_win_height, math.max(valid_bot_height, valid_top_height))
122+
123+
-- Adjust anchor and position based on available space
124+
local east_or_west = win_conf.anchor:sub(2, 2)
125+
119126
if north then
120127
if valid_top_height >= new_win_height then
121128
opt.anchor = 'S' .. east_or_west
122129
opt.row = row
123-
opt.height = math.min(valid_top_height, #content)
130+
opt.height = new_win_height
124131
elseif valid_bot_height >= new_win_height then
125132
opt.anchor = 'N' .. east_or_west
126133
opt.row = row + win_conf.height + margin
127-
opt.height = math.min(valid_bot_height, #content) - 2
134+
opt.height = new_win_height
135+
else
136+
-- Fallback: Fit within whichever space is larger
137+
if valid_top_height > valid_bot_height then
138+
opt.anchor = 'S' .. east_or_west
139+
opt.row = row
140+
opt.height = valid_top_height
141+
else
142+
opt.anchor = 'N' .. east_or_west
143+
opt.row = row + win_conf.height + margin
144+
opt.height = valid_bot_height
145+
end
128146
end
129147
else
130148
if valid_bot_height >= new_win_height then
131149
opt.anchor = 'N' .. east_or_west
132150
opt.row = row
133-
opt.height = math.min(valid_bot_height, #content)
134-
else
151+
opt.height = new_win_height
152+
elseif valid_top_height >= new_win_height then
135153
opt.anchor = 'S' .. east_or_west
136154
opt.row = row - win_conf.height - margin
137-
opt.height = math.min(valid_top_height, #content)
155+
opt.height = new_win_height
156+
else
157+
-- Fallback: Fit within whichever space is larger
158+
if valid_bot_height > valid_top_height then
159+
opt.anchor = 'N' .. east_or_west
160+
opt.row = row
161+
opt.height = valid_bot_height
162+
else
163+
opt.anchor = 'S' .. east_or_west
164+
opt.row = row - win_conf.height - margin
165+
opt.height = valid_top_height
166+
end
138167
end
139168
end
169+
170+
-- Create the preview window with calculated options and set content/buffer options.
140171
preview_buf, preview_winid = win
141172
:new_float(opt, false, true)
142173
:setlines(content)

lua/lspsaga/diagnostic/show.lua

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@ local function new_node()
3434
}
3535
end
3636

37-
---single linked list
38-
local function generate_list(entrys)
37+
local function create_linked_list(entrys)
3938
local list = new_node()
40-
4139
local curnode
4240
for _, item in ipairs(entrys) do
4341
if #list.diags == 0 then
@@ -53,6 +51,37 @@ local function generate_list(entrys)
5351
return list
5452
end
5553

54+
local function sort_entries(entrys)
55+
table.sort(entrys, function(a, b)
56+
if a.severity ~= b.severity then
57+
return a.severity < b.severity
58+
elseif a.lnum ~= b.lnum then
59+
return a.lnum < b.lnum
60+
else
61+
return a.col < b.col
62+
end
63+
end)
64+
end
65+
66+
---single linked list
67+
local function generate_list(entrys, callback)
68+
local diagnostic_config = vim.diagnostic.config and vim.diagnostic.config()
69+
local severity_sort_enabled = diagnostic_config and diagnostic_config.severity_sort
70+
71+
if severity_sort_enabled then
72+
vim.defer_fn(function()
73+
sort_entries(entrys)
74+
local list = create_linked_list(entrys)
75+
if callback then
76+
callback(list)
77+
end
78+
end, 0)
79+
return nil
80+
else
81+
return create_linked_list(entrys)
82+
end
83+
end
84+
5685
local function find_node(list, lnum)
5786
local curnode = list
5887
while curnode do
@@ -363,8 +392,11 @@ function sd:show_diagnostics(opt)
363392
if next(entrys) == nil then
364393
return
365394
end
366-
opt.entrys_list = generate_list(entrys)
367-
self:show(opt)
395+
396+
generate_list(entrys, function(sorted_list)
397+
opt.entrys_list = sorted_list
398+
self:show(opt)
399+
end)
368400
end
369401

370402
return setmetatable(ctx, sd)

0 commit comments

Comments
 (0)