Выбор нескольких текстовых пятен в визуальном режиме? - PullRequest
0 голосов
/ 29 сентября 2019

Я делаю некоторое редактирование уценки в vim для файла. Я пытаюсь преобразовать его в уценку с подсветкой кода и т. Д.

- Arithmetic operators:`+,−,*, /`
- Constants: `e`, `pi`
- Functions: (abs x), (max x y... ), (ceiling x) (expt x y), (exp x),
    (cos x), ...

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

(abs x), (max x y... ), (ceiling x) (expt x y), (exp x), (cos x), ...

А затем выполните S`, чтобы окружить каждый фрагмент текста обратными чертами. Как я могу сделать это, не выбирая каждый из них, а затем делать S` несколько раз?

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

Как я могу сделать это, не выбирая каждый, а затем повторять S`?

Это действительно то, что лучше всего работает в Vim. С небольшой помощью макросов:

Интерактивная версия:

/(.\{-})<CR>
qqysa)`nnq
@q
@@
@@

... до тех пор, пока вы не сделаете их все и не вернетесь к тому, с чего начали.

Неинтерактивная версия "просто сделай это":

:set nows<CR>
gg
/(.\{-})<CR>
qqqqqysa)`nn@qq@q

Возможно, вы захотите вернуться к :set ns впоследствии.

Конечно, если вы знаете, что нет вложенных скобок,тогда самый простой ответ использует :s, как предложил другой ответчик.

РЕДАКТИРОВАТЬ с объяснением макроса:

qqqqq...@qq@q - это цикл. Вот как это работает:

  • qq, а затем q очищает регистр q. Это будет важно позже.
  • qq начинает запись макроса.
  • ysa) окружает круглые скобки с `.
  • nn идет кследующий матч. Мы должны сделать это дважды, потому что окружение переходит к предшествующему, и n снова будет соответствовать тем же скобкам.
  • @q вызывает макрос q. Это пусто, так что это ничего не делает ... сейчас. Однако, читайте дальше ...
  • q останавливает запись макроса и сохраняет его в регистре q.
  • Теперь, когда q больше не пусто, мы можемвыполнить его с @q. Однако во время выполнения q будет по-прежнему не пустым, поэтому, когда мы дойдем до точки в макросе, которая ничего не делала во время записи, макрос перезапустится, давая нам примитив, но функционирующий,Цикл рекурсии.
  • Цикл останавливается, когда что-то прерывается: например, невозможность перейти к следующему совпадению. Обычно вы просто меняете все совпадения, чтобы больше не осталось совпадений;однако редактирование этого макроса не приводит к сбою сопоставления, поэтому мы должны полагаться на :set nows, чтобы не допустить бесконечного добавления обратных скобок ко всем скобкам.

Через некоторое времяМы можем переписать шаблон так, чтобы :set nows (и дополнительные n) не были нужны:

/`\@<!(.\{-})<CR>
qqqqqysa)`n@qq@q

Это соответствует паре скобок, которым не предшествует обратный удар, так что после всехсовпадения были рассмотрены, для n совпадений нет, что естественно нарушает цикл.

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

0 голосов
/ 30 сентября 2019

Используя глобальную команду (предполагая, что `S`` происходит изround.vim):

:global/(/normal f(ysab`

(Это влияет на весь файл и может делать только одно изменение за раз. Повторите с @:)

С макросом:

qqf(ysab`q

Повторите с @q и затем @@

Или с заменой:

:substitute/([^)]\+)/`&`/g
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...