@@ -351,41 +351,66 @@ function text_edits.write_to_dot_repeat(text_edit)
351
351
)
352
352
local chars_to_insert = text_edit .newText
353
353
354
- utils .with_no_autocmds (function ()
355
- local curr_win = vim .api .nvim_get_current_win ()
356
-
357
- -- create temporary floating window and buffer for writing
358
- local buf = get_dot_repeat_buffer ()
359
- local win = vim .api .nvim_open_win (buf , true , {
360
- relative = ' win' ,
361
- win = vim .api .nvim_get_current_win (),
362
- width = 1 ,
363
- height = 1 ,
364
- row = 0 ,
365
- col = 0 ,
366
- noautocmd = true ,
367
- })
368
- vim .api .nvim_buf_set_text (0 , 0 , 0 , 0 , 0 , { ' _' .. string.rep (' a' , chars_to_delete ) })
369
- vim .api .nvim_win_set_cursor (0 , { 1 , chars_to_delete + 1 })
370
-
371
- -- emulate builtin completion (dot repeat)
372
- local saved_completeopt = vim .opt .completeopt
373
- local saved_shortmess = vim .o .shortmess
374
- vim .opt .completeopt = ' '
375
- if not vim .o .shortmess :match (' c' ) then vim .o .shortmess = vim .o .shortmess .. ' c' end
376
- vim .fn .complete (1 , { ' _' .. chars_to_insert })
377
- vim .opt .completeopt = saved_completeopt
378
- vim .o .shortmess = saved_shortmess
379
-
380
- -- close window and focus original window
381
- vim .api .nvim_win_close (win , true )
382
- vim .api .nvim_set_current_win (curr_win )
383
-
384
- -- exit completion mode
385
- vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (' <Plug>BlinkCmpDotRepeatHack' , true , true , true ), ' in' , false )
354
+ utils .defer_neovide_redraw (function ()
355
+ utils .with_no_autocmds (function ()
356
+ local curr_win = vim .api .nvim_get_current_win ()
357
+
358
+ -- create temporary floating window and buffer for writing
359
+ local buf = get_dot_repeat_buffer ()
360
+ local win = vim .api .nvim_open_win (buf , true , {
361
+ relative = ' win' ,
362
+ win = vim .api .nvim_get_current_win (),
363
+ width = 1 ,
364
+ height = 1 ,
365
+ row = 0 ,
366
+ col = 0 ,
367
+ noautocmd = true ,
368
+ })
369
+ vim .api .nvim_buf_set_text (0 , 0 , 0 , 0 , 0 , { ' _' .. string.rep (' a' , chars_to_delete ) })
370
+ vim .api .nvim_win_set_cursor (0 , { 1 , chars_to_delete + 1 })
371
+
372
+ -- emulate builtin completion (dot repeat)
373
+ local saved_completeopt = vim .opt .completeopt
374
+ local saved_shortmess = vim .o .shortmess
375
+ vim .opt .completeopt = ' '
376
+ if not vim .o .shortmess :match (' c' ) then vim .o .shortmess = vim .o .shortmess .. ' c' end
377
+ vim .fn .complete (1 , { ' _' .. chars_to_insert })
378
+ vim .opt .completeopt = saved_completeopt
379
+ vim .o .shortmess = saved_shortmess
380
+
381
+ -- close window and focus original window
382
+ vim .api .nvim_win_close (win , true )
383
+ vim .api .nvim_set_current_win (curr_win )
384
+
385
+ -- exit completion mode
386
+ vim .api .nvim_feedkeys (
387
+ vim .api .nvim_replace_termcodes (' <Plug>BlinkCmpDotRepeatHack' , true , true , true ),
388
+ ' in' ,
389
+ false
390
+ )
391
+ end )
386
392
end )
387
393
end
388
394
395
+ --- Disable redraw in neovide for the duration of the callback
396
+ --- Useful for preventing the cursor from jumping to the top left during `vim.fn.complete`
397
+ --- @generic T
398
+ --- @param fn fun (): T
399
+ --- @return T
400
+ function utils .defer_neovide_redraw (fn )
401
+ if neovide and neovide .disable_redraw then neovide .disable_redraw () end
402
+
403
+ local success , result = pcall (fn )
404
+
405
+ -- make sure that the screen is updated and the mouse cursor returned to the right position before re-enabling redrawing
406
+ pcall (vim .api .nvim__redraw , { cursor = true , flush = true })
407
+
408
+ if neovide and neovide .enable_redraw then neovide .enable_redraw () end
409
+
410
+ if not success then error (result ) end
411
+ return result
412
+ end
413
+
389
414
--- Moves the cursor while preserving dot repeat
390
415
--- @param amount number Number of characters to move the cursor by , can be negative to move left
391
416
function text_edits .move_cursor_in_dot_repeat (amount )
0 commit comments