I found the following answer in this question on the Unix & Linux Stack Exchange:
In insert mode, the cursor is between characters, or before the first
or after the last character. In normal mode, the cursor is over a
character (newlines are not characters for this purpose). This is
somewhat unusual: most editors always put the cursor between
characters, and have most commands act on the character after (not,
strictly speaking, under) the cursor. This is perhaps partly due to
the fact that before GUIs, text terminals always showed the cursor
on a character (underline or block, perhaps blinking). This
abstraction fails in insert mode because that requires one more
position (posts vs fences).
Switching between modes has to move the cursor by a half-character, so
to speak. The i
command moves left, to put the cursor before the
character it was over. The a
command moves right. Going out of
insert mode (by pressing Esc) moves the cursor left if
possible (if it's at the beginning of the line, it's moved right
instead).
I suppose the Esc behavior sort of makes sense. Often,
you're typing at the end of the line, and there Esc can
only go left. So the general behavior is the most common behavior.
Think of the character under the cursor as the last interesting
character, and of the insert command as a
. You can repeat
a Esc without moving the cursor, except that
you'll be bumped one position right if you start at the beginning of a
non-empty line.
Credits to the original author.
If you would like to edit this behavior, you could follow the advice from @ib. in this answer:
Although I would not recommend changing the default cursor mechanics,
one way of achieving the behavior in question is to use the following
Insert-mode mapping.
:inoremap `^
Here the Esc key is overloaded in Insert mode to
additionally run the `^
command which moves the cursor to the
position where it had been the last time Insert mode was left. Since
in this mapping it is executed immediately after leaving Insert mode
with Esc, the cursor is left one character to the right as
compared to its position with default behavior.
Unlike some other workarounds, this one does not require Vim to be
compiled with the +ex_extra
feature.