Search code examples
vim

How to Insert Line Breaks by Calling join() Function in VimScript


I have a list in VimScript:

let demo = ["First Line", "Second Line", "Third Line"]

Now, I try to call join(demo, "\r") to insert line breaks between items. The result I expect is:

First Line
Second Line
Third Line

However, the REAL result is:

First Line<0d>Second Line<0d>Third Line

How should I call join() to insert line breaks between items?

--- EDIT ---

Here is the actual code sample:

autocmd BufNewFile *.cc call InitCPPSrcFile("//")
 
function InitCPPSrcFile(comment_flag)
    let &display = "truncate,uhex"
    let l:demo = [a:comment_flag . "First Line", "Second Line", "Third Line"]
    call setline(1, join(l:demo, "\n" . a:comment_flag))
endfunction

Solution

  • So, the <0d> and <00> are a bit confusing but that's because of set display+=uhex. Without it, they are displayed as ^M and ^@, "carriage return" and "null", respectively, which is slightly easier to reason about.

    Anyway, it is not join() that is playing with your nerves but setline():

    :call setline(1, "foo\nbar")
    :1#
        1 foo^@bar
    

    I am not sure how to fix this or even it is worth fixing, because setline() will do what you expect with a list as argument:

    :call setline(1, ["foo", "bar"])
    :1,2#
        1 foo
        2 bar
    

    In this case, :help join() is messy anyway, because of what it forces you to do in order to insert the // before every line:

     item item item
         ^    ^        " where join() inserts stuff
     item item item
    ^    ^    ^        " where you want to insert stuff
    

    I would suggest :help map() instead, which allows you to manipulate each item exactly how you want:

    autocmd BufNewFile *.cc call InitCPPSrcFile("//")
    
    function InitCPPSrcFile(comment_flag)
        let &display = "truncate,uhex"
        let l:demo = ["First Line", "Second Line", "Third Line"]
        call setline(1, map(l:demo, { idx, val -> a:comment_flag .. val }))
    endfunction
    

    *.cc