Skip to content

Commit bfb1d76

Browse files
committed
fix: completion async
1 parent 96e9f2d commit bfb1d76

File tree

4 files changed

+146
-138
lines changed

4 files changed

+146
-138
lines changed

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

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,59 +26,61 @@ function Source:is_available()
2626
return vim.bo.filetype == 'opencode'
2727
end
2828

29-
Source.get_completions = Promise.async(function(self, ctx, callback)
30-
local completion = require('opencode.ui.completion')
31-
local completion_sources = completion.get_sources()
32-
33-
local line = ctx.line
34-
local col = ctx.cursor[2] + 1
35-
local before_cursor = line:sub(1, col - 1)
29+
function Source:get_completions(ctx, callback)
30+
Promise.spawn(function()
31+
local completion = require('opencode.ui.completion')
32+
local completion_sources = completion.get_sources()
3633

37-
local trigger_chars = table.concat(vim.tbl_map(vim.pesc, self:get_trigger_characters()), '')
38-
local trigger_char, trigger_match = before_cursor:match('([' .. trigger_chars .. '])([%w_/%-%.]*)$')
34+
local line = ctx.line
35+
local col = ctx.cursor[2] + 1
36+
local before_cursor = line:sub(1, col - 1)
3937

40-
if not trigger_match then
41-
callback({ is_incomplete_forward = false, items = {} })
42-
return
43-
end
38+
local trigger_chars = table.concat(vim.tbl_map(vim.pesc, self:get_trigger_characters()), '')
39+
local trigger_char, trigger_match = before_cursor:match('([' .. trigger_chars .. '])([%w_/%-%.]*)$')
4440

45-
local context = {
46-
input = trigger_match,
47-
cursor_pos = col,
48-
line = line,
49-
trigger_char = trigger_char,
50-
}
41+
if not trigger_match then
42+
callback({ is_incomplete_forward = false, items = {} })
43+
return
44+
end
5145

52-
local items = {}
53-
for _, completion_source in ipairs(completion_sources) do
54-
local source_items = completion_source.complete(context):await()
55-
for i, item in ipairs(source_items) do
56-
table.insert(items, {
57-
label = item.label,
58-
kind = item.kind,
59-
kind_icon = item.kind_icon,
60-
kind_hl = item.kind_hl,
61-
detail = item.detail,
62-
documentation = item.documentation,
63-
insertText = item.insert_text or item.label,
64-
sortText = string.format(
65-
'%02d_%02d_%02d_%s',
66-
completion_source.priority or 999,
67-
item.priority or 999,
68-
i,
69-
item.label
70-
),
71-
score_offset = -(completion_source.priority or 999) * 1000 + (item.priority or 999),
72-
73-
data = {
74-
original_item = item,
75-
},
76-
})
46+
local context = {
47+
input = trigger_match,
48+
cursor_pos = col,
49+
line = line,
50+
trigger_char = trigger_char,
51+
}
52+
53+
local items = {}
54+
for _, completion_source in ipairs(completion_sources) do
55+
local source_items = completion_source.complete(context):await()
56+
for i, item in ipairs(source_items) do
57+
table.insert(items, {
58+
label = item.label,
59+
kind = item.kind,
60+
kind_icon = item.kind_icon,
61+
kind_hl = item.kind_hl,
62+
detail = item.detail,
63+
documentation = item.documentation,
64+
insertText = item.insert_text or item.label,
65+
sortText = string.format(
66+
'%02d_%02d_%02d_%s',
67+
completion_source.priority or 999,
68+
item.priority or 999,
69+
i,
70+
item.label
71+
),
72+
score_offset = -(completion_source.priority or 999) * 1000 + (item.priority or 999),
73+
74+
data = {
75+
original_item = item,
76+
},
77+
})
78+
end
7779
end
78-
end
7980

80-
callback({ is_incomplete_forward = true, is_incomplete_backward = true, items = items })
81-
end)
81+
callback({ is_incomplete_forward = true, is_incomplete_backward = true, items = items })
82+
end)
83+
end
8284

