2012-05-29 4 views
7

Я часто нахожу себя с проблемами, которые должны сочетать регулярные выражения, какое-то движение, а также копирование и вставка. Я уверен, что есть какой-то способ сделать это в vim, но я не видел ничего вместе. В качестве примера прямо сейчас проблема, которую я пытаюсь решить, такая.Как использовать VIM для объединения мощности макросов и регулярных выражений

  1. Найти строку, которая является/^ Описание/
  2. Сохранить захваченный текст
  3. Перейти к линии,/^ TEXT « "(. *)"(*.) -/
  4. Заменить захваченный текст выше захваченного текста, начиная с шага 2
  5. Повторите по мере необходимости движения вперед через файл

кто-нибудь знает способ быстро автоматизировать этот тип задачи в VIM?

ответ

4

Я не узнал все новые возможности, связанные с vim-only; Я изучил vi перед vim, и это решение будет работать в любом редакторе vi-ish. Возможно, может быть даже лучшее решение, использующее функции vim.

Что бы я обычно делал в этом случае, используйте команду :map, чтобы связать несколько ключей, каждый из которых выполняет часть вышеуказанного. Вам нужно выбрать несколько ключей, на которых вы можете жить некоторое время; Я часто использую g и v. @Neil Forrester предложил использовать функциональные клавиши, что отличная идея.

Теперь вы показали шаблоны регулярных выражений с парсерами, указывающими группу соответствия. (В vi или vim вам действительно нужно поместить обратную косую черту перед каждым париком, чтобы сделать ее «волшебной», см. Документацию.) Однако для этого решения я собираюсь использовать команду f, которая (f) inds a указанный символ; и/или команду t, которая перескакивает символ un (t) il. f прыгает до персонажа, где t прыгает прямо перед символом. Итак, с f" мы можем перейти к первой двойной кавычки строки, а затем с помощью t" мы можем прыгать до момента, когда перед второй двойной кавычкой.Итак, последовательность f"lyt" найдет первую двойную кавычку, переместит один символ вправо, а затем выдержит все до следующей двойной кавычки. Но, давайте сохраним yanked текст в один из 26 названных буферов; давайте просто воспользуемся буфером «a»: f"l"ayt" Это немного запутанно, потому что мы должны использовать "a для обозначения именованного буфера «a», но у нас есть много других " символов, которые мы ищем.

Кроме того, в рамках «карты» вам может потребоваться записать нажатие клавиши Enter. То, как вы это делаете, - нажать Ctrl + V, затем нажать клавишу Enter. Это будет отображаться как ^M. В моем коде ниже, если вы видите ^M, он не предназначен для фактического ^, за которым следует фактический M, а скорее один ключ, который представляет клавишу Enter.

Итак, теперь мы можем сделать наши два ключевых сопоставления. Давайте связать v делать шаги 1 и 2, и g делать шаги 3 и 4.

:map v /^Description "/^Mf"l"ayt" 

:map g /^TEXT "/^Mf"ldt""aP 

Не забывайте, используйте Ctrl + V и Enter, а не на самом деле, набрав^M, так что вы не можете просто скопируйте/вставьте выше, не редактируя его.

Теперь используйте ключ v, чтобы выполнить шаги 1 и 2, и клавишу g, чтобы выполнить шаги 3 и 4. Путем поочередного нажатия двух клавиш вы можете сделать очень быстро.

Возможно, также существует способ сделать это, используя скрипты в vim, но, с другой стороны, вы можете просто написать короткий скрипт Python (или ваш любимый язык), если хотите сценарий. Два ключевых макроса, выше, действительно обеспечивают быстрый способ делать подобные вещи в vim.

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

+0

Это был ответ, который я искал. Ключевыми командами, которые мне были нужны, были f и t. Мне на самом деле пришлось заменить «delete» на «yank», но в идеале. Спасибо. – z4ce

+0

Конечно, «yank» лучше, чем «удалить» для этого; Я не уверен, почему я думал, что вы хотите удалить текст из «Описание» при вводе его в «ТЕКСТ». Я продолжу и отредактирую ответ, поэтому будущие его читатели не смущаются. – steveha

4

Вы можете сопоставить следующую последовательность с неиспользуемой клавишей (например, F2), а затем нажать ее столько раз, сколько хотите.

:map <F2> /^Description "(.*)"<CR>y//e/^TEXT "(.*)-<CR>Pd//e 

При желании можно добавить <F2> до конца, так что он будет работать рекурсивно, пока матч не выходит из строя.

:map <F2> /^Description "(.*)"<CR>y//e/^TEXT "(.*)-<CR>Pd//e<F2> 

Давайте разберемся, чтобы увидеть, что происходит. Это перемещение к началу вашего первого поиска:

/^Description "(.*)"<CR> 

Это yanks до конца вашего первого поиска.

y//e 

Это ваш второй поиск:

/^TEXT "(.*)-<CR> 

Это ставит то, что вы рывок непосредственно перед курсором, перемещает один символ вправо, а затем удаляет до конца своего второго поиска.

Pld//e 
+0

Обычно я считаю целесообразным разделить работу на два макроса. Когда я делаю такие вещи, у меня иногда есть несколько заметок, необходимых для одного поиска, или иногда я хочу отредактировать исходную строку или что-то еще. – steveha

+0

Это хорошо, но я должен был быть более ясным, что я хотел захватить текст в тексте, который должен соответствовать \ (. * \) И использовать его. Я уверен, что я найду методы здесь полезными. – z4ce