среда, 30 марта 2011 г.

vim и автодополнение кода

Совсем недавно захотелось мне попробовать дополнение кода в редакторе vim. Вот как-то раньше не испытывал необходимости, а тут вот раз и захотелось. :)



Слышал когда-то, что это можно осуществить с помощью плагинчика OmniCppComplete. Пока разбирался с OmniCppComplete, нашел clang complete. И наконец, благодаря vim-конференции, узнал о неком GCCSense, с помощью которого тоже можно устроить автодополнение. Так вот, далее попробую рассказать какие недостатки имеют каждый из этих способов автодополнения.

OmniCppComplete

Установка плагина достаточна проста и описана на его страничке — не буду повторяться. Плагин использует ctags для дополнения кода, поэтому ему требуется сперва построить файлы с тегами, которые надо перечислить в опции vim-а tags примерно так:
set tags+=~/src/tags/tags.all
set tags+=~/src/tags/tags.stl
Недостатки:
  1. Надо отдельно строить ctags файлы для заголовочных файлов в /usr/include.
  2. Не так-то просто построить ctags файлы для STL.
  3. Существенный размер ctags файлов. Например для boost у меня получилось полтора гигабайта. Мелочь, но все-таки.
  4. Проблемы при дополнении всяких указателей, например, boost::shared_ptr. Плагин неправильно реагирует на оператор -> и выдает список методов для указателя, а не для объекта, на который он указывает.
  5. По мере написания кода необходимо обновлять ctags. Это, конечно же, автоматизируется системой сборки, но иногда заметно.

clang complete

Второй вариант — это автодополнение с помощью clang. Опять же процесс установки достаточно хорошо описан на странице плагина. Вполне разумные настройки по-умолчанию, т.е. сразу можно пользоваться. Только сначала надо установить компилятор clang. Недостатки:
  1. Установленный clang. Хотя если вы им пользуетесь, то это не недостаток. :)
  2. На момент допонения кода исходный файл должен быть синтаксически правильным, т.е. безошибочно обрабатываться компилятором. Например, если вы напишите
    std::vector<int> v;
    v.
    
    и решили vector подключить позже, то плагин вместо того, чтобы предложить список методов для объекта v, выдаст сообщение об ошибке.
  3. Неудобное поведение при автодополнении. Если рассмотреть код выше, то после нажатия на точку плагин выдаст список подходящих методов и полей и сразу же напишет после точки первый вариант. Если список достаточно длинный, то такое поведение сильно мешает, потому что часто хочется написать несколько первых букв метода, а потом выбрать нужный вариант из списка. Возможно, такое поведение можно настроить, а я не нашел.

GCCSense

И наконец, последний известный мне способ дополнения кода в vim. Способ с GCCSense, конечно, совсем пугает своей установкой кучи всего из исходников, но я все таки попробовал. А чтобы не было сильно страшно, то попробовал в виртуалке. :)

Плагин для vim лежит в архиве с исходниками GCCSense, который надо скопировать в ~/.vim/plugin/. После запуска vim надо выполнить :call GCCSenseDiagnose() и вроде бы должно все работать.

Снова о недостатках:
  1. Надо установить кучку разного стафа, при этом этого всего нет в пакетах.
  2. Пишут, что "Development assist is not supported in a code which can not be compiled with GCC 4.4" и что "Development assist is not available in header files".
  3. Не дополняет, если не подключены соответствующие заголовочные файлы.
  4. Неудобное поведение при автодополнении. См. clang complete недостаток номер 3.

В заключении

Такая вот не сильно радостная ситуация в vim с дополнением кода. :)

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

  1. А всего-то надо было прописать "(require 'semantic-gcc)"
    :)

    ОтветитьУдалить
  2. >А всего-то надо было прописать "(require 'semantic-gcc)"

    хе-хе, классно. :)

    Только зачем тогда разработчик GCCSense сделал плагин для emacs?

    ОтветитьУдалить