Найти тему
Блокнот математика

Рубрика "Секреты Вим". QuickFix

Всем привет, поговорим о системе компиляции и исправления ошибок в программном коде, которую можно использовать и в других целях. Например, для поиска по файлам. Система эта в Вим называется QuickFix. Она запоминает позиции в файлах и комментарии к ним (сообщение об ошибке), и позволяет перемещаться между ними. По сути, Вим является IDE: мощной, удобной, бесплатной, эффективной...

Оглавление рубрики

В IDE — системах для разработки — существуют средства для отладки. Сообщения об ошибках и предупреждениях компилятора обрабатываются и курсор переходит в нужный файл на нужную строку и одновременно показывается сообщение об ошибке. Аналогичные средства есть в Вим. Они основаны на такой возможности, как QuickFix.

В целом, это список позиций в файлах. Грубо говоря, файл, номер строки, позиция в строке и сообщение об ошибке или предупреждение. Этим можно пользоваться разными способами:

  • обрабатывать сообщения компилятора, непосредственно или через make;
  • искать текст, встроенным средством vimgrep или внешней утилитой grep;
  • искать по справке Vim средством helpgrep;
  • перемещаться по объектам программного кода (переменным, функциям классам) по тому же принципу, что и метки (tags), посредством Cscope;
  • и как угодно еще, потому что функции для доступа к QuickFix встроены в скриптовый язык Вим.

Помимо списка QuickFix, есть еще локальные списки, для каждого окна свой. Команды для QuickFix все начинаются с 'c', а локальные все с 'l'.

Предположим, что вы используете Си или C++, Fortran, любой из компиляторов GNU Compiler Collection, и make, и дали команду :make. Они сообщают об ошибках, выдавая соощение и указывая файл и позицию в тексте, где ошибка, вероятно, допущена. Вот, например, так:

gfortran -ffree-line-length-none -c -o adj adj.f90
adj.f90:46:9:
do k=1,q
1
Error: Symbol ‘q’ at (1) has no IMPLICIT type

Если возникли ошибки или предупреждения, Вим соберет выдачу, создаст список QuickFix, откроет файл с первой ошибкой, выставит курсор на соответствующую позицию и напишет внизу сообщение. Таким образом, вам не надо вручную открывать файлы, переходить на нужную строку, вспоминать, что там было не так... Вам надо только исправить ошибку.

Список QuickFix, открытый командой :copen
Список QuickFix, открытый командой :copen

Вы можете исправить ошибку и запросить следующую посредством :cnext. Можно сократить до :cn, восклицательный знак означает, что можно переходить к другому файлу, игнорируя несохраненные изменения в текущем. Можно указать число перед командой, пропустив сколько-то ошибок (например, если вы сразу исправили две).

Вернуться к предыдущей можно командой :cprev (:cprevious или :cp, или :cNext), все аналогично.

Можно посмотреть весь список: copen. Можно указать число — высоту в строках (по умолчанию 10). Потом его можно закрыть :cclose

Этого и хватит для большинства случаев. Далее возможности для экспертов.

Можно просто перейти к ошибке по номеру: cc номер. Можно прыгнуть на первую ошибку в следующем/предыдущем файле: cnfile или cpfile (или cNfile).

Переход на первую ошибку: crewind или cfirst. Если после указано число, переход на ошибку по номеру. Аналогично с последней ошибкой: clast.

Все это удобно для привязок. Я повесил :cnext на F4. Теперь все очень эффективно: make, исправил ошибку, перешел-исправил, перешел-исправил, опять :make...

Можно сохранить выдачу в файл, если по какой-то причине вы не используете make. Открыть его потом позволяет vim -q file или из Вима: :cfile

При этом будет осуществлен переход на первую ошибку. Можно не переходить, тогда :cgetfile

Если файл уже открыт в буфере, то можно использовать его: cbuffer или cgetbuffer, и даже можно задать диапазон, если нужны не все строки

Хотите объединить два списка ошибок? Можно: caddfile для файлов, caddbuffer для буферов.

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

:cexpr system('...')

И там вообще можно все сделать, что душе угодно.

Варианты cgetexpr, caddexpr в представлении не нуждаются.

cdo позволяет выполнить команду во всех позициях (пакетная операция), а cfdo — в каждом файле. Например, вставить в каждый файл с проблемой комментарий "В этом файле имеется проблема" для разработчкиков.

Напоминаю, что все команды есть для локальных списков (для каждого окна): достаточно заменить первую c на l.

Списков QuickFix может быть несколько: до десяти. В каждый момент не более одного, но Вим помнит предыдущие (или последующие, если вы перешли к более раннему). Перемещаться позволяют команды :colder, :cnewer. Это удобно при поиске (vimgrep): вы нашли процедуры для расчета китов, акул и бегемотов, заглянули, решили поискать что-то еще. Нашли, поработали. Вернулись к китам/акулам/бегемотам...

Удобно и при сборке, если на кажды подпроект у вас свой особый Makefile. Например, в модели Земли есть подмодели океана, атмосферы, растительности суши и экосистемы океана, и связующее звено. И в каждом свой Makefile. Поотлаживал одну, потом другую: такое бывает надо, хоть и не часто.

Еще у Вима есть команда :compiler, позволяющая задать настройки для данного компилятора. В поставке идут плагины для Перла, Фортрана, разных Си, Теха и многих других. По сути, задается формат сообщения об ошибках (переменная errorformat).

В общем Вим даст 100 очков вперед любой навороченной IDE даже "голый", без настроек. А настроить его можно так, что Мооленаар не узнает! И это все богатство у вас УЖЕ стоит (если у вас Линукс) и им можно пользоваться. Если вы работете на кластере через ssh, у вас точно есть Вим. Удачи, коллеги!

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