Отправить буквенную строку из скрипта python-vim на панель tmux
Я использую Vim (8.0) и tmux (2.3) вместе следующим образом: в сеансе tmux у меня есть окно, разделенное на 2 панели, на одной панели есть какой-то текстовый файл, открытый в Vim, на другой панели есть какая-то программа, для которой я хочу отправить строки текста. Типичный вариант использования - отправка строк из скрипта Python в сеанс IPython, запущенный на другой панели.
Я делаю это с помощью скрипта Vim, который использует Python, пример фрагмента кода (при условии, что целевая панель 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('%', '\%')
и т.д., но у этого есть 2 недостатка: во-первых, я не знаю всех символов vim, которые должны быть экранированы, поэтому до сих пор это были пробные и ошибочные символы, а во-вторых, символы "
не экранирован должным образом - то есть в строке, которую получает Vim, "
просто исчезает, даже если я делаю cmd = cmd.replace('"', '\"')
, Итак, есть ли общий способ сказать Vim, что он ничего не интерпретирует, просто получает необработанную строку и отправляет ее как есть? Если нет, то почему "
не сбежал правильно?
1 ответ
Vimscript
Вы ищете shellescape()
функция. Если вы используете :!
Команда Vim, {special}
аргумент должен быть 1.
silent execute '!tmux send-keys -t 0 -l ' . shellescape(cmd, 1)
Но поскольку вас не интересует (отображает) вывод оболочки, и вам не нужно взаимодействовать с запущенным скриптом, я бы переключился с :!
на нижний уровень system()
команда.
call system('tmux send-keys -t 0 -l ' . shellescape(cmd))
питон
Использование Python (вместо чистого Vimscript) не имеет никаких преимуществ (по крайней мере, в небольшом фрагменте в вашем вопросе). Вместо этого, если вы встраиваете Python cmd
переменная в выражении Vimscript, теперь вам также нужна функция Python для экранирования значения в виде строки Vimscript (что-то вроде '%s'" % str(cmd).replace("'", "''"))
). Кроме того, вы можете сохранить значение в переменной Vim и получить к нему доступ через Python через vim.vars
,