@@ -20,6 +20,7 @@ local copilot = {
2020 cycling = nil ,
2121 cycling_callbacks = nil ,
2222 params = nil ,
23+ --- @type copilot_get_completions_data_completion[] | nil
2324 suggestions = nil ,
2425 choice = nil ,
2526 },
@@ -160,6 +161,7 @@ local function clear_preview()
160161 vim .api .nvim_buf_del_extmark (0 , copilot .ns_id , copilot .extmark_id )
161162end
162163
164+ --- @return copilot_get_completions_data_completion | nil
163165local function get_current_suggestion ()
164166 local ok , choice = pcall (function ()
165167 if
@@ -392,16 +394,16 @@ function mod.prev()
392394 end )
393395end
394396
395- --- @param partial ? ' word ' | ' line '
396- local function accept_suggestion ( partial )
397+ --- @param modifier ? ( fun ( suggestion : copilot_get_completions_data_completion ): copilot_get_completions_data_completion )
398+ function mod . accept ( modifier )
397399 local suggestion = get_current_suggestion ()
398400 if not suggestion or vim .fn .empty (suggestion .text ) == 1 then
399401 return
400402 end
401403
402404 reset_state ()
403405 with_client (function (client )
404- if partial then
406+ if modifier then
405407 -- do not notify_accepted for partial accept.
406408 -- revisit if upstream copilot.vim adds this feature.
407409 return
@@ -412,48 +414,53 @@ local function accept_suggestion(partial)
412414 copilot .uuid = nil
413415 clear_preview ()
414416
417+ if type (modifier ) == " function" then
418+ suggestion = modifier (suggestion )
419+ end
420+
415421 local range , newText = suggestion .range , suggestion .text
416422
417- if partial then
423+ -- Hack for 'autoindent', makes the indent persist. Check `:help 'autoindent'`.
424+ vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (" <Space><Left><Del>" , true , false , true ), " n" , false )
425+ vim .lsp .util .apply_text_edits ({ { range = range , newText = newText } }, 0 , " utf-16" )
426+ -- Put cursor at the end of current line.
427+ vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (" <End>" , true , false , true ), " n" , false )
428+ end
429+
430+ function mod .accept_word ()
431+ mod .accept (function (suggestion )
432+ local range , text = suggestion .range , suggestion .text
433+
418434 local cursor = vim .api .nvim_win_get_cursor (0 )
419435 local _ , character = cursor [1 ], cursor [2 ]
420436
421- if partial == " word" then
422- local _ , char_idx = string.find (newText , " %s*%p*[^%s%p]*%s*" , character + 1 )
423- if not char_idx then
424- return
425- end
426-
427- newText = string.sub (newText , 1 , char_idx )
437+ local _ , char_idx = string.find (text , " %s*%p*[^%s%p]*%s*" , character + 1 )
438+ if char_idx then
439+ suggestion .text = string.sub (text , 1 , char_idx )
428440
429441 range [" end" ].line = range [" start" ].line
430442 range [" end" ].character = char_idx
431- elseif partial == " line" then
432- local next_char = string.sub (newText , character + 1 , character + 1 )
433- local _ , char_idx = string.find (newText , next_char == " \n " and " \n %s*[^\n ]*\n %s*" or " \n %s*" , character )
434- if char_idx then
435- newText = string.sub (newText , 1 , char_idx )
436- end
437443 end
438- end
439444
440- -- Hack for 'autoindent', makes the indent persist. Check `:help 'autoindent'`.
441- vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (" <Space><Left><Del>" , true , false , true ), " n" , false )
442- vim .lsp .util .apply_text_edits ({ { range = range , newText = newText } }, 0 , " utf-16" )
443- -- Put cursor at the end of current line.
444- vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (" <End>" , true , false , true ), " n" , false )
445+ return suggestion
446+ end )
445447end
446448
447- function mod .accept ()
448- accept_suggestion ( )
449- end
449+ function mod .accept_line ()
450+ mod . accept ( function ( suggestion )
451+ local text = suggestion . text
450452
451- function mod .accept_word ()
452- accept_suggestion (" word" )
453- end
453+ local cursor = vim .api .nvim_win_get_cursor (0 )
454+ local _ , character = cursor [1 ], cursor [2 ]
454455
455- function mod .accept_line ()
456- accept_suggestion (" line" )
456+ local next_char = string.sub (text , character + 1 , character + 1 )
457+ local _ , char_idx = string.find (text , next_char == " \n " and " \n %s*[^\n ]*\n %s*" or " \n %s*" , character )
458+ if char_idx then
459+ suggestion .text = string.sub (text , 1 , char_idx )
460+ end
461+
462+ return suggestion
463+ end )
457464end
458465
459466function mod .dismiss ()
0 commit comments