2

I want to set node's executable path for neovim. So I have added this line in init.vim.

let g:coc_node_path = system('which node')

But when I open nvim I get this error.

[coc.nvim] "/home/akash/.nvm/versions/node/v15.5.0/bin/node^@" is not executable, checkout https://nodejs.org/en/download

But if I edit the path manually,

let g:coc_node_path = '/home/akash/.nvm/versions/node/v15.5.0/bin/node'

then it works fine. So why does system('which node') append ^@ to its output?

1
3

What a coincidence. I encountered this exact same thing a few hours before you posted this. I just figured it was a line-ending issue and solved it by wrapping the system() call in a call to trim().

Since you mentioned it I since verified that the cause is the presence of a newline in the output of system().

So you can solve this with a trim() call that directly addresses the problem like so...

trim(system(...), "\n")

If you are using an older version of Vim which doesn't have trim() you can use something like this instead...

let foo = system(...)
let foo = strcharpart(foo, 0, strchars(foo)-1))

Or this...

let foo = substitute(system(...), "\n$", "", "")

Update: I should point out that this isn't a bug or anything. When running a command from the shell you'll get a newline at the end and that's expected. system() does the right thing and passes everything back to the caller. It just so happens that there's a fairly common use case, assigning the result to a variable, where we don't want that newline.

(Note: One thing that might not be expected is that Vim normalizes line-endings on non-unix systems so, for example, Windows CRLF becomes LF. It makes sense but one needs to be aware of it.)

2
  • As some recent answers pointed out, trim() was only introduced in Vim v8.0.1630, so it might not be available if you're using stock Vim shipped with a somewhat older distribution.
    – filbranden
    Jan 3 at 20:30
  • 1
    Oh, yeah. Thx for the reminder.
    – B Layer
    Jan 4 at 1:17
2

What you're seeing is the newline at the end of the command, as @BLayer's answer states.

A better approach for this specific case of finding a binary would be to use the Vimscript function exepath() here instead of shelling out to the which command:

let g:coc_node_path = exepath('node')

This is more efficient (since it doesn't need to spawn an external process) and ends up avoiding the issue with the newline altogether.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.