Skip to content

Commit ad83284

Browse files
committed
feat(completion): better sorting for context items
1 parent 141c9e8 commit ad83284

File tree

6 files changed

+57
-18
lines changed

6 files changed

+57
-18
lines changed

lua/opencode/types.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
---@field documentation string Documentation text
304304
---@field insert_text string Text to insert when selected
305305
---@field source_name string Name of the completion source
306+
---@field priority? number Optional priority for individual item sorting (lower numbers have higher priority)
306307
---@field data table Additional data associated with the item
307308

308309
---@class CompletionSource

lua/opencode/ui/completion/context.lua

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ local state = require('opencode.state')
44
local icons = require('opencode.ui.icons')
55

66
local M = {}
7+
local kind_priority = {
8+
selection_item = 3,
9+
mentioned_file = 4,
10+
subagent = 5,
11+
}
712

813
---@generic T
914
---@param name string
@@ -13,7 +18,7 @@ local M = {}
1318
---@param icon string|nil
1419
---@param additional_data? T
1520
---@return CompletionItem
16-
local function create_context_item(name, type, available, documentation, icon, additional_data)
21+
local function create_context_item(name, type, available, documentation, icon, additional_data, priority)
1722
local label = name
1823

1924
return {
@@ -24,6 +29,7 @@ local function create_context_item(name, type, available, documentation, icon, a
2429
documentation = documentation or (available and name or 'Enable ' .. name .. ' for this message'),
2530
insert_text = '',
2631
source_name = 'context',
32+
priority = priority or (available and 100 or 200),
2733
data = { type = type, name = name, available = available, additional_data = additional_data },
2834
}
2935
end
@@ -100,7 +106,15 @@ local function add_mentioned_files_items(ctx)
100106
local filename = vim.fn.fnamemodify(file, ':~:.')
101107
table.insert(
102108
items,
103-
create_context_item(filename, 'mentioned_file', true, 'Select to remove file ' .. filename, icons.get('file'))
109+
create_context_item(
110+
filename,
111+
'mentioned_file',
112+
true,
113+
'Select to remove file ' .. filename,
114+
icons.get('file'),
115+
nil,
116+
kind_priority.mentioned_file
117+
)
104118
)
105119
end
106120
end
@@ -125,7 +139,15 @@ local function add_selection_items(ctx)
125139
string.format('Selection %d %s (%s)', i, selection.file and selection.file.name or 'Untitled', selection.lines)
126140
table.insert(
127141
items,
128-
create_context_item(label, 'selection_item', true, format_selection(selection), icons.get('selection'), selection)
142+
create_context_item(
143+
label,
144+
'selection_item',
145+
true,
146+
format_selection(selection),
147+
icons.get('selection'),
148+
selection,
149+
kind_priority.selection_item
150+
)
129151
)
130152
end
131153
return items
@@ -141,7 +163,15 @@ local function add_subagents_items(ctx)
141163
for _, agent in ipairs(ctx.mentioned_subagents or {}) do
142164
table.insert(
143165
items,
144-
create_context_item(agent .. ' (agent)', 'subagent', true, 'Select to remove agent ' .. agent, icons.get('agent'))
166+
create_context_item(
167+
agent .. ' (agent)',
168+
'subagent',
169+
true,
170+
'Select to remove agent ' .. agent,
171+
icons.get('agent'),
172+
nil,
173+
kind_priority.subagent
174+
)
145175
)
146176
end
147177
return items
@@ -198,13 +228,6 @@ local context_source = {
198228
end, items)
199229
end
200230

201-
table.sort(items, function(a, b)
202-
if a.data.available ~= b.data.available then
203-
return a.data.available
204-
end
205-
return a.label < b.label
206-
end)
207-
208231
return items
209232
end,
210233
on_complete = function(item)

lua/opencode/ui/completion/engines/blink_cmp.lua

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,15 @@ function Source:get_completions(ctx, callback)
6464
detail = item.detail,
6565
documentation = item.documentation,
6666
insertText = item.insert_text or item.label,
67-
sortText = string.format('%02d_%02d_%s', completion_source.priority or 999, i, item.label),
68-
score_offset = -(completion_source.priority or 999) * 1000,
67+
sortText = string.format(
68+
'%02d_%02d_%02d_%s',
69+
completion_source.priority or 999,
70+
item.priority or 999,
71+
i,
72+
item.label
73+
),
74+
score_offset = -(completion_source.priority or 999) * 1000 + (item.priority or 999),
75+
6976
data = {
7077
original_item = item,
7178
},

lua/opencode/ui/completion/engines/nvim_cmp.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function M.setup(completion_sources)
6262
detail = item.detail,
6363
documentation = item.documentation,
6464
insertText = item.insert_text or item.label,
65-
sortText = string.format('%02d_%02d_%s', completion_source.priority or 999, j, item.label),
65+
sortText = string.format('%02d_%02d_%02d_%s', completion_source.priority or 999, item.priority or 999, j, item.label),
6666
data = {
6767
original_item = item,
6868
},

lua/opencode/ui/completion/engines/vim_complete.lua

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,27 @@ function M._update()
8787
local items = {}
8888
for _, source in ipairs(M._completion_sources or {}) do
8989
local source_items = source.complete(context)
90-
for _, item in ipairs(source_items) do
90+
for i, item in ipairs(source_items) do
9191
if vim.startswith(item.insert_text or '', trigger_char) then
9292
item.insert_text = item.insert_text:sub(2)
9393
end
94+
local source_priority = source.priority or 999
95+
local item_priority = item.priority or 999
9496
table.insert(items, {
9597
word = #item.insert_text > 0 and item.insert_text or item.label,
9698
abbr = (item.kind_icon or '') .. item.label,
9799
menu = source.name,
98100
kind = item.kind:sub(1, 1):upper(),
99101
user_data = item,
102+
_sort_text = string.format('%02d_%02d_%02d_%s', source_priority, item_priority, i, item.label),
100103
})
101104
end
102105
end
103106

107+
table.sort(items, function(a, b)
108+
return a._sort_text < b._sort_text
109+
end)
110+
104111
if #items > 0 then
105112
local start_col = before_cursor:find(vim.pesc(trigger_char) .. '[%w_%-%.]*$')
106113
if start_col then

lua/opencode/ui/completion/files.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ end
7979

8080
---@param file string
8181
---@return CompletionItem
82-
local function create_file_item(file, suffix)
82+
local function create_file_item(file, suffix, priority)
8383
local filename = vim.fn.fnamemodify(file, ':t')
8484
local dir = vim.fn.fnamemodify(file, ':h')
8585
local file_path = dir == '.' and filename or dir .. '/' .. filename
@@ -101,6 +101,7 @@ local function create_file_item(file, suffix)
101101
documentation = 'Path: ' .. detail,
102102
insert_text = file_path,
103103
source_name = 'files',
104+
priority = priority,
104105
data = { name = filename, full_path = full_path },
105106
}
106107
end
@@ -126,7 +127,7 @@ local file_source = {
126127
end
127128

128129
local files_and_dirs = find_files_fast(input)
129-
local items = vim.tbl_map(create_file_item, files_and_dirs)
130+
local items = vim.tbl_map(function(file) return create_file_item(file, nil, 10) end, files_and_dirs)
130131
sort_util.sort_by_relevance(items, input, function(item)
131132
return vim.fn.fnamemodify(item.label, ':t')
132133
end, function(a, b)
@@ -155,7 +156,7 @@ function M.get_recent_files()
155156
if result then
156157
for _, file in ipairs(result) do
157158
local suffix = table.concat({ file.added and '+' .. file.added, file.removed and '-' .. file.removed }, ' ')
158-
table.insert(recent_files, create_file_item(file.path, ' ' .. suffix))
159+
table.insert(recent_files, create_file_item(file.path, ' ' .. suffix, 1))
159160
end
160161
end
161162
return recent_files

0 commit comments

Comments
 (0)