23

Sometimes in insert mode I hit <CR> by mistake and I have to hit the backspace multiple times (depends on the indentation) to get back where I was.

e.g.

<div>
  <p> This is some text []</p>
</div>

The cursor is [] and I hit <CR> :

<div>
  <p> This is some text 
  []</p>
</div>

Now I have to hit backspace twice to get back to the previous line (this case isn't so bad but it doesn't have a lot of indentation).

Do you know a better way to do ?

nobe4
  • 16,033
  • 4
  • 48
  • 81

4 Answers4

22

I have this in my vimrc, the second part is relevant:

inoremap <expr> <silent> <cr> pumvisible() ? "<c-y>" : "<c-g>u<cr>"

What this does: everytime you hit Enter in insert mode, it will also "break the undo sequence, start new change" (see h: i_CTRL-G_u). This means, if you hit Enter by mistake, you can now undo your change without removing previous inserted lines, either with ESC u a, or with Ctrl-o u, as Statox proposed. Basically, each line can be undone separately.

source

EDIT/UPDATE: If you happen to use Vim emulation in Emacs, a.k.a. evil-mode, you can use this package for a similar effect.

VanLaser
  • 9,700
  • 2
  • 24
  • 34
  • Now I'm curious about the first part and how <c-y> relates to the pop-up menu. – 8bittree Jul 07 '15 at 13:16
  • 2
    See this answer: http://vi.stackexchange.com/a/3844/1800 . Ctrl-y in insert mode will complete the current popup selection, and the above mapping will allow Enter to complete too. – VanLaser Jul 07 '15 at 13:19
  • Nice trick. However, I'd probably replace the last part "<c-g>u<cr>" by &paste ? "<cr>" : "<c-g>u<cr>", otherwise next time you paste by mistake 200 lines of HTML you'll have a lot of fun undoing it. :) – lcd047 Jul 07 '15 at 14:51
  • everything can be improved ;) never happened to me so far though (I usually paste from normal mode) – VanLaser Jul 07 '15 at 16:16
  • Actually, I just tested with set paste and ... it seems to do something "magic" itself, by undoing the whole insert session in one go (as if the CR insert mode mapping is ignored) – VanLaser Jul 07 '15 at 16:40
  • 2
    ... and the explanation: when paste is on, Insert mode mappings are disabled (as per Vim's help) – VanLaser Jul 31 '15 at 18:34
  • 1
    I like this solution better because the other solutions relying on Backspace, Ctrl-W, and Ctrl-U might not work depending on how the backspace option is set. – doubleDown Nov 01 '15 at 10:50
10

How about:

inoremap <C-\> <C-o>:left 0<Cr><BS>

<C-o> will execute a normal mode command (:left 0), which will remove all indent, this will also put your cursor at the start of the line. <BS> will get you back to the last line.

This is a bit like a "backwards J".

Unfortunately, mapping Shift+Enter or Ctrl+Enter doesn't seem possible, so I choose <C-\>, as being "near the enter".

Martin Tournoij
  • 62,054
  • 25
  • 192
  • 271
6

The way I do it is Ctrl-wBackspace.

Ctrl-w to delete the last word (I forgot if this is standard vim or not), and since it's just spaces it will take me back to the beginning of the line. Then Backspace will take me back to the previous line where I was.

  • Sweet, I didn't know about the Ctrl-wuse in insert-mode. But the Carpetsmoker♦ is still quicker. Thus the default binding of Ctrl-\\doesn't seems that useful. – nobe4 Jul 08 '15 at 07:44
  • 1
    Ctrl+w is "standard Vim" ;-) See: :help i_CTRL-W. And pressing it twice seems to do the trick as well? – Martin Tournoij Jul 08 '15 at 07:44
  • 1
    I just saw on the help page that <C-u> may be more usefull as it deletes all the characters on the new line – nobe4 Jul 08 '15 at 07:46
2

My way out of this is (from insert mode) UpCtrl-oJDel. Possibly not the most efficient combination, but it's what I'm doing without needing to think about it.

lcd047
  • 3,700
  • 16
  • 26