Отправить буквенную строку из скрипта 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,

Другие вопросы по тегам