From :help c_ctrl-e
:
CTRL-E or <End> *c_CTRL-E* *c_<End>* *c_End*
cursor to end of command-line
In command-line mode, <C-e>
moves the cursor to the end of the line, and when you are inside the expression register =
, you are on the command-line.
So, when you hit <C-N>
in normal mode, here's what Vim does:
- type
@="
- move the cursor to the end of the command-line (it's already at the end anyway) because of
^E
; it doesn't insert the character ^E
because the latter was interpreted as a motion
- type
"^M
In the end, it's as if you had typed: @=""
, which is an empty string. So, Vim doesn't execute anything.
It would work if there was something in the string, for example if you type @="dd"
in normal mode, it will delete the current line. But here, there's nothing left in the string, because ^E
was interpreted as a motion.
For this reason, you can't use ^E
in your mapping.
Your mapping works for ^Y
because of this (:help c_ctrl-y
):
CTRL-Y When there is a modeless selection, copy the selection into
the clipboard. |modeless-selection|
If there is no selection CTRL-Y is inserted as a character.
Like ^E
, ^Y
is associated with an action on the command-line. But not if there is no selection.
In this case, contrary to ^E
, it simply inserts a literal control character.
Depending on the context, there are various ways to write a control character like ^E
:
^E
(Ctrl-VCtrl-E) to insert it on the command-line or in a buffer
<C-E>
in a mapping
"\<C-E>"
in a string
"\<lt>C-E>"
in a string read by a mapping command such as :nnoremap
So, if for some reason you really wanted to use the expression register (maybe because you wanted to create a mapping accepting a count), you could use "\<lt>C-E>"
, like this:
nnoremap ^N @="\<lt>C-E>"^M
In this mapping, 2 translations occur at different times.
First, when your :nnoremap
command is executed and add an entry in the mappings table, the keycode <lt>
is translated as the character <
, and the resulting string is "\<C-E>"
.
Then, when you hit <C-N>
in normal mode, the string "\<C-E>"
is translated into the control character ^E
.
The keycode <lt>
is necessary to protect <C-E>
from being automatically translated into a literal control character when :nnoremap
is executed.
If you don't protect <C-E>
with <lt>
, the same problem as before will repeat; ^E
will be intepreted as a motion on the command-line instead of a character to insert.
@="^E"
message. I'm perplexed as to why it wont work for<c-e>
but will for seemingly any other<c-...>
character.nnoremap <C-n> <C-e>
nnoremap <c-n> @="<c-e>j"
; that scrolls the window and moves my cursor down at the same time. The @= makes it so the operation is repeatable. ie I can press10
ctrl-n
to scroll the window, and move cursor 10 lines down.nnoremap <c-n> <c-e>j
scrolls the window down 10 but the cursor only goes down 1. The mappingnnoremap <c-p> @="<c-y>k"
which does the exact opposite, works perfectly fine.