@@ -153,4 +153,95 @@ M.build_completion = function(macros, raw)
153
153
return completion
154
154
end
155
155
156
+ local registered_cmp_sources = {}
157
+ M .build_cmp_source = function (name , macros )
158
+ if registered_cmp_sources [name ] then
159
+ logger .debug (" cmp source " .. name .. " already registered" )
160
+ return nil
161
+ end
162
+ local source = {}
163
+
164
+ source .new = function ()
165
+ return setmetatable ({}, { __index = source })
166
+ end
167
+
168
+ source .get_trigger_characters = function ()
169
+ return { " @" , " " }
170
+ end
171
+
172
+ local completion = M .build_completion (macros , true )
173
+
174
+ source .complete = function (self , params , callback )
175
+ local ctx = params .context
176
+ local suggestions , triggered = completion (ctx .cursor_before_line :match (" %S*$" ), ctx .cursor_line , ctx .cursor .col )
177
+
178
+ if not triggered and not ctx .cursor_before_line :match (" %s*@%S*$" ) then
179
+ suggestions = {}
180
+ end
181
+
182
+ logger .debug (" macro completion suggestions: " .. vim .inspect (suggestions ))
183
+
184
+ local items = {}
185
+ for _ , suggestion in ipairs (suggestions ) do
186
+ table.insert (items , {
187
+ label = suggestion ,
188
+ kind = require (" cmp" ).lsp .CompletionItemKind .Keyword ,
189
+ documentation = name ,
190
+ })
191
+ end
192
+ logger .debug (" macro cmp complete output: " .. vim .inspect (items ))
193
+
194
+ callback (items )
195
+ end
196
+
197
+ local has_cmp , cmp = pcall (require , " cmp" )
198
+ if not has_cmp then
199
+ logger .warning (" cmp not found, skipping cmp source registration" )
200
+ return source
201
+ end
202
+
203
+ cmp .register_source (name , source )
204
+ registered_cmp_sources [name ] = true
205
+
206
+ if true then
207
+ return source
208
+ end
209
+
210
+ cmp .event :on (" complete_done" , function (event )
211
+ if not event or not event .entry or event .entry .source .name ~= name then
212
+ return
213
+ end
214
+ local ctx = event .entry .source .context
215
+ local suggestions , triggered = completion (ctx .cursor_before_line :match (" %S*$" ), ctx .cursor_line , ctx .cursor .col )
216
+ logger .debug (
217
+ " macro cmp complete_done suggestions: " .. vim .inspect (suggestions ) .. " triggered: " .. vim .inspect (triggered )
218
+ )
219
+ if not suggestions or not triggered then
220
+ return
221
+ end
222
+
223
+ vim .schedule (function ()
224
+ -- insert a space if not already present at the cursor
225
+ local cursor_col = vim .api .nvim_win_get_cursor (0 )[2 ]
226
+ local line = vim .api .nvim_get_current_line ()
227
+ logger .debug (
228
+ " macro cmp complete_done cursor_col: "
229
+ .. cursor_col
230
+ .. " line: "
231
+ .. line
232
+ .. " char: "
233
+ .. line :sub (cursor_col , cursor_col )
234
+ )
235
+ if line :sub (cursor_col , cursor_col ) ~= " " then
236
+ vim .api .nvim_put ({ " " }, " c" , false , true )
237
+ end
238
+ vim .schedule (function ()
239
+ cmp .complete (suggestions )
240
+ end )
241
+ end )
242
+ end )
243
+
244
+ return source
245
+ end
246
+
156
247
return M
0 commit comments