tpope / vim-rsi

rsi.vim: Readline style insertion
http://www.vim.org/scripts/script.php?script_id=4359
589 stars 36 forks source link

Prevent <C-b> and <C-f> from breaking undo sequence in insert mode #31

Closed lacygoill closed 8 years ago

lacygoill commented 8 years ago

Hello and thank you for your plugin,

currently, when you hit:

You end up with the text (foo). However the last inserted text (the one in the dot register) is not (foo) but foo. I think it's because <Left> and <Right> breaks the undo sequence, it's discussed in :help ins-special-special. If you prefix <Left> and <Right> with <C-g>U, then the whole edition is not broken anymore.

I don't know if you think it's a good idea, but on my machine it works and I prefer this behavior (because this way you can repeat your insertion with . even though you moved your cursor with <C-b> or <C-f>), so I made a simple modification to the code and propose you this pull request.

Thank you for reading my message.

justinmk commented 8 years ago

I've been meaning to make a similar PR. However, you need to make it backward compatible with older Vim versions. There's also no reason this can't be done for other inline movements like <M-b>, <M-f>, <C-e>, <C-a>.

tpope commented 8 years ago

My immediate gut reaction was "no", but I guess I am open to try merging it if you fix the backwards compatibility thing.

lacygoill commented 8 years ago

I've tried fixing the backwards compatibility and add <C-A> / <C-E>. However, I'm new to vimscript so I don't know if it's properly coded.

For example, I don't know if you allow the creation of a global variable g:keep_undo_sequence to test whether Vim supports <C-G>U. Also, do you accept line continuations?

I tested the code on my machine (Vim 7.4.1046) and it seems to work as expected, but I haven't tested it yet on an old version of Vim (<7.4.849) because I don't have one at the moment.

If I must change something or everything, let me know what and I'll do my best.

lacygoill commented 8 years ago

I couldn't use: let s:ctrlg_u = has('patch-7.4.849') ? "\<Lt>C-G>U" : "" because then the mappings inserted <C-G>U literally, so I had to use unicodes instead: let s:ctrlg_u = has('patch-7.4.849') ? "\u07\u55" : ""

I also had to use a function to access the script-local variable from the mappings, it's the only way I found:

function! s:CtrlGU()
  return s:ctrlg_u
endfunction
lacygoill commented 8 years ago

I made a quick test with an older version 7.4.052 and it seems to work, the cursor moves as expected and the dot register doesn't contain anything related to <C-G>U.

Edit: The regexes for <M-b> and <M-f> sometimes don't work as expected. I'm not sure I can fix them.

lacygoill commented 8 years ago

I don't think I can emulate the behavior of b and w for <M-b> and <M-f> and the code is probably wrong here and there, so I'm going to close the PR. But thank you again very much for considering it, I appreciate. Have a nice day!