okuuva / auto-save.nvim

🧶 Automatically save your changes in NeoVim
GNU General Public License v3.0
168 stars 9 forks source link

Unwanted autosave occurs in insert mode when pressing Enter inside `{}` #57

Closed andreasacwu closed 3 weeks ago

andreasacwu commented 2 months ago

I'm experiencing an issue where an unwanted autosave is triggered while in insert mode. This happens specifically when I press Enter inside empty curly braces {}. All configs the same as the default.

primeapple commented 2 months ago

Wow, good find. I can reproduce that. Will have a look!

torbjornvatn commented 2 months ago

I have the same issue I use the https://github.com/stevearc/conform.nvim plugin installed via LazyVim as well

primeapple commented 2 months ago

From the very first glance, I have this problem because of the mini.pairs plugin. When you press enter inside brackets it nicely formats the text, so instead of

{
|}

it becomes this

{
 | 
}

I think this is achieved by breaking out of insert mode, triggering the TextChanged event in normal mode and jumping back in insert mode. Tho I wonder why the "jumping back to insert mode" doesn't trigger the InsertEnter Event?

Will investigate further.

akikanellis commented 2 months ago

I had a look at mini.pairs and it seems to be related to this part:

-- Temporarily ignore mode change to not trigger some common expensive
-- autocommands (like diagnostic check, etc.)
local cache_eventignore = vim.o.eventignore
vim.o.eventignore = 'InsertLeave,InsertLeavePre,InsertEnter,ModeChanged'
H.restore_eventignore(cache_eventignore)

mini.pairs ignores the InsertEnter event, which is why it is not picked up by this plugin's cancel_defered_save. Not sure what the optimal way to solve this would be, but a few options come to mind:

  1. Make eventignore parameterisable in mini.pairs and then either add TextChanged to the list of events or remove all events (with the risk of triggering other tools like diagnostics when hitting <CR> between separators like {})
  2. Stop leaving InsertMode in mini.pairs (I have a feeling this is not possible or, at the minimum, would require quite a bit of re-architecture)
  3. Allow passing in tables of events in cancel_defered_save, and have auto-save match each table against the last N events, whenever an event is emitted. For example, passing in the following: cancel_defered_save = { { "InsertLeave" }, { "TextChanged", "TextChangedI" } } would preserve the current behaviour for the normal cases, while at the same time capturing the weird sequence of events emitted due to mini.pairs. Not sure how possible (or intuitive) this would be, though
  4. Detect in auto-save when we are in Insert mode and do not save. Potentially also allow parameterising the modes where this plugin's functionality is disabled.

As for current solutions:

condition = function() return vim.api.nvim_get_mode()["mode"] ~= "niI" end

This works because mini.pairs only temporarily exits Insert mode, similar to what happens when pressing C-o while in insert mode. That action results in the mode of niI, which can then be detected within condition.

torbjornvatn commented 2 months ago

I've tested this approach and it seems to work. Maybe add a note about it in the README?

primeapple commented 3 weeks ago

This got fixed by mini.pairs, see https://github.com/echasnovski/mini.nvim/issues/1273