问题
I am using Vim (8.0) and tmux (2.3) together in the following way: In a tmux session I have a window split to 2 panes, one pane has some text file open in Vim, the other pane has some program to which I want to send lines of text. A typical use case is sending lines from a Python script to IPython session running in the other pane.
I am doing this by a Vim script which uses python, code snippet example (assuming the target tmux pane is 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
This works well, except for when cmd
has some characters which has to be escaped, like %
, #
, $
, etc. The cmd
variable is read from the current line in the text file opened in Vim, so I can do something like cmd = cmd.replace('%', '\%')
etc., but this has 2 disadvantages: first, I don't know all the vim characters which have to be escaped, so it has been trial and error up until now, and second, the characters "
is not escaped properly - that is in the string Vim gets, the "
just disappears, even if I do cmd = cmd.replace('"', '\"')
.
So, is there a general way to tell Vim to not interpret anything, just get a raw string and send it as is? If not, why is the "
not escaped properly?
回答1:
Vimscript
You're looking for the shellescape()
function. If you use the :!
Vim command, the {special}
argument needs to be 1.
silent execute '!tmux send-keys -t 0 -l ' . shellescape(cmd, 1)
But as you're not interested in (displaying) the shell output, and do not need to interact with the launched script, I would switch from :!
to the lower-level system()
command.
call system('tmux send-keys -t 0 -l ' . shellescape(cmd))
Python
The use of Python (instead of pure Vimscript) doesn't have any benefits (at least in the small snippet in your question). Instead, if you embed the Python cmd
variable in a Vimscript expression, now you also need a Python function to escape the value as a Vimscript string (something like '%s'" % str(cmd).replace("'", "''"))
). Alternatively, you could maintain the value in a Vim variable, and access it from Python via vim.vars
.
来源:https://stackoverflow.com/questions/47632209/send-literal-string-from-python-vim-script-to-a-tmux-pane