echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
5.02k stars 185 forks source link

mini.pairs: Input lag for {<CR>} expansion #839

Closed cthoma closed 5 months ago

cthoma commented 5 months ago

Contributing guidelines

Module(s)

mini.pairs

Description

I very much appreciate the work and effort that is being put into the mini plugin collection, but I have something to complain, and maybe a solution for it.

pairs.lua:390

-- Precomputed keys to increase speed
-- stylua: ignore start
local function escape(s) return vim.api.nvim_replace_termcodes(s, true, true, true) end
H.keys = {
  above     = escape('<C-o>O'), -- <<<< This is the offending line.
  bs        = escape('<bs>'),
  cr        = escape('<cr>'),
  del       = escape('<del>'),
  keep_undo = escape('<C-g>U'),
  -- NOTE: use `get_arrow_key()` instead of `H.keys.left` or `H.keys.right`
  left      = escape('<left>'),
  right     = escape('<right>')
}
-- stylua: ignore end

The issue arises from the fact the <C-o>O is used to add a blank line between opening and closing curly braces. This mapping brings us briefly into normal mode, which triggers events we don't need -- that's what causes the lag. A blank line above is all we want.

I rewrote the offending line to above = escape('<cr><up><C-f>'). This sequence keeps us in insert mode and there is no lag.

<C-f> ... reindent current line :h i_CTRL-F

Neovim version

-

Steps to reproduce

-

Expected behavior

No response

Actual behavior

-

echasnovski commented 5 months ago

Thanks for the issue!

This was already brought up and discussed in #626 with a detailed resolution in this comment.

However, I think I like the idea of using <C-f> for re-indent, but not with <Up> as it might be disabled by some users and seems to break some later remapping (like to work well with 'mini.completion'). Maybe <C-g>k could work, though.

That said, direct keys replace breaks tests and I did not manage to quickly figure out why exactly. Will take a look later.

echasnovski commented 5 months ago

This should now be fixed on latest main.

Although using <C-f> instead of O was promising, it has some problems. It does not necessarily reindents but puts directly ^F (needs either 'cindent' or 'indentexpr' option). Even disabling it with the equivalent of :autocmd InsertCharPre * if v:char == "\<C-F>" | let v:char = '' | endif, involving manual <Up> navigation has issues that it breaks the undo blocks (expanding in <CR> will need two u to fully undo).

The current approach of temporarily ignoring some events seems like the best alternative. It does not add much overhead (around 0.002 ms if triggered inside a pair), so let's hope there will not be any other unwatned side effects.