Найти в Дзене
Блокнот математика

Рубрика "Секреты Вим". Поиск в файлах: vimgrep

Сегодня расскажу про средство глобального поиска: vimgrep. Это способ найти что-то в файлах и потом открывать их из Вим и делать то, что вам надо...

Всем привет, сегодня расскажу про средство глобального поиска: vimgrep. Про unix-утилиту grep у меня тоже есть заметка, и grep доступен из Вим. Можно вызвать его как любую внешнюю команду, из командной строки Вим с использованием восклицательного знака: !grep...

А можно использовать команду Вим, которая тоже называется :grep, и по сути обращается к системной утилите.

Но речь сегодня пойдет о встроенном средстве Вим, которое делает то же самое, только лучше, с использованием регулярных выражений Вим, в том числе многострочных, с распознаванием концов строк и вообще. Ещё мощнее только Перл, где можно вообще всё.

Итак, команды семейства vimgrep.

Осуществляют поиск по шаблону в файлах. Поиск такой полезен и порой необходим при работе с многими файлами, например, программным проектом, книгой, диссертацией.

:vimgrep! /регэксп/gj список файлов

ищет шаблон в указанных файлах. Найденное заносится в список quickfix и по найденным фрагментам можно перемещаться командами cnext, cprev. Или просмотреть все командой clist. Подробнее про quickfix в отдельной заметке совсем скоро.

Вроде этого, выдача команды :clist. Можно перемещаться между находками в файле и от файла к файлу посредством :cnext, cprev.
Вроде этого, выдача команды :clist. Можно перемещаться между находками в файле и от файла к файлу посредством :cnext, cprev.

Шаблоны файлов обычные: * означает "что угодно", ? — один символ, [abc] — любой символ из перечисленных.

Есть еще **, который означает "и подкаталоги". Так, /usr/inc**/*.a будет искать файлы *.a во всех подкаталогах всех каталогов inc* в каталоге /usr. То есть, /usr/inc/a/b/c/d.a, /usr/include/a.a, /usr/include/perl/perl.a и так далее. До ста уровней глубины!

Флаг g, если указан, добавляет каждое совпадение, а без него строка добавляется не более одного раза.

Флаг j, если указан, препятствует переходу в тот файл, где первое совпадение. Если флага нет, то восклицательный знак означает "игнорировать изменения" в текущем файле.

Шаблон — обычное регулярное выражение. Если это просто слово, то можно опустить //. В общем случае их можно заменить на любую пару неалфавитных символов, например ||, только их не должно быть в шаблоне.

Переменная ignorecase действует, как и отменяющие ее ключи \C и \c в шаблоне. А вот smartcase не действует, что и логично: мало ли что там в файле.

Можно указать число перед командой — это максимум, поле которого поиск прекращается. Например, 1vimgrep — поиск до первого совпадения.

В переменной wildignore можно указать шаблон файлов, в которых искать не надо, а suffixes — файлы с низким приоритетом (по умолчанию bak и все в таком роде), они обыскиваются последними.

Можно добавить l (это строчная L) перед командой — lvimgrep — тогда найденное вставляется в местный список для каждого окна и перемещаться по найденному можно посредством lnext, lprev. Удобно, если у вас в каждом окне или вкладке свой поиск.

Еще можно добавить a в конце — vimgrepa или lvimgrepa — тогда найденное добавляется к списку, вместо того, чтобы заменять список.

Все эти префиксы и суффиксы применимы и к :grep, конечно: lgrepa, например.

Можно перемещаться и между списками. Создав один посредством vimgrep, можно найти, например, нужную функцию. Она вызывает другую, поищем ее. При этом список найденного заместится новым (если a не добавлено в конце команды). Так несколько раз, а потом можно возвращаться к старым списком командой :colder. Это не про холод, а от слова older. Есть еще :cnewer. Так можно гулять по дереву вызовов.

Все сказанное про список найденного работает и с make. Скажите :make и исправляйте ошибки в коде в уюте и комфорте. Но это уже другая история.

Путеводитель по каналу и оглавление рубрики