将文字字符串从 python-vim 脚本发送到 tmux 窗格

Send literal string from python-vim script to a tmux pane

我通过以下方式一起使用 Vim (8.0) 和 tmux (2.3):在 tmux 会话中,我有一个 window 拆分为 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 有一些必须转义的字符,例如 %#$ 等。 cmd 变量是从 Vim 打开的文本文件的当前行读取的,所以我可以做类似 cmd = cmd.replace('%', '\%') 等的事情,但这有两个缺点:首先,我不知道所有必须转义的 vim 字符,因此到目前为止一直在反复试验,其次,字符 " 未正确转义 - 即在字符串 Vim 中," 就消失了,即使我这样做 cmd = cmd.replace('"', '\"')。 那么,有没有一种通用的方法可以告诉 Vim 不解释任何内容,只获取原始字符串并按原样发送?如果不是,为什么 " 没有正确转义?

Vim脚本

您正在查找 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

使用Python(而不是纯Vim脚本)没有任何好处(至少在您问题的小片段中)。相反,如果您将 Python cmd 变量嵌入到 Vim 脚本表达式中,现在您还需要一个 Python 函数来将值转义为 Vim 脚本字符串(类似于 '%s'" % str(cmd).replace("'", "''")))。或者,您可以在 Vim 变量中维护该值,并通过 vim.vars.

从 Python 访问它