Say I have a line with just a character 's', let's go see \n
's effect under different circumstances:
:s/s/a\nb
a^@b
:s/s/a\\nb
a\nb
:s/s/a\\\nb
a\^@b
:s/s/a\\\\nb
a\\nb
:echo "a\nb"
a
b
:echo "a\\nb"
a\nb
:echo "a\\\nb"
a\
b
:echo "a\\\\nb"
a\\nb
So why does \n
behave differently? Then let's see the condition using substitute()
:echo substitute(" ", " ", "a\nb", "")
a
b
:echo substitute(" ", " ", "a\\nb", "")
a
b
:echo substitute(" ", " ", "a\\\nb", "")
a
b
:echo substitute(" ", " ", "a\\\\nb", "")
a\nb
This time, \n
is still interpreted as "newline", but how to explain the backslash?
Next part, say I still have a line with just a character 's', instead of \n
, \r
is going to be studied:
:s/s/a\rb
a
b
:s/s/a\\rb
a\rb
:s/s/a\\\rb
a\
b
:s/s/a\\\\rb
a\\rb
\r
's effect is like \n
in :echo "a\nb"
, and the rule of backslash is the same.
:echo "a\rb"
b
:echo "a\\rb"
a\rb
:echo "a\\\rb"
b\ "This is the most strange case!!!
:echo "a\\\\rb"
a\\rb
What does \r
do in this case? And the third subcase is even stranger.
:echo substitute(" ", " ", "a\rb", "")
b
:echo substitute(" ", " ", "a\\rb", "")
b
:echo substitute(" ", " ", "a\\\rb", "")
b
:echo substitute(" ", " ", "a\\\\rb", "")
a\rb
Still, I cannot understand how different number of backslashes behave.
My question are:
\n
or \r
behave differently under :substitute
、 echo
directly and substitute()
?substitute()
?\n
and \r
in Vim?Supplement 1:
if I :let s = "a\\\nb"
and then <C-r>=s
to see it in the buffer, I see
a\
b
How to explain this?
A sequence of zero or more non- <newline> characters plus a terminating <newline> character. And, therefore, they all need to end with a newline character. That's why Vim always adds a newline by default (because, according to POSIX, it should always be there).
n is a default mapping in vim. In particular, n repeats the last search from the cursor's position down. You recently searched for "final" so that's what it searched for. In general, it is pretty easy to find out what a key does with :help <key> while in vim.
You can type f<character> to put the cursor on the next character and F<character> for the previous one. You can also use ; to repeat the operation and use , to repeat it in opposite direction.
One can search forward in vim/vi by pressing / and then typing your search pattern/word. To search backward in vi/vim by pressing ? and then typing your search pattern/word. Once word found in vim, you can press the n key to go directly to the next occurrence of the word in backwards.
For both :echo
and substitute()
, \n
is a newline and \r
is a carriage return. They should do what you would expect. \n
moves the cursor to the next line (column 1), and \r
moves the cursor to column 1 same line. For \r
the next character that gets printed will overwrite the previously print character. (I'm mostly focused on substitute()
and :echo
, :substitute
is below)
For why echo and substitute() behave differently. You need to understand how many interpretations of the string are happening. For echo only one happens for substitute() two happen.
:echo substitute(" ", " ", "a\\\rb", "")
b
:echo substitute(" ", " ", 'a\\\rb', "")
b\
The second is the same as what you would have expected for echo.
Strings in double quotes have there contents changed according to :help expr-quote
. This means that both echo and substitute see the same thing if the string is only interpreted once (which is using single quotes)
"a\\\rb"
gets interpreted as a\rb
after one interpretation and then a<CR>b
after the second. Which leads to only b
getting printed.
\r
and \n
change depending on where they are used. The only difference would be :substitute
where \r
is used as a newline in the replacement.This is one of the cases where :substitute
and substitute()
behave differently,
:substitue
follows
<CR> split line in two at this point
(Type the <CR> as CTRL-V <Enter>) s<CR>
\r idem s/\r
...
\n insert a <NL> (<NUL> in the file)
(does NOT break the line) s/\n
(<NUL>
is the same as ^@
which is not the same as a newline)
while substitute()
follows
The special meaning is also used inside the third argument {sub} of
the substitute() function with the following exceptions:
...
- <CR> and \r inserts a carriage-return (CTRL-M).
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With