Skip to content

Commit fa384d6

Browse files
committed
refactor: use CompletionItem.command
1 parent da52c5b commit fa384d6

11 files changed

Lines changed: 143 additions & 355 deletions

File tree

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,6 @@ require('opencode').setup({
236236
snacks_layout = nil -- `layout` opts to pass to Snacks.picker.pick({ layout = ... })
237237
},
238238
completion = {
239-
supports_kind_icons = false, -- set to true if your completion engine supports kind icons (blink does) it will show icons with proper highlight instead of a generic kind icon
240-
use_native_completion = false, -- Set to true if you use native nvim completion otherwise it might not auto trigger in the input window.
241239
file_sources = {
242240
enabled = true,
243241
preferred_cli_tool = 'server', -- 'fd','fdfind','rg','git','server' if nil, it will use the best available tool, 'server' uses opencode cli to get file list (works cross platform) and supports folders

ftplugin/opencode.lua

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,9 @@ local bufnr = vim.api.nvim_get_current_buf()
1010
local opencode_ls = require('opencode.lsp.opencode_ls')
1111
local client_id = opencode_ls.start(bufnr)
1212
local completion = require('opencode.ui.completion')
13-
local config = require('opencode.config')
14-
local use_native_completion = config.ui.completion.use_native_completion
15-
16-
if client_id then
17-
local augroup = vim.api.nvim_create_augroup('OpencodeLSP', { clear = true })
18-
-- track insert start state
19-
vim.api.nvim_create_autocmd('InsertEnter', {
20-
group = augroup,
21-
buffer = bufnr,
22-
callback = function()
23-
if use_native_completion then
24-
vim.lsp.completion.enable(true, client_id, bufnr, { autotrigger = true })
25-
end
26-
completion.on_insert_enter()
27-
end,
28-
})
29-
30-
vim.api.nvim_create_autocmd('TextChangedI', {
31-
group = augroup,
32-
buffer = bufnr,
33-
callback = function(e)
34-
completion.on_text_changed()
35-
end,
36-
})
37-
38-
vim.api.nvim_create_autocmd('InsertLeave', {
39-
group = augroup,
40-
buffer = bufnr,
41-
callback = function()
42-
completion.clear_pending()
43-
end,
44-
})
45-
46-
vim.api.nvim_create_autocmd({ 'CompleteDone' }, {
47-
group = augroup,
48-
buffer = bufnr,
49-
callback = function(e)
50-
completion.on_complete_done_event()
51-
end,
52-
})
13+
if client_id and not completion.has_completion_engine() then
14+
pcall(function()
15+
vim.bo.completeopt = 'menu,menuone,noselect,fuzzy'
16+
vim.lsp.completion.enable(true, client_id, bufnr, { autotrigger = true })
17+
end)
5318
end

lua/opencode/config.lua

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ M.defaults = {
149149
snacks_layout = nil,
150150
},
151151
completion = {
152-
supports_kind_icons = false,
153-
use_native_completion = false,
154152
file_sources = {
155153
enabled = true,
156154
preferred_cli_tool = 'server',
@@ -286,18 +284,11 @@ function M.setup(opts)
286284

287285
update_keymap_prefix(M.values.keymap_prefix, M.defaults.keymap_prefix)
288286

289-
-- Legacy completion settings handling
290287
if opts.preferred_completion then
291288
vim.notify(
292-
'[opencode.nvim] "preferred_completion" is deprecated. Please configure completion "ui.completion" table.',
289+
'[opencode.nvim] "preferred_completion" is deprecated and has no effect. Please remove it from your config.',
293290
vim.log.levels.WARN
294291
)
295-
if opts.preferred_completion == 'vim_complete' then
296-
M.values.ui.completion.use_native_completion = true
297-
end
298-
if opts.preferred_completion == 'blink' then
299-
M.values.ui.completion.supports_kind_icons = true
300-
end
301292
end
302293
end
303294

lua/opencode/keymap.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
local M = {}
22

33
local function is_completion_visible()
4-
local ok, completion = pcall(require, 'opencode.ui.completion')
5-
return ok and completion.is_visible()
4+
return require('opencode.ui.completion').is_completion_visible()
65
end
76

87
local function wrap_with_completion_check(key_binding, callback)

lua/opencode/lsp/opencode_ls.lua

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
local config = require('opencode.config')
21
---In-process LSP server for opencode completion
32
---Provides completion for files, subagents, commands, and context items
43
---Works with any LSP-compatible completion plugin (blink.cmp, nvim-cmp, etc.)
@@ -21,6 +20,9 @@ handlers[ms.initialize] = function(params, callback)
2120
resolveProvider = false,
2221
triggerCharacters = triggers,
2322
},
23+
executeCommandProvider = {
24+
commands = { 'opencode.completion_done' },
25+
},
2426
},
2527
serverInfo = {
2628
name = 'opencode_ls',
@@ -29,6 +31,21 @@ handlers[ms.initialize] = function(params, callback)
2931
})
3032
end
3133

34+
handlers[ms.workspace_executeCommand] = function(params, callback)
35+
if params.command == 'opencode.completion_done' then
36+
local item = params.arguments and params.arguments[1]
37+
if item then
38+
require('opencode.ui.completion').on_completion_done(item)
39+
end
40+
callback(nil, nil)
41+
else
42+
callback({
43+
code = -32601,
44+
message = 'Method not found: ' .. tostring(params.command),
45+
}, nil)
46+
end
47+
end
48+
3249
---Get word to complete from cursor position
3350
---@param params lsp.CompletionParams
3451
---@return string word_to_complete
@@ -63,18 +80,21 @@ local function get_completion_context(params)
6380
end
6481

6582
function M.supports_kind_icons()
66-
return config.ui.completion.supports_kind_icons
83+
return require('opencode.ui.completion').supports_kind_icons()
6784
end
6885

6986
---Convert opencode CompletionItem to LSP CompletionItem
7087
---@param item CompletionItem
7188
---@param index integer
72-
---@return lsp.CompletionItem
89+
---@return OpencodeLspItem
7390
local function to_lsp_item(item, index)
7491
local source = require('opencode.ui.completion').get_source_by_name(item.source_name)
92+
local kind = (source and source.custom_kind) or vim.lsp.protocol.CompletionItemKind.Function ---@type lsp.CompletionItemKind
93+
local priority = source and source.priority or 999
94+
---@type OpencodeLspItem
7595
local lsp_item = {
7696
label = (M.supports_kind_icons() and '' or item.kind_icon .. ' ') .. item.label,
77-
kind = source.custom_kind or vim.lsp.protocol.CompletionItemKind.Function,
97+
kind = kind,
7898
kind_hl = item.kind_hl,
7999
kind_icon = M.supports_kind_icons() and item.kind_icon or '',
80100
detail = item.detail,
@@ -85,7 +105,12 @@ local function to_lsp_item(item, index)
85105
insertText = item.insert_text or item.label,
86106
insertTextFormat = vim.lsp.protocol.InsertTextFormat.PlainText,
87107
filterText = item.label,
88-
sortText = string.format('%02d_%02d_%02d_%s', source.priority or 999, item.priority or 999, index, item.label),
108+
sortText = string.format('%02d_%02d_%02d_%s', priority, item.priority or 999, index, item.label),
109+
command = {
110+
title = 'opencode.completion_done',
111+
command = 'opencode.completion_done',
112+
arguments = { item },
113+
},
89114
data = {
90115
source_name = item.source_name,
91116
original_data = item.data,
@@ -103,10 +128,12 @@ handlers[ms.textDocument_completion] = function(params, callback)
103128
local word, trigger_char, line = get_completion_context(params)
104129

105130
-- Build completion context
131+
---@type CompletionContext
106132
local completion_context = {
107133
input = word,
108134
trigger_char = trigger_char,
109135
line = line,
136+
cursor_pos = params.position.character,
110137
}
111138

112139
local completion = require('opencode.ui.completion')
@@ -121,6 +148,7 @@ handlers[ms.textDocument_completion] = function(params, callback)
121148

122149
Promise.all(promises)
123150
:and_then(function(results)
151+
---@type OpencodeLspItem[]
124152
local all_items = {}
125153
local is_incomplete = false
126154

@@ -136,7 +164,6 @@ handlers[ms.textDocument_completion] = function(params, callback)
136164
end
137165

138166
callback(nil, { isIncomplete = is_incomplete, items = all_items })
139-
completion.store_completion_items(all_items)
140167
end)
141168
:catch(function(err)
142169
local log = require('opencode.log')

lua/opencode/types.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@
107107

108108
---@class OpencodeCompletionConfig
109109
---@field file_sources OpencodeCompletionFileSourcesConfig
110-
---@field supports_kind_icons boolean
111-
---@field use_native_completion boolean
112110

113111
---@class OpencodeLoadingAnimationConfig
114112
---@field frames string[]
@@ -416,6 +414,12 @@
416414
---@field get_trigger_character? fun(): string|nil Optional function returning the trigger character for this source
417415
---@field custom_kind? integer Custom LSP CompletionItemKind registered for this source
418416

417+
---Extended LSP completion item with opencode-specific rendering fields
418+
---@class OpencodeLspItem : lsp.CompletionItem
419+
---@field kind lsp.CompletionItemKind
420+
---@field kind_hl? string Highlight group for the kind icon
421+
---@field kind_icon string Icon string for the kind
422+
419423
---@class OpencodeContext
420424
---@field current_file OpencodeContextFile|nil
421425
---@field cursor_data OpencodeContextCursorData|nil

0 commit comments

Comments
 (0)