有3个密切相关的vim命令可以让你调用外部程序:
:[range]!{filter-cmd} {arg}
(前命令,:help :range!
)
:[range]write !{cmd}
(前命令,:help :w_c
)
system({expr}, {arg})
(vimscript函数,:help system()
)
(我包括!
和:!cmd
作为1的一部分。)
从我的观点来看,有三个重要的区别:
[range]
被发送到stdin,stdout替换[range]
[range]
被发送到stdin,stdout被忽略system()
的返回值,因此stdout可以保存为变量:let @a = system(..)
真的没有办法将当前缓冲区或当前行作为stdin发送到外部命令并且无限制地访问stdout吗?
如果你想编写一个复杂的移动命令,需要解析行/缓冲区(解析最好不要用vimscript编写),这似乎非常令人惊讶。
(尝试通过{arg}
发送内容会因为以下几个原因而疯狂:1。字符长度限制,2。您必须在vimscript中编写shell转义函数*)
这是我能找到的唯一其他相关问题。它将一个字符串变量作为shell参数发送到(unix)'echo',然后将其作为stdin发送到您的程序:Can I pass a string as stdin to a system call from vim?
*如果vim函数shellescape()
能够达到你想要的效果,那就太棒了,但是在Windows上,保护来自cmd.exe
和CommandLineToArgvW
的输入甚至不具备远程可靠性。实际上,在Windows上,vim通过cmd.exe
两次发送任何单个shell字符串。
答案 0 :(得分:4)
好的,我错误地提到了一个非常重要的细节:system({expr},{input})
的第二个参数不被视为shell输入,它作为stdin发送。所以你会做类似的事情:
:let stdin = join(getline(1,'$'), "\n")
:let a = system('C:/main.exe',stdin)
几乎system(..)
的所有示例都使用并警告shell转义,但这是针对{expr}
参数的(如果{expr}
不是动态字符串,则转义是一个小得多的问题)。