我正在以下列方式一起使用Vim(8.0)和tmux(2.3):在tmux会话中,我有一个分为2个窗格的窗口,一个窗格在Vim中打开了一些文本文件,另一个窗格有一些程序我要发送文本行。一个典型的用例是从Python脚本向另一个窗格中运行的IPython会话发送行。
我是通过一个使用python,代码片段示例的Vim脚本来做的(假设目标tmux窗格为0):
py import vim
python << endpython
cmd = "print 1+2"
vim_cmd = "silent !tmux send-keys -t 0 -l \"" + cmd + "\"" # -l for literal
vim.command(vim_cmd)
endpython
除非cmd
包含一些必须转义的字符,例如%
,#
,$
等,否则此效果很好。{{1}从Vim中打开的文本文件中的当前行读取变量,所以我可以做cmd
等等,但这有两个缺点:首先,我不知道所有的vim字符都必须被转义,所以它一直是试验和错误,第二,字符cmd = cmd.replace('%', '\%')
没有正确转义 - 即在Vim得到的字符串中,"
只是消失,即使我做"
。
那么,有没有一种通用的方法告诉Vim不解释任何东西,只需获取一个原始字符串并按原样发送它?如果没有,为什么cmd = cmd.replace('"', '\"')
未正确转义?
答案 0 :(得分:4)
您正在寻找shellescape()
功能。如果使用:!
Vim命令,则{special}
参数必须为1。
silent execute '!tmux send-keys -t 0 -l ' . shellescape(cmd, 1)
但是由于您对(显示)shell输出不感兴趣,并且不需要与已启动的脚本进行交互,我会从:!
切换到较低级system()
命令。
call system('tmux send-keys -t 0 -l ' . shellescape(cmd))
使用Python(而不是纯粹的Vimscript)并没有任何好处(至少在你问题的小片段中)。相反,如果您在Vimscript表达式中嵌入Python cmd
变量,那么现在您还需要一个Python函数来将值转义为Vimscript字符串(类似'%s'" % str(cmd).replace("'", "''"))
)。或者,您可以在Vim变量中维护该值,并通过vim.vars
从Python访问它。