пятница, 29 февраля 2008 г.

Использование ctags в редакторе vim

1. Что такое ctags?

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

2. Для чего нужен ctags?

Этот файл с тегами позволяет редактору быстро и легко локализовать нужный объект. Вот примерный список редакторов, умеющих
ctags:
Vi и его наследники (Elvis, Vim, Vile, Lemmy), CRiSP, Emacs, FTE (Folding Text Editor), JED, jEdit, Mined, NEdit (Nirvana Edit), TSE (The SemWare Editor), UltraEdit, WorkSpace, X2, Zeus.
В моем случае мы кроме прямого назначения будем использовать эту утилиту для "умного" авто дополнения. Но об этом позже.

3. Где взять ctags?

Ну это не проблема, умей вы пользоваться гуглем :). Для моего дистрибутива похоже что
ctags шел вместе со стандартной поставкой пакета vim-full (ubuntu 7.10). И отлично работал вместе с vim даже когда я о нем не подозревал :).
В любом случае для дебианоподобных дистров можно выполнить команду
sudo apt-get install ctags
которая установит пакет с нужными зависимостями.

4. Как мне создать теговый файл для моего С\С++ проекта?

Простой способ:
ctags -R
создаст файл tags рекурсивно обойдя файлы текущей директории.

Я предпочитаю способ посложнее:
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .
Разберемся в опциях:

--c++-kinds=+p - добавляет прототипы к базе тэгов для С\С++ файлов

--fields=+iaS - используемые поля: наследование (i), доступ (a), сигнатура функции (S)
--extra=+q - добавляет контекстную информацию к тегу. (без этой опции скрипт не может получить методы класса (Without this option, the script cannot get class members.))

5. Как добавить тег файл к текущей сессии vim?

:set tags+=/path/to/file
Некоторые пути сканируются по умолчанию, это:
./tags,./TAGS,tags,TAGS


6. Как использовать
ctags в моем коде?

Я приведу самые распространенные комбинации, все остальное можно прочитать набрав в vim :h ctags

CTRL-] - перейти на определение тега(в новом буфере)
CTRL-t - возвратиться назад по стеку вызовов
[i - показать первую строку содержащую слово под курсором, поиск с начала файла.
]i -
показать первую строку содержащую слово под курсором, поиск с текущей позиции.
[I - показать все вхождения данного тега
]I -
показать все вхождения данного тега с текущей позиции курсора
[ CTRL-I - перейти на определение тега(в новом буфере)
] CTRL-I - перейти на определение тега(в новом буфере) с текущей позиции курсора
CTRL-W i - открыть новое окно с курсором на строке ключевого слова.

Всеми пользоваться конечно же не обязательно, я думаю мне на этот момент хватит только выделенных болдом комбинаций.

Рекомендую добавить такую строчку в ваш ~/.vimrc
map <F4> [I:let nr = input("Which one: ")<Bar>exe "normal " . nr ."[\t"<CR>

Это позволит увидеть все вхождение тега, выбрать нужное и отрыть его в новом окне по нажатию F4

2 комментария:

dm комментирует...

Thanks a lot for a good example of "passing" arguments to map!

Alexei комментирует...

Спасибо за [I комбинации! Давно пользуюсь vim'ом, но не знал про них. В vim'е всегда открывается что-то новое. (: