Question

There are 3 closely related vim commands that let you call an external program:

  1. :[range]!{filter-cmd} {arg} (ex-command, :help :range!)

  2. :[range]write !{cmd} (ex-command, :help :w_c)

  3. system({expr}, {arg}) (vimscript function, :help system())

(I'm including ! and :!cmd as part of 1.)

From my view, there are three important distinctions:

  1. [range] is sent to stdin in, stdout replaces [range]
  2. [range] is sent to stdin, stdout is ignored
  3. stdout is the return value of system(), so stdout can be saved to a variable as :let @a = system(..)

Is there really no way to send the current buffer or current line as stdin to an external command AND have unfettered access to stdout?

If you want to write, e.g., a complicated movement command that requires parsing of the line/buffer (parsing which would be better off not written in vimscript), this seems very surprising.

(Trying to send stuff through {arg} would be crazy for a couple reasons: 1. character length limits, 2. you'd have to write a shell escaping function from within vimscript*)

Here is the only other related question I could find. It sends a string variable as shell arguments to (unix) 'echo', which then sends it as stdin to your program: Can I pass a string as stdin to a system call from vim?

*If the vim function shellescape() does what you want, great, but on Windows it isn't even remotely robust for protecting input from cmd.exe and from CommandLineToArgvW. In fact, on Windows vim sends any single shell string through cmd.exe twice.

Was it helpful?

Solution

OK, I was erring about one very important detail: the second argument to system({expr},{input}) isn't treated as shell input, it is sent as stdin. So you would do something like:

:let stdin = join(getline(1,'$'), "\n")
:let a = system('C:/main.exe',stdin)

Almost all examples of system(..) use and warn about shell escaping, but that is for the {expr} argument (and this escaping is a much smaller problem if {expr} is not a dynamic string).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top