10

When we are in insert mode in vim:

foo b[a]r

Where [] denotes cursor position

And we go back to normal mode, cursor is going one position left:

foo [b]ar

Is there advantage of this?

Sławosz
  • 11,187
  • 15
  • 73
  • 106
  • Why was this question marked 'duplicate', when it clearly asks about **leaving** the insert mode, whereas the 'right' question asks about **entering** the insert mode? – d.k Oct 26 '20 at 17:35

5 Answers5

6

From the VIM FAQ:

10.2. In insert mode, when I press the <Esc> key to go to command mode, the
 cursor moves one character to the left (except when the cursor is on
 the first character of the line). Is it possible to change this
 behavior to keep the cursor at the same column?

No. It is not possible to change this behavior. The cursor is *always*
positioned on a valid character (unless you have virtual-edit mode
enabled). So, if you are appending text to the end of a line, when you
return to command mode the cursor *must* drop back onto the last character
you typed. For consistency sake, the cursor drops back everywhere, even if
you are in the middle of a line.

You can use the CTRL-O command in insert mode to execute a single ex
command and return back to insert mode without moving the cursor column.

See this vim tip if you'd like to change this behavior in your .vimrc and position to the left only on EOL.

Benj
  • 31,668
  • 17
  • 78
  • 127
  • I don't think, this is a good argumentation for this interaction of `i` and ``. (a): `i` is not the intended way to "append text to a line". (2): move back to "always" step onto a valid character is not true, e.g. when located at the beginning of a (possibly empty) line. – Jan Jul 31 '13 at 16:30
  • @Benj 'No. It is not possible to change this behavior.' why does wiki say it's not possible, It's perfectly possible. Just add this to your vimrd.`inoremap l` – saga Jan 23 '17 at 13:42
  • @saga Try doing that when you're on the first character in the line and you'll find it's a bit frustrating. – Benj Feb 01 '17 at 21:49
6

Your initial "state" is wrong, this is what you get in insert mode:

bar[]

In insert mode, the cursor is between characters while it is on a character in normal mode. When you leave insert mode, the cursor has to be on a character: what character could it be? The one on the left of the insert mode cursor or the one on the right? How is Vim supposed to decide which side is the good one?

One hint would be the command used to enter insert mode: leaving insert mode after i could probably leave the cursor on the left side and a could probably leave it on the right side. But, what would be the point of having the cursor on the character that's on the right of the last character we typed?

Anyway, insert mode is for inserting text exclusively. i<Esc> or a<Esc> make no sense and serve no practical purpose. On the other hand:

Lorem[] dolor sit amet.
Lorem ipsum[] dolor sit amet.
<Esc>
Lorem ipsu[m] dolor sit amet.

makes a lot more sense than:

Lorem[] dolor sit amet.
Lorem ipsum[] dolor sit amet.
<Esc>
Lorem ipsum[ ]dolor sit amet.

Doesn't it?

romainl
  • 186,200
  • 21
  • 280
  • 313
  • 4
    that doesn't make more sense, not to me – theonlygusti Oct 24 '16 at 16:20
  • @theonlygusti when you exit insert mode, the cursor is positioned at the last character you entered. – saga Jan 23 '17 at 13:39
  • @saga but I don't feel that it should be, unless it's the end of a line. I feel like the cursor should be positioned at, well, the cursor – theonlygusti Jan 23 '17 at 17:14
  • @theonlygusti suppose you want to add `name:myname` to a string, and `myname` is in a register. Because the cursor is placed at last character entered, you can just type `name:`, press esc, and copy the content with `p`. If the cursor behaves like you say it should, you will have to move it back one character before pasting from the register. It will become intuitive once you try it.(this can be said for vim as well ;-) – saga Jan 24 '17 at 07:53
  • BTW, you can get the desired behaviour by adding this to your vimrc: `inoremap l`. But it's not recommended. I had it in my vimrc, now I don't, cos it's counter productive. – saga Jan 24 '17 at 07:59
  • @saga In that case you could just use `P` – olejorgenb Jan 01 '19 at 20:24
3

I don't see a direct advantage over just typing h.

The observed movement to the left is a side product of a convention in VIM - always leave insert mode "to the left" - which I find very convenient.

Convenient, because there are many ways to enter insert mode and, having done some insertions, I care about how to exit rather how I have entered insert mode.

There are ways to change this behavior, cf. these SE posts:

Community
  • 1
  • 1
Jan
  • 4,932
  • 1
  • 26
  • 30
3

Well, the convention is vim is different than what we are used to. See, for example, how the default paste works. If you press p - the yanked text appears AFTER the cursor instead of AT the cursor like we are used to.

And where is the cursor located at the end of the paste? it's located one character BEFORE the end of the new text! So if you want to continue to write after the text you need to move to the right and then press i!

You need to just switch to thinking that the actual cursor is one character to the right (or down) than the one you see. That's the vim convention.

If you start using a/o to enter insert mode by default instead of i/O, it might help you do this. Just transition your thought so a is the default, and then the paste, and the location of the cursor exiting insert mode, and many other things will make more sense.

Edit

A few more words to actually answer your question (rather than help you cope with the behaviour)

The most important feature in vim is the consistency of behaviour. The goal is to allow you to know exactly what will happen without even looking at the screen.

So, when you exit insert mode, where should the cursor be? It can't be after the text, because if the text ends at the end of the line, the cursor can't get there! (can't be after end of line). Same for paste - if you paste at the end of a line the resulting cursor can't be after the inserted text!.

Because of consistency requirement - if it sometimes can't be after the inserted text, then is should never be there. Otherwise, if you type without looking at the screen, you don't know where the cursor will be - you'll have to look up and check!

Many of the behaviours of vim can be explained like this: why does '^' get you to the first character and not one-before-first? (so that a would work to insert, like it does with paste, $ etc.) because if the first char is at the start of the line - you can't go "one before it". And you want to be consistent.

rabensky
  • 2,864
  • 13
  • 18
2

It could be because you are only allowed to move the cursor in the written area for example bar[] should become ba[r] when not in insertion mode, but you are right it doesn't need to happen always

Andreas
  • 970
  • 18
  • 28
  • @Jan changing line is still a valid change in the document when you escape insert-mode the cursor moves back from the next character to the new-line which makes no difference. eg from [] to [\n] which means newline (so it doesn't escape the newline) – Andreas Aug 01 '13 at 06:08