8385
function Source:execute(ctx, item, callback, default_implementation)
8486
default_implementation()

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

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local Promise = require('opencode.promise')
12
local M = {}
23

34
function M.setup(completion_sources)
@@ -27,57 +28,59 @@ function M.setup(completion_sources)
2728
return vim.bo.filetype == 'opencode'
2829
end
2930

30-
source.complete = Promise.async(function(self, params, callback)
31-
local line = params.context.cursor_line
31+
function source:complete(params, callback)
32+
Promise.spawn(function()
33+
local line = params.context.cursor_line
3234

33-
local col = params.context.cursor.col
34-
local before_cursor = line:sub(1, col - 1)
35+
local col = params.context.cursor.col
36+
local before_cursor = line:sub(1, col - 1)
3537

36-
local trigger_chars = table.concat(vim.tbl_map(vim.pesc, self:get_trigger_characters()), '')
37-
local trigger_char, trigger_match = before_cursor:match('.*([' .. trigger_chars .. '])([%w_%-%.]*)')
38+
local trigger_chars = table.concat(vim.tbl_map(vim.pesc, self:get_trigger_characters()), '')
39+
local trigger_char, trigger_match = before_cursor:match('.*([' .. trigger_chars .. '])([%w_%-%.]*)')
3840

39-
if not trigger_match then
40-
callback({ items = {}, isIncomplete = false })
41-
return
42-
end
43-
44-
local context = {
45-
input = trigger_match,
46-
cursor_pos = col,
47-
line = line,
48-
trigger_char = trigger_char,
49-
}
41+
if not trigger_match then
42+
callback({ items = {}, isIncomplete = false })
43+
return
44+
end
5045

51-
local items = {}
52-
for _, completion_source in ipairs(completion_sources) do
53-
local source_items = completion_source.complete(context):await()
54-
for j, item in ipairs(source_items) do
55-
table.insert(items, {
56-
label = item.label,
57-
kind = 1,
58-
cmp = {
59-
kind_text = item.kind_icon,
60-
},
61-
kind_hl_group = item.kind_hl,
62-
detail = item.detail,
63-
documentation = item.documentation,
64-
insertText = item.insert_text or '',
65-
sortText = string.format(
66-
'%02d_%02d_%02d_%s',
67-
completion_source.priority or 999,
68-
item.priority or 999,
69-
j,
70-
item.label
71-
),
72-
data = {
73-
original_item = item,
74-
},
75-
})
46+
local context = {
47+
input = trigger_match,
48+
cursor_pos = col,
49+
line = line,
50+
trigger_char = trigger_char,
51+
}
52+
53+
local items = {}
54+
for _, completion_source in ipairs(completion_sources) do
55+
local source_items = completion_source.complete(context):await()
56+
for j, item in ipairs(source_items) do
57+
table.insert(items, {
58+
label = item.label,
59+
kind = 1,
60+
cmp = {
61+
kind_text = item.kind_icon,
62+
},
63+
kind_hl_group = item.kind_hl,
64+
detail = item.detail,
65+
documentation = item.documentation,
66+
insertText = item.insert_text or '',
67+
sortText = string.format(
68+
'%02d_%02d_%02d_%s',
69+
completion_source.priority or 999,
70+
item.priority or 999,
71+
j,
72+
item.label
73+
),
74+
data = {
75+
original_item = item,
76+
},
77+
})
78+
end
7679
end
77-
end
7880

79-
callback({ items = items, isIncomplete = true })
80-
end)
81+
callback({ items = items, isIncomplete = true })
82+
end)
83+
end
8184

8285
cmp.register_source('opencode_mentions', source.new())
8386

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

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local Promise = require('lua.opencode.promise')
12
local M = {}
23

34
local completion_active = false
@@ -58,59 +59,61 @@ function M.trigger(trigger_char)
5859
end
5960

6061
function M._update()
61-
if not completion_active then
62-
return
63-
end
64-
65-
local line = vim.api.nvim_get_current_line()
66-
local col = vim.api.nvim_win_get_cursor(0)[2]
67-
local before_cursor = line:sub(1, col)
68-
local trigger_char, trigger_match = M._get_trigger(before_cursor)
62+
Promise.spawn(function()
63+
if not completion_active then
64+
return
65+
end
6966

70-
if not trigger_char then
71-
completion_active = false
72-
return
73-
end
67+
local line = vim.api.nvim_get_current_line()
68+
local col = vim.api.nvim_win_get_cursor(0)[2]
69+
local before_cursor = line:sub(1, col)
70+
local trigger_char, trigger_match = M._get_trigger(before_cursor)
7471

75-
local context = {
76-
input = trigger_match,
77-
cursor_pos = col + 1,
78-
line = line,
79-
trigger_char = trigger_char,
80-
}
72+
if not trigger_char then
73+
completion_active = false
74+
return
75+
end
8176

82-
local items = {}
83-
for _, source in ipairs(M._completion_sources or {}) do
84-
local source_items = source.complete(context)
85-
for i, item in ipairs(source_items) do
86-
if vim.startswith(item.insert_text or '', trigger_char) then
87-
item.insert_text = item.insert_text:sub(2)
77+
local context = {
78+
input = trigger_match,
79+
cursor_pos = col + 1,
80+
line = line,
81+
trigger_char = trigger_char,
82+
}
83+
84+
local items = {}
85+
for _, source in ipairs(M._completion_sources or {}) do
86+
local source_items = source.complete(context):await()
87+
for i, item in ipairs(source_items) do
88+
if vim.startswith(item.insert_text or '', trigger_char) then
89+
item.insert_text = item.insert_text:sub(2)
90+
end
91+
local source_priority = source.priority or 999
92+
local item_priority = item.priority or 999
93+
table.insert(items, {
94+
word = #item.insert_text > 0 and item.insert_text or item.label,
95+
abbr = (item.kind_icon or '') .. item.label,
96+
menu = source.name,
97+
kind = item.kind:sub(1, 1):upper(),
98+
user_data = item,
99+
_sort_text = string.format('%02d_%02d_%02d_%s', source_priority, item_priority, i, item.label),
100+
})
88101
end
89-
local source_priority = source.priority or 999
90-
local item_priority = item.priority or 999
91-
table.insert(items, {
92-
word = #item.insert_text > 0 and item.insert_text or item.label,
93-
abbr = (item.kind_icon or '') .. item.label,
94-
menu = source.name,
95-
kind = item.kind:sub(1, 1):upper(),
96-
user_data = item,
97-
_sort_text = string.format('%02d_%02d_%02d_%s', source_priority, item_priority, i, item.label),
98-
})
99102
end
100-
end
101103

102-
table.sort(items, function(a, b)
103-
return a._sort_text < b._sort_text
104-
end)
104+
table.sort(items, function(a, b)
105+
return a._sort_text < b._sort_text
106+
end)
105107

106-
if #items > 0 then
107-
local start_col = before_cursor:find(vim.pesc(trigger_char) .. '[%w_%-%.]*$')
108-
if start_col then
109-
vim.fn.complete(start_col + 1, items)
108+
if #items > 0 then
109+
local start_col = before_cursor:find(vim.pesc(trigger_char) .. '[%w_%-%.]*$')
110+
if start_col then
111+
vim.fn.complete(start_col + 1, items)
112+
end
113+
else
114+
completion_active = false
110115
end
111-
else
112-
completion_active = false
113-
end
116+
end)
114117
end
115118

116119
M.on_complete = function()

lua/opencode/ui/completion/files.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ local file_source = {
121121
return {}
122122
end
123123

124-
local recent_files = #input < 1 and M.get_recent_files() or {}
124+
local recent_files = #input < 1 and M.get_recent_files():await() or {}
125125
if #recent_files >= 5 then
126126
return recent_files
127127
end

0 commit comments

Comments
 (0)