2

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.

  • 2
    I suppose the expression register executes the function which appends some text, but it also stores the code returned by append() when everything went fine, which is 0. It would explain why it inserts 1 instead of 0 when append() fails because you gave it a line number which exceeds the maximum number of lines in the buffer. – saginaw Feb 20 '16 at 0:21
  • 1
    I also suppose that both information get returned through a list with 2 items, code returned in the first, evaluation/execution of the function in the second. So if you only wanted the evaluation/execution of the function, you could try: <c-r>=append(line('.'), readfile('foo.txt'))[1] – saginaw Feb 20 '16 at 0:21
  • 2
    @saginaw No, I don't think there's a list involved here. I think it's like this: <c-r>=append(..) calls append, append adds 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 0:37
  • 1
    Ah you're right. <c-r>=append(line('.'), readfile('foo.txt'))[0] inserts both the code and the contents of foo.txt, while <c-r>=append(line('.'), readfile('foo.txt'))[whatever number] inserts only foo.txt. – saginaw Feb 20 '16 at 0:43
  • 2
    :echo type(append(line('.'), readfile('foo.txt')[1])) returns 1 which is the code for a string and seems to show that Vim automatically transforms 0[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 1:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.