2

I am trying to learn about jobs and channels on Vim (on Windows), and I am using the following sequence as an example:

let job = job_start("cmd")
let channel = job_getchannel(job)
let response = ch_evalraw(channel, "dir\n")

Here echo response yields dir instead of what I expect, the first line of output from dir (Volume in drive C is OS). Why is this the case, and how can I modify this to get what I expect?

5
  • Does it stop returning "dir" itself if you run "cmd /k" instead? I think what you're seeing is cmd's "echo", which I believe is somewhat common in DOS/Windows (at least I recall having to start my .BAT files with @echo off back in the day...) See docs.microsoft.com/en-us/windows-server/administration/…
    – filbranden
    May 5, 2021 at 14:59
  • I still get dir when I run cmd /k instead. I also get the same result if I replace cmd.exe with powershell.exe, and dir with ls
    – user34918
    May 5, 2021 at 17:36
  • On the other hand, if I replace cmd.exe with bash.exe that comes with Git on Windows , and dir with ls, then I get the first line of output of ls
    – user34918
    May 5, 2021 at 17:45
  • Ah, sorry... I meant cmd /q (for quiet.) I think it's normal that you only get the first line of output... I'm not super familiar with jobs and channels, but that's what I'm getting too. If you just want to run an external command and get the output, using systemlist() is much more straightforward!
    – filbranden
    May 5, 2021 at 17:50
  • 1
    cmd /q works -- I get Volume in drive C is OS instead of dir
    – user34918
    May 5, 2021 at 18:00

1 Answer 1

1

The reason why you're seeing the command you just ran coming back in the channel is because Windows' cmd.exe will by default run with “echo” on, which means it will print back the command to be executed before executing it and sending back the output produced by it.

You can use job_start("cmd /q") to have it disable “echo” at startup, which should solve the problem and have your read from the channel return the first line produced by the dir command. See documentation for cmd.exe at Microsoft's website.

Another alternative is using, for example, bash.exe from a distribution such as Git Bash, which will not produce the “echo” you've seen with cmd.


Note that a read from the channel will only produce the first line of output from dir and further channel reads don't seem to send the next lines of output from that command. I haven't really used Vim jobs and channels extensively, so I'm not really sure what the issue there is. You might want to ask a separate question about that if you'd like to explore that further...

If all you want is to capture the output of an external command, a much easier approach is to use the system() or systemlist() functions, which will take care of all the details for you and simply return a string or list. For example, to put the output of dir under the cursor in the current buffer, all you need is:

:put =systemlist('dir')
1
  • 1
    Thank you for your answer and I apologize for my slow interaction. I did a little bit of experimenting and I still don't really get what's going on. For example, given your suggestions I thought something like cmd /k echo off should also work (since /k should leave cmd.exe running after echo off) but it doesn't. Also, apparently powershell.exe doesn't have this command echoing property (according to various dubious posts online) but it exhibits the same behavior as a job from within Vim.
    – user34918
    May 6, 2021 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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