echasnovski / mini.nvim

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

Conflict between mini.animate scrolling effect and vim-cool clearing search highlights on cursor move #611

Closed gitaarik closed 9 months ago

gitaarik commented 9 months ago

Contributing guidelines

Module(s)

mini.animate

Description

I'm using mini.animate for enabling smooth scrolling in Nvim. I also use a plugin vim-cool which clears search highlights when you move the cursor.

When I search for a pattern, then press "n" to go to the next result, and the next result is so far below that mini.animate will trigger a scrolling effect, then the search results are not highlighted anymore.

The problem is that I think that mini.animate actually moves the cursor, simulating the scrolling effect, I guess. But that clears the search highlight unintended. See the screen recording below.

mini-animate-vim-cool

Now I figured I could use the MiniAnimateDoneScroll event to execute set hlsearch when the scroll is done. Like this:

vim.api.nvim_create_autocmd("User", {
  pattern = "MiniAnimateDoneScroll",
  callback = function()
    vim.defer_fn(function()
      vim.cmd("set hlsearch")
    end, 0)
  end,
})

And that actually works (note that the defer_fn is necessary), but now the problem is that this is always executed after each scroll animation. And I only want to set hlsearch when I was actually searching, not when I scroll manually with <Ctrl-D> for example.

So I thought maybe I can save the current hlsearch state before the animation starts. But there doesn't seem to be an event for that. Does anybody have an idea or suggestion for this?

echasnovski commented 9 months ago

Yes, both scroll and resize animations are done with side effects. And yes, scroll animation actually moves cursor to show smoother cursor transition. Plus sometimes it is necessary to move cursor to show intermediate window view, as only view which contains cursor can be set.

The solution of this issue can be something along the line of this suggestion for n keymap which centers current line and opens folds.

Closing as scroll and resize animation indeed need extra work to play nicely with other plugins/functionality (if at all possible).

gitaarik commented 9 months ago

Ok, I managed to make it work with these keybindings:

vim.keymap.set("n", "n", "<cmd>let g:search_in_progress=1<cr>n", { noremap = true })
vim.keymap.set("n", "*", "<cmd>let g:search_in_progress=1<cr>*", { noremap = true })
vim.keymap.set("n", "N", "<cmd>let g:search_in_progress=1<cr>N", { noremap = true })

And then I only do set hlsearch when g:search_in_progress is 1, and then set it back to 0:

vim.api.nvim_create_autocmd("User", {
  pattern = "MiniAnimateDoneScroll",
  callback = function()
    vim.defer_fn(function()
      if vim.g.search_in_progress == 1 then
        vim.cmd("set hlsearch")
        vim.g.search_in_progress = 0
      end
    end, 0)
  end,
})

And that actually seems to work good! Thanks for your suggestion!