@@ -153,4 +153,95 @@ M.build_completion = function(macros, raw)
153153 return completion
154154end
155155
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+
156247return M
0 commit comments