Raimondi / delimitMate

Vim plugin, provides insert mode auto-completion for quotes, parens, brackets, etc.
http://www.vim.org/scripts/script.php?script_id=2754
1.98k stars 117 forks source link

Fix undo via `<Esc>:undojoin<cr>i` (applied via `s:get_left_motion`) #184

Closed blueyed closed 9 years ago

blueyed commented 10 years ago

While this fixes the undo chaining in general, <Left> is still being used in block-wise visual mode, where exiting insert mode would also exit the block-wise mode.

Ref: https://github.com/Raimondi/delimitMate/issues/138

justinmk commented 9 years ago

@Raimondi Breaking blockwise-visual mode is less egregious than breaking undo and repeat (@majutsushi would you agree?). Why not merge this until a solution for repeat is found?

Raimondi commented 9 years ago

This approach is unreliable because visualmode() returns the last visual mode used, regardless of how we got into insert mode. <C-V> <Esc> i() would make this code behave as if <C-V>I() was used.

Also, using a count when entering insert mode breaks with this PR due to leaving insert mode half way.

I thought on using mappings for the relevant commands (cCsIA) for blockwise visual mode in order to make it more reliable, but I'm trying to find an alternative that doesn't involve mappings.

fritzophrenic commented 9 years ago

I'm guessing this is the same cause of what Raimondi is saying, but these changes seem to work fine until I use blockwise visual mode, even once. After I do that, undo is broken again every time I insert a (.

fritzophrenic commented 9 years ago

For now I replaced your InsertEnter/InsertLeave autocmds with this as a workaround for many cases. I know it's not perfect but I hope it will suffice for me for now:

autocmd BufRead,BufNewFile,BufEnter,CursorMoved,CursorHold * if mode()=~'[vV^V]' | let b:delimitMate_modetracker = mode() | else | let b:delimitMate_modetracker = '' | endif
autocmd InsertEnter * let b:delimitMate_visualmode = b:delimitMate_modetracker
autocmd InsertLeave * unlet! b:delimitMate_visualmode

(Note, that's supposed to be a literal ^V character, not a '^' and a 'V')

fritzophrenic commented 9 years ago

I just discovered that somehow in my setup, only the first (empty) Vim buffer has working undo. On every subsequent buffer I edit, inexplicably the undojoin runs but the undo sequence is not joined at all. Does this also happen for you or do I need to figure out what about my setup is causing the problem?

majutsushi commented 9 years ago

In my own simple pairs plugin I have resorted to just aborting all of the plugin maps if visualmode() == '^V'. As @Raimondi said this will result in some false positives, but at least it doesn't break anything. Unfortunately it doesn't help with repeat and counts, though.

justinmk commented 9 years ago

Vim_dev has a patch that solves the problem, mostly.

blueyed commented 9 years ago

For reference, I've just noticed some weird behavior in a buffer: it throwed E790: undojoin is not allowed after undo when inserting a (, but not via feedkeys("i(") and not every time, but very often.

I have not investigated further - I really hope for this to be fixed via Vim/Neovim.

majutsushi commented 9 years ago

I think that can be avoided by prefixing undojoin with silent!.

blueyed commented 9 years ago

Probably. But it indicates that this rather frugile. I was not using undo before.