Skip to content

Commit d5943ac

Browse files
fredizzimoSaghen
andauthored
fix: disable Neovide drawing when setting up dot repeat (#1582)
* fix: disable Neovide drawing when setting up dot repeat * feat: `defer_neovide_redraw` helper --------- Co-authored-by: Liam Dyer <[email protected]>
1 parent 54c5c9c commit d5943ac

File tree

1 file changed

+57
-32
lines changed

1 file changed

+57
-32
lines changed

lua/blink/cmp/lib/text_edits.lua

+57-32
Original file line numberDiff line numberDiff line change
@@ -351,41 +351,66 @@ function text_edits.write_to_dot_repeat(text_edit)
351351
)
352352
local chars_to_insert = text_edit.newText
353353

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)
386392
end)
387393
end
388394

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+
389414
--- Moves the cursor while preserving dot repeat
390415
--- @param amount number Number of characters to move the cursor by, can be negative to move left
391416
function text_edits.move_cursor_in_dot_repeat(amount)

0 commit comments

Comments
 (0)