Я использую vim для редактирования латексных документов. Часто я хочу изменить имя переменной на другое. Тем не менее, немного раздражает, когда приходится искать нерелевантные совпадения, когда я ищу имя переменной. Я хотел бы искать только в «математических зонах», как это определено в файле синтаксиса tex. Есть ли простой способ ограничить поиск определенной областью синтаксиса?
10
synIDattr()
для получения синтаксических групп для символа под курсором. Вы можете написать функцию, которая выполняет поиск (или выполняетnormal n
), а затем использует ее,synIDattr()
чтобы решить, оставаться ли в этом месте или продолжить поиск вперед.Ответы:
Вот функция, которую вы можете попробовать. Я только немного проверил это, но, кажется, работает нормально.
Функция вызывает функцию поиска Vim в цикле, пока не найдет «обычное» совпадение, которое также является «квалифицированным» совпадением с конкретным элементом синтаксиса, или пока оно не достигнет конца буфера.
Требуется два аргумента. Первый - это шаблон поиска, и он передается без изменений в
search()
функцию Vim . Посмотрите,:help search()
как работает эта функция. Второй аргумент - это имя элемента синтаксиса, по которому вы хотите фильтровать эти совпадения. Это также может быть шаблон и сравнивается как регистрозависимое регулярное выражение.Чтобы найти шаблон «альфа» в математических зонах вы можете сделать
В
.
конце - атом образца для любого отдельного символа, см:help /.
. Это происходит потому , что многие элементы синтаксиса математики зоны называетсяtexMathZoneA
, иtexMathZoneB
т.д.search()
Функция перемещает курсор к следующему «обычному» матчу. Затем наша функция получает все идентификаторы синтаксического элемента для этой новой позиции курсораsynstack()
. Перебирая их, он по очереди извлекает имя каждого элемента и проверяет его на соответствиеsyntaxitem
аргументу. Смотрите:help synstack()
и:help synIDattr()
. Если есть «квалифицированное» совпадение, возвращается номер строки. Если он достигает конца буфера, не найдя «подходящего» соответствия, он возвращается0
. Смысл функции заключается в том, чтобы перевести курсор к следующему «квалифицированному» совпадению, чтобы вы могли выполнить там некоторую операцию, но полезно возвращать «номер строки или 0», чтобы указать, имеет ли смысл повторно вызывать функцию, для Например, если вы хотите повторно вызвать функцию из другой функции или макроса.Я решил использовать
W
флаг для,search()
потому что он предотвращает «обтекание» конца буфера. В противном случае функция может застрять, поскольку она продолжает находить одинаковые «обычные» совпадения, но не «квалифицированные» совпадения.источник
В случае, если ваши «математические зоны» определены каким-либо синтаксическим шаблоном, скажем, строкой «математика», вы можете по крайней мере использовать последовательности шаблонов, чтобы найти строку с соответствующим шаблоном, как в:
(Примечание: два шаблона могут быть на разных линиях!)
Это может не ограничивать ваши совпадения зонами - для этого вам нужно будет определить конец зоны - но оно будет отображать только те совпадения после исходного шаблона / математика /. Вы можете повторить поиск следующего вхождения, используя историю ex-mode (
:
up-arrow
enter
).Примечание: Истр , что в более раннем VIM / VI версии я также был в состоянии использовать этот метод непосредственно в качестве команды поиска (в отличие от команды экс-режим)
/math//your pattern/
с преимуществом меньшего набора текста и использованием изn
иN
команд, но я не могу подтвердить что для моей текущей версии VIM.источник
Если вы ищете строку
foo
внутри$...$
или$$...$$
, это должно работать:Это привязывает совпадение к
$
символу, но выбирает только строкуfoo
.Это не очень простое решение, но можно использовать
:global
+,:substitute
чтобы найти «математические зоны» и искать внутри них:Притворившись, что
:substitute
это команда поиска, вы можете перейти к следующему вхождениюn
и выйтиq
. Если вы подтвердите замену по ошибке, проблем не должно быть.Вам придется установить список внутри
%(
...)
с именами математических сред, которые вы используете (полный список немного здоровен:)align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat
. Обратите внимание, что здесь я использую\v
шаблон magic ( ).Объяснение:
:global
выполнить команду Ex (:s
) в каждой строке , где шаблон матчи (:help :global
)/\v
начинают очень волшебный рисунок (:h /
,:h pattern
,:h magic
)\\begin\{
соответствует буквальном\begin{
%(align|alignat|displaymath)
соответствуют ни одному из этих слов (:h /\%(
,:h /bar
)\}/
соответствует буквальному}
и закончить картину.+1,/\\end/-1
диапазон, состоящий из следующей строки (считая от найденной:global
) до строки, найденной по шаблону поиска/\\end
. В этом диапазонеs/foo/&/gc
поиск и замена каждого вхождения литералаfoo
на себя, после подтверждения (:h :substitute
)источник
\mathit
имена переменных, найти их гораздо проще.Если вы ищете строку «утром» внутри файла
/morning
затем enterи нажмите , nчтобы двигаться вперед направлениеисточник
I would like to search only in "math zones"
ваш метод ищет весь файл, но не ограничивает исследовательскую зону.Нет другого выбора, кроме как написать для этого отдельную функцию. Я написал функцию, которая ищет строку, которую вы хотите, и останавливается, только если:
Вы просто называете это строкой, которую хотите найти.
Я намерен написать аналогичную функцию для GrammerousCheck, которая останавливается только на грамматических ошибках вне математики.
источник