2013-01-10 2 views
3

Я написал несколько макросов в моем .vimrc для системы управления версиями, которую я использую (Perforce) (пожалуйста, не предлагайте плагин perforce для vim, я попробовал его и Мне это не нравится). Все они отлично работают, за исключением макроса возврата, который прерывается из-за подсказки подтверждения (что мне нужно, чтобы я не случайно сбрасывал свои изменения). В настоящее время она выглядит следующим образом:vim: команда карты с подтверждением на ключ

map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | !p4 revert <C-R>=expand("%:p")<CR><CR><CR>:edit<CR> | endif 

Это приводит к Баш жаловаться, когда ВИМ пытается загрузить файл:

bin/bash: -c: line 0: syntax error near unexpected token `(' 

Глядя на буфер Баш видит, похоже, ошибка в том, что ВИМ отправляет его все после первой трубы, а не только часть, предназначенная для bash. Я попробовал несколько альтернатив, но я не могу заставить его работать. У меня есть, чтобы показать правильное диалоговое окно подтверждения, когда я удалял трубы и endif (используя сокращение, если), но затем vim жалуется после того, как пользователь дает ответ.

ответ

3

Использование трубы для объединения нескольких команд vim не особенно четко определено, и существует множество эксцентриситетов. Критически (см. :help :bar) он не может использоваться после команды, такой как команда оболочки :!, которая видит в качестве аргумента символ |.

Возможно, вам будет легче использовать функцию system().

E.G.

:echo system("p4 revert " . shellescape(expand("%:p"))) 

shellescape() обертка полезна в случае, если у вас есть символы, такие как пробелы и кавычки в имени файла (или умно назвал его ; rm -rf ~ (Не пытайтесь повторить это дома!)).

В интересах создания более читаемый/поддерживаемого кода, вы можете переместить свой код в функцию:

function Revert() 
    if confirm('Revert to original?', "&Yes\n&No", 1)==1 
     return system("p4 revert " . shellescape(expand("%:p"))) 
    endif 
endfunction 

который вы бы получить доступ с помощью команды :call или :echo в макросе.

+0

В решении есть небольшая ошибка, команда требует «p4 revert», а не «p4», но в целом формат работает. Спасибо –

4

Я думаю, что вы хотите что-то вдоль этих линий:

:map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 <Bar> exe "!p4 revert" . expand("%:p") <Bar> edit <Bar> endif<CR><CR> 

Помните, что :map немой последовательность нажатий клавиш: что вы отображения F8 случае должна быть последовательность нажатий клавиш, которые будут работать, если наберется. A <CR> в середине инструкции :if не означает 'и нажимает Enter при выполнении команды в этой точке, если условие истинно'; это означает «нажмите Enter здесь, когда в середине ввода команды :if», что явно не то, что вы хотите.

Строительство его часть на время, изнутри:

  1. Там есть команда оболочки иногда хотите запустить.
  2. Эта команда оболочки должна находиться внутри :if, чтобы выполнить бит «иногда», и после этого следует :endif.
  3. После буквального ! все содержимое передается в оболочку, включая | символов, которые обычно означают начало другой команды Vim.Это разумно, потому что | - отличный персонаж, который можно использовать в командах оболочки. Поэтому нам нужно каким-то образом содержать команду оболочки. :exe может это сделать; он выполняет заданную строку как команду - и ее аргумент, являющийся строкой, имеет определенный конец. Таким образом, общая форма: :if condition | exe "!shell command" | endif.
  4. Ваша команда оболочки имеет выражение в ней. Использование :exe делает это проще, поскольку вы можете просто конкатенировать константные части строки команды с результатом выражения. Таким образом, команда становится :exe "!p4 revert" . expand("%:p") - попробуйте сделать это самостоятельно, и убедитесь, что она делает то, что вы хотите, прежде чем идти дальше.
  5. Полагая, что внутри условия дает вам :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif - повторите попытку перед определением отображения.
  6. После того, как вы работаете, определите отображение. Литерал | завершает отображение и обозначает начало следующей команды Vim. В вашем оригинале определение отображения только доходило до конца условия (проверьте его с :map <F8> после загрузки файла), и часть !p4 запускается немедленно, в файле Vim, который определяет отображение! Вам необходимо изменить каждый | в вашей команде на <Bar>, подобно тому, как каждое нажатие Enter в вашей команде нуждается в написании как <CR>. Это дает вам отображение выше. Попробуйте, введя его сначала в командной строке, затем снова сделайте :map <F8>, чтобы проверить, что вы думаете. И только тогда попробуйте нажать F8.
  7. Если это работает, поместите отображение в .vimrc.
+0

Спасибо, к сожалению, я могу принять только один ответ, но у меня есть и ваше преимущество. –

Смежные вопросы