forked from sudo-tee/opencode.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnvim_cmp.lua
More file actions
146 lines (122 loc) · 3.73 KB
/
nvim_cmp.lua
File metadata and controls
146 lines (122 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
local Promise = require('opencode.promise')
local CompletionEngine = require('opencode.ui.completion.engines.base')
---@class NvimCmpEngine : CompletionEngine
local NvimCmpEngine = setmetatable({}, { __index = CompletionEngine })
NvimCmpEngine.__index = NvimCmpEngine
---Create a new nvim-cmp completion engine
---@return NvimCmpEngine
function NvimCmpEngine.new()
local self = CompletionEngine.new('nvim_cmp')
return setmetatable(self, NvimCmpEngine)
end
---Check if nvim-cmp is available
---@return boolean
function NvimCmpEngine:is_available()
local ok = pcall(require, 'cmp')
return ok and CompletionEngine.is_available()
end
---Setup nvim-cmp completion engine
---@param completion_sources table[]
---@return boolean
function NvimCmpEngine:setup(completion_sources)
local ok, cmp = pcall(require, 'cmp')
if not ok then
return false
end
CompletionEngine.setup(self, completion_sources)
local engine = self
local source = {}
function source.new()
return setmetatable({}, { __index = source })
end
function source:get_trigger_characters()
return engine:get_trigger_characters()
end
function source:is_available()
return engine:is_available()
end
function source:complete(params, callback)
Promise.spawn(function()
local line = params.context.cursor_line
local col = params.context.cursor.col
local before_cursor = line:sub(1, col - 1)
local trigger_char, trigger_match = engine:parse_trigger(before_cursor)
if not trigger_match then
callback({ items = {}, isIncomplete = false })
return
end
local context = {
input = trigger_match,
cursor_pos = col,
line = line,
trigger_char = trigger_char,
}
local wrapped_items = engine:get_completion_items(context):await()
local items = {}
for _, wrapped_item in ipairs(wrapped_items) do
local item = wrapped_item.original_item
table.insert(items, {
label = item.label,
kind = 1,
cmp = {
kind_text = item.kind_icon,
},
kind_hl_group = item.kind_hl,
detail = item.detail,
documentation = item.documentation,
insertText = item.insert_text or '',
sortText = string.format(
'%02d_%02d_%02d_%s',
wrapped_item.source_priority,
wrapped_item.item_priority,
wrapped_item.index,
item.label
),
data = {
original_item = item,
},
})
end
callback({ items = items, isIncomplete = true })
end)
end
cmp.register_source('opencode_mentions', source.new())
local config = cmp.get_config()
local sources = vim.deepcopy(config.sources or {})
cmp.setup.filetype({ 'opencode' }, {
sources = vim.list_extend(sources, {
{
name = 'opencode_mentions',
keyword_length = 1,
options = {},
},
}),
})
cmp.event:on('confirm_done', function(event)
local entry = event and event.entry
if entry and entry.source.name == 'opencode_mentions' then
local item_data = entry:get_completion_item().data
if item_data and item_data.original_item then
engine:on_complete(item_data.original_item)
end
end
end)
return true
end
---Check if nvim-cmp completion menu is visible
---@return boolean
function NvimCmpEngine:is_visible()
local ok, cmp = pcall(require, 'cmp')
return ok and cmp.visible()
end
---Trigger completion manually for nvim-cmp
---@param trigger_char string
function NvimCmpEngine:trigger(trigger_char)
vim.api.nvim_feedkeys(trigger_char, 'in', true)
local cmp = require('cmp')
if cmp.visible() then
cmp.close()
end
cmp.complete()
end
return NvimCmpEngine