While looking for ways to solve How can I create a /* comments section with /// like in XCode?, I cam across this puzzling behaviour. Say I have foo.txt containing:
/*!
* @author Robbie Yi JIANG, 29-Jan-2016 14:01:45
*
*
*/
And I open Vim, go to insert mode, and try <c-r>=append(line('.'), readfile('foo.txt')), instead of the above text, I see:
0
/*!
* @author Robbie Yi JIANG, 29-Jan-2016 14:01:45
*
*
*/
Note the 0 at the start! This also happens if I use readfile('foo.txt', 'b'), or <c-r><c-r>=. Interestingly, the 0 gets placed just before wherever the cursor was, and the file starts from the line below. So, if I had (|| being the cursor):
foo |b|ar
I get:
foo 0bar
/*!
* @author Robbie Yi JIANG, 29-Jan-2016 14:01:45
*
*
*/
This doesn't happen if I use :call append(line('.'), readfile('foo.txt')).
foo.txt doesn't have any oddities:
$ od -c foo.txt
0000000 / * ! \n * @ a u t h o r R
0000020 o b b i e Y i J I A N G ,
0000040 2 9 - J a n - 2 0 1 6 1 4 : 0
0000060 1 : 4 5 \n * \n * \n * / \n
0000076
Tests were done using vim -Nu NONE, 7.4.1129 and 7.4.1294.
append()when everything went fine, which is0. It would explain why it inserts1instead of0whenappend()fails because you gave it a line number which exceeds the maximum number of lines in the buffer. – saginaw Feb 20 '16 at 00:21<c-r>=append(line('.'), readfile('foo.txt'))[1]– saginaw Feb 20 '16 at 00:21<c-r>=inserts whatever the expression returned, which would be0/1here. Thatappendinserts text is a side-effect. I feel very dumb. – muru Feb 20 '16 at 00:26<c-r>=append(..)callsappend,appendadds some text wherever it's told to, returns 0 or 1 as appropriate, and then<c-r>=inserts the return value. – muru Feb 20 '16 at 00:37<c-r>=append(line('.'), readfile('foo.txt'))[0]inserts both the code and the contents offoo.txt, while<c-r>=append(line('.'), readfile('foo.txt'))[whatever number]inserts onlyfoo.txt. – saginaw Feb 20 '16 at 00:43append()is a number. When you add[1]behind this number, Vim automatically coerces the number into a string. So:echo append(...)[1]is the same as:echo "0"[1], which is the second character in the string"0", but there's no second character, so you get an empty string. – saginaw Feb 20 '16 at 00:58:echo type(append(line('.'), readfile('foo.txt')[1]))returns1which is the code for a string and seems to show that Vim automatically transforms0[1]into"0"[1]. And when you give an index which is beyond the length of a string, Vim doesn't raise an error but simply returns an empty string.:h expr-[:]:If an index goes out of range for the string characters are omitted.– saginaw Feb 20 '16 at 01:27