Об удобной навигации и отладке C++ кода в Vim

    Компания, где я работаю, разрабатывает программное обеспечение на C++ под Linux. Долгое время мы использовали Qt Creator, с редкими ребятами работающими из Emacs и Vim. Когда я сам попытался пересесть на Vim, я понял, что ситуация с плагинами для разработки на С++ очень не простая. Поработав немного с CTags, я быстро понял, что без напильника работать в Vim будет очень сложно.
    К сожалению, с ростом опыта работы с Vim редактор в Qt Creator в режиме эмуляции устраивал меня все меньше, и в какой-то момент я решил потратить немного времени и разобраться, как же сделать из Vim нормальную среду.
    Я очертил для себя четыре вещи, которые я бы хотел от среды разработки, и которых мне бы хватило в Vim, чтобы полностью на него перейти:

    1. Автодополнение
    2. Навигация по коду
    3. Отладка прямо из среды
    4. Интеграция с Git (в частности Blame прямо в редакторе, и Git Grep)

    Автодополнение в Vim — это решенная проблема, и название у решения YouCompleteMe. Это очень качественный плагин, который реализует автодополнение для большого количества языков программирования, в частности Python и C++. Ходят слухи, что внутри Google YouCompleteMe решает и вторую проблему с навигацией кода, но использует для этого внутренные инструменты гугла для индексирования.

    Интеграция с Git в какой-то степени решена с помощью vim-fugitive. Это не такая комплексная интеграция, как бывает у Jet Brains, или в Visual Studio, но сравнимая с тем, что предлагает Qt Creator. Те два сценария, которые нужны были мне: blame и grep — работают хорошо.

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

    Конечно, как я упомянул выше, для навигации можно было использовать CTags, но если вы работали с CTags, то вы знаете, что он не решает проблему. Парсер C++ очень слабый, и часто CTags находит совершенно неправильные участки кода.

    В интернете как несколько лет назад, так и сейчас, единственное, что находится на тему навигации по C++ коду — это вот эта статья. Я настроил этот плагин, и он в принципе работал. Но было много нареканий, из которых два самых больших:
    1. Процесс индексирования надо запускать руками
    2. Нельзя найти символ по его названию

    В конечном итоге, это все закончилось разработкой собственного плагина для Vim, который позволяет перемещаться по C++ коду. Он требует наличия Compilation Database. Если в проекте используется CMake, то чтобы его получить достаточно вызвать

    cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
    


    Иначе можно либо воспользоваться Bear, либо построить его руками, формат очень простой.

    Плагин называется CtrlK, и позволяет делать следующие вещи:

    1. Перейти к определению символа под курсором.
    2. Поиск всех вхождений символа под курсором.
    3. Поиска символа по его названию (для этого используется FuzzyFinder, но поиск, к сожалению, не Fuzzy, а только по подстроке). Поиск работает для функций, методов, классов, глобальных переменных, макросов, и даже аргументов функций и локальных переменных.
    4. Отображение названия функции, внутри которой находится курсор, в строке состояния. Очень удобно при редактировании больших функций, когда ее объявление находится за пределами экрана.

    Кроме того, есть эксперементальная возможность показывать отдельное окно, в котором постоянно показывается определение символа под курсором. Такую возможность я видел только в среде Source Insight, и ее полезность кажется спорной, но я нахожу ее очень удобной.

    Плагин использует libclang для парсинга кода и leveldb для индекса.

    Как и YouCompleteMe, плагин состоит из серверной части и клиента. Здесь под серверной частью подразумевается некоторый процесс, который запущен параллельно с Vim, и который общается с Vim. Для установки мы пошли немного другим путем, чем YCM. Если YouCompleteMe просит запустить руками Make после установки через Vundle, мы вместо этого сделали установку серверной части через pip.
    Сначала казалось, что можно написать весь плагин на Python, и не делать серверной части, но скорость парсинга большого количества файлов через clang библиотеку для python очень низкая, и пришлось ее писать на C++, что требует выноса этой функциональности в запущенный отдельно процесс, и немного осложняет установку.

    В итоге, установка сводится к установке питоновских библиотек clang, leveldb и серверной части ctrlk:

      sudo pip install leveldb
      sudo pip install clang
      sudo pip install ctrlk
    


    (Если sudo pip install ctrlk не сработал)
    Исторически сложилось так, что pip package для ctrlk принадлежит не мне. В текущем package есть две недоработки — не указана зависимость от ez_setup, ее можно разрешить руками

      sudo pip install ez_setup
    


    И отсутствуют заголовочные файлы и библиотеки clang. Это с большим шансом приводит к ошибке компиляции, потому что стандартная установка clang/llvm не помещает их туда, где компилятор нашел бы их без подсказки.
    Обе эти проблемы решены в репозитории, но пока pip package не обновлен. Если sudo pip install ctrlk упал с ошибкой компиляции, то можно просто установить его руками

      git clone https://github.com/SkidanovAlex/py-ctrlk.git
      cd py-ctrlk
      python setup.py build
      sudo python setup.py install
    



    Установке плагина (а также L9 и FuzzyFinder, от которых CtrlK зависит). Для этого проще всего использовать Vundle:

      Plugin 'L9'
      Plugin 'FuzzyFinder'
      Plugin 'SkidanovAlex/CtrlK'
    


    И небольшим настройкам в vimrc

      let g:ctrlk_clang_library_path="/home/user/llvm/lib"
      nmap <F3> :call GetCtrlKState()<CR>
      nmap <C-k> :call CtrlKNavigateSymbols()<CR>
      nmap <F2> :call CtrlKGoToDefinition()<CR>
      nmap <F12> :call CtrlKGetReferences()<CR>
    


    Где g_ctrlk_clang_library_path должен указывать на путь к libclang.so. Его можно найти, например, запустив

    locate libclang.so
    


    После этого vim, запущенный из директории с compilation database (или любой ее поддиректории) начнет индексировать файлы, и через некоторое время по ним можно начать навигацию. F3 покажет текущий статус парсера, Ctrl+K открывает FuzzyFinder, в котором можно искать символы, F2 перепрыгивает на определение символа, и F12 показывает все места в коде, где символ под курсором используется.

    Если хочется, чтобы строка состояния показывала название текущей функции, то можно ее настроить, например, так:

      hi User1 ctermbg=darkgreen ctermfg=black guibg=darkgreen guifg=black
      hi User2 ctermbg=gray ctermfg=black guibg=gray  guifg=black
      hi User3 ctermbg=darkgray ctermfg=gray  guibg=darkgray  guifg=gray
    
      set statusline=%1*\ %{CtrlKGetCurrentScope()}\ %2*\ %F%m%r%h\ %w\ \ %3*\ %r%{getcwd()}%h%=%l:%c
      set laststatus=2
    


    Вот два примера работы. В первом примере мы запускаем Vim из папки с проектом, нажимаем Ctrl+K, и переходим к файлу. Это не очень удачный пример, потому что к файлу перейти можно и просто используя Fuzzy Finder или CtrlP, но в CtrlK таким же образом можно перейти и к любом классу или другому символу.



    Во втором примере мы опять использум Ctrl+K чтобы найти функцию RestoreStartWorker, в ней позиционируем курсор на классе CodePrinter, и находим все упоминания этого класса в коде, нажав F12. Если бы мы нажали F2, то Vim бы сразу прыгнул на определение класса.



    В этом примере есть небольшая задержка при поиске всех вхождений. На самом деле, она работает моментально, но после первого открытия любого файла проходит 1-3 секунды на его парсинг, и до того, как парсинг закончится, переход на определение и поиск вхождений не работают.

    В завершении, немного про отладку. Для отладки есть несколько плагинов, и они все очень плохие. Я потратил несколько дней, и все-таки сумел установить PyClewn и заставить его работать. PyClewn позволяет устанавливать точки останова, смотреть на локальные переменные, наблюдать за выводом программы прямо из Vim, и позволяет вводить команды для GDB. Это значительно менее удобно, чем интеграция у QtCreator, например, или у любой другой полноценной среды разработки, но немного лучше, чем запускать GDB в отдельном терминале. PyClewn в целом решал проблему, но хотелось большего.
    Мой коллега написал плагин для Vim, который использует TMux, чтобы запустить GDB рядом с Vim на одном экране, и либо управлять им прямо из Vim (например, ставить точки останова, смотреть значения переменных), либо переключаться в окно GDB и просто работать с GDB. Локальные переменные, или поля объектов, можно смотреть в виде дерева в nerd tree. К сожалению, у плагина нет никакой документации, но его установка достаточно проста. Надо установить два плагина через Vundle, а затем настроить vimrc.

    Plugin 'ManOfTeflon/exterminator'
    Plugin 'ManOfTeflon/nerdtree-json'
    


    Если уже используется стандартное nerdtree, то его надо убрать. nerttree-json — это форк nerdtree, который позволяет расширять его возможности, и делать lazy-вычисление элементов дерева.

    Затем вот пример настройки exterminator у автора плагина:

    Скрытый текст
    function! s:get_range()
      " Why is this not a built-in Vim script function?!
      let [lnum1, col1] = getpos("'<")[1:2]
      let [lnum2, col2] = getpos("'>")[1:2]
      let lines = getline(lnum1, lnum2)
      let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
      let lines[0] = lines[0][col1 - 1:]
      return join(lines, "\n")
    endfunction
    
    nnoremap <silent> & :exec 'VimGrep ' . expand('<cword>')<cr>
    vnoremap <silent> & :exec 'VimGrep ' . s:get_range()
    comm! -nargs=0 -range GdbVEval exec 'GdbEval ' . s:get_range()
    
    nnoremap <silent> <F6>  :exec "GdbEval " . expand("<cword>")<CR>
    vnoremap <silent> <F6>  :GdbVEval<cr>
    nnoremap <silent> <F5>  :GdbLocals<CR>
    nnoremap <silent> <F4>  :GdbNoTrack<CR>
    
    nnoremap <silent> <Insert> :GdbContinue<cr>
    nnoremap <silent> <End> :GdbBacktrace<cr>
    nnoremap <silent> <Home> :GdbUntil<cr>
    nnoremap <silent> <S-Up> :GdbExec finish<cr>
    nnoremap <silent> <S-Down> :GdbExec step<cr>
    nnoremap <silent> <S-Right> :GdbExec next<cr>
    nnoremap <silent> <S-Left> :GdbToggle<cr>
    noremap <silent> <PageUp> :GdbExec up<cr>
    noremap <silent> <PageDown> :GdbExec down<cr>
    
    function! s:start_debugging(cmd)
        cd $PATH_TO_EXECUTABLE
        exec 'Dbg ' . a:cmd
    endfunction
    command! -nargs=1 DbgWrapper    call s:start_debugging(<f-args>)
    
    nnoremap <silent> <leader>B :DbgWrapper ./executable<cr>
    


    Где $PATH_TO_EXECUTABLE и ./executable — путь к программе для отладки и ее название.


    С такой конфигурацией в запущенном из TMux Vim можно запустить отладку через \B, в результате чего TMux разделит экран на два, и запустит во втором GDB, связанный с Vim. В частности, при передвижении по фреймам в GDB Vim будет показывать код в текущем фрейме, и из Vim с помощью горячих клавиш можно передвигаться по фреймам, ставить точки останова, выполнять программу по шагам, и показывать значения переменных в nerdtree. В частности, F5 покажет значения всех локальных переменных, а F6 — переменной под курсором.

    Код плагина для навигации по C++ и его серверной части открыты и доступны на GitHub под MIT License:
    https://github.com/SkidanovAlex/CtrlK
    https://github.com/SkidanovAlex/py-ctrlk

    Код плагина для отладки тоже открыт, и доступен под WTFPL лицензией:
    https://github.com/ManOfTeflon/exterminator
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 92

      –27
      Может имеет смысл попробовать современную IDE, вместо того чтобы мучаться с VIM и подобными?
        +3
        Отказ от мышки повышает скорость работы с кодом в полтора-два раза. И как раз выучить приемы для работы достаточно просто.
        Но как же муторно его настраивать для комфортной работы.
          0
          Так там же заявляют vim-emulator плагин
            +13
            Вы так говорите, будто в современной IDE нельзя отказаться от мышки.
              +3
              Может и можно, но это сильно непросто.

              Даже если получится отказаться от мышки — отказаться от использования стрелок практически невозможно.

              Но вот например удобной работы с системой контроля версий и чтобы без мыши я в IDE чего-то ещё не видел. В той же Идее работа с гитом сделана ужасно. Консоль намного удобнее.

              И кстати ещё раз об Идее. Вот надо поискать что-то в тексте проекта. Идея это умеет. Но только в результатах поиска придётся рыться мышкой. Такие дела. Поикать в результатах поиска тоже не выйдет. Даже банальный git grep получается удобнее, чем такой поиск потому, что результаты его работы можно отправить в less и просматривать сколько влезет и искать внутри этих результатов тоже можно.

              Вот замечательно в Идее сделан поиск класса и файлов по названию. И символов по названию. Просто блеск. Но, как показывает автор статьи, воткнуть такой поиск в текстовый редактор не то чтобы совсем не сложно, но реализуемо в разумные сроки. А теперь так вообще доступно каждому, потому что автор всё за нас уже сделал.
                0
                UI для контроля версий часто ограничен, это верно. Но кто мешает переключиться в консоль, набрать git grep, затем назад переключиться в IDEA? Я пользуюсь Eclipse и команды для git нередко ввожу в открытом фаре (открытом с клавиатуры, конечно). Результаты отправляю не в less, а в edit:< в фаре, а там и макросы, и регекспы. Просто в IDE надо делать то, что удобно делать в IDE, а не стремиться делать абсолютно всё в одной программе.
                  0
                  Золотые слова! Так и поступаю.

                  Хотя IDE по определению является такой штукой, в которой надо делать всё.

                  0
                  Для git в vim отлично работает fugitive, который автор статьи как-то вскользь упомянул. В нём возможностей чуть ли не больше, чем в консольном клиенте git. grep, blame, commit, merge — что угодно, не выходя из редактора. Очень удобно.

                  Даже банальный git grep получается удобнее, чем такой поиск потому, что результаты его работы можно отправить в less и просматривать сколько влезет и искать внутри этих результатов тоже можно.

                  git сам перенаправляет длинный вывод в PAGER, самому вызывать less даже не нужно.
                    0
                    fugitive я всё никак не попробую. Наверное потому, что консоли пока хватает с головой. Но может это моё ретроградство, надо устроить себе неделю новых инструментов.

                    И да, git действительно перенаправляет длинный вывод в PAGER, тут я запутался из-за того, что в основном пользуюсь утилитой под названием ag (silver searcher), windows версия которой отстаёт чуть ли не на год. И вот она по умолчанию в less не вызывает. Кстати рекомендую, отличная штука. Если отказывались от grep в пользу ack, переход на ag для вас — острая необходимость.
                      0
                      Да, ag я тоже использую. Его можно из vim вызывать с помощью плагина Ack.vim, указав ему что нужно использовать ag вместо ack:
                      let g:ackprg = "ag"

                      Удобно тем, что результаты открываются в отдельном подокне vim.

                      Ещё есть ag для vim (просто в quicklist добавляет результаты).

                      git grep обычно работает быстрее ag (автор последнего признавался), и его можно из fugitive вызывать (Ggrep).
                      0
                      Одна из первых вещей, которые я сделал, когда начал серьёзно пользоваться git — это убрал нафиг перенаправление в PAGER, поставив core.page = cat. Мне часто нужно набрать в консоли что‐то, зависящее от вывода, перенаправленного в PAGER, но PAGER это делать мешает. Или посмотреть, что было выведено командой раньше, а что сейчас. Если мне нужен less, то написать после команды L (zsh: alias -g L='| less') не проблема, но если он мне не нужен (что чаще), то писать <code>|cat или эквивалентный alias неудобно.
                        0
                        Дело привычки, для меня вывод в PAGER по умолчанию удобен.
                        Для себя повесил bindkey для "| less":

                        zsh (~/.zshrc)
                        bindkey -s '^O' ' | less'
                        


                        bash (~/.inputrc)
                        "\C-o": " | less"
                        
                          0
                          Основные две проблемы с PAGER — это то, что git считает длинными командами всё («git сам перенаправляет длинный вывод» — это неправда, просто less’у можно сказать, чтобы он не возникал, если вывод не слишком длинный (= если он целиком помещается на экране)) и то, что после выхода less в терминале ничего не видно, при этом запустить команду в текущей оболочке из less не получится. alias -g удобнее bindkey, потому что в истории останется alias и его легко удалить и заменить на что‐нибудь ещё.
                            0
                            Обычно у меня проект открыт в нескольких окнах tmux, поэтому less устраивает. В одном окне его вывод, в другом vim/что-то ещё.
                            bindkey в данном случае просто вставляет строку "| less", когда вы его жмёте. То есть, в истории останется. Удалить/заменить — Ctrl-w или fc, никаких проблем.
                              0
                              Да, если считать по количеству клавиш на удаление, то почти одинаково. Количество клавиш на ввод так совсем одинаково. alias -g всё же имеет преимущество, т.к. все удобные <C-…> у меня уже заняты, да и результат выглядит компактнее. Недостаток — может испортить скрипты, загруженные после создания alias’а.

                              Кстати, zsh при использовании emacs варианта раскладки использует widget для <C-w>, который считает, что | следует непременно удалять вместе с предшествовавшим словом (даже если оное отделено пробелом).
                  0
                  [citation needed] ©
                  0
                  Вот когда ее доделают…
                  Пока что есть только EAP, который становится тыквой через 60 дней.
                    +2
                    > Может имеет смысл попробовать мучаться с современнуюой IDE, вместо того чтобы мучаться с VIM и подобными?
                    fixed :)
                      –9
                      Миллионы людей по всему миру платят за современные IDE явно не потому что они мазахисты и им не хватает мучений.
                        +11
                        Это достаточно распространённый аргумент (миллионы не могут ошибаться), и я сомневаюсь, что он верный.
                          0
                          Добавлю, что исходный мой комментарий был шуточным с учётом того, что CLion я не пользовался и ничего относительно конкретно него сказать не могу.
                            0
                            Я пытался пользоваться CLion, он просто невероятно тормозной на больших проектах. Снёс его, когда он за полчаса смог распарсить около половины проекта. Тот же NetBeans быстрее в несколько раз.
                            +3
                            Пфф, миллионы неосиляторов :)
                          +4
                          Лично я на столько привык к VIM, что с другими редакторами и IDE приходится мучится.
                            +6
                            Судя по количеству ваших постов в блоге Jetbrains, вы правы.
                              +1
                              Да, я слежу за CLion, и даже был на приватной бете с ее самого начала. CLion пока что не так хорош, как другие среды Jet Brains, и немного неповоротлив. Сегодня, если бы я работал в графической среде, я бы по прежнему выбрал QtCreator, но я тоже верю, что у CLion большое будущее.

                              В любом случае, отвечая на ваш вопрос, я часто работаю удаленно, и мне удобно, когда я могу подцепиться по SSH, запустить Vim и работать так.
                                0
                                Не нужно «работать удаленно», нужно так настроить окружение, чтобы «удаленная работа» не требовалась — это само по себе даст огромный прирост в производительности, причем всем членам команды, а не только вам. Получается, вы пользуетесь vim не потому, что он удобнее, а потому, что при удаленной работе по SSH у него нет и близко никаких сколь-нибудь похожих по удобству аналогов. Т.е. перепутаны причина и следствие как бы, происходит личение симптомов, а не болезни.
                                  0
                                  Согласен, но я не хочу пользовать git и сборщиком для обслуживания корпоротивного сайта моей компании. Когда мне нужно поменять background-color в css сайта, я захожу на сервер и меняю его с помощью vim. С другой стороны, все это можно сделать и с помощью ed или nano, но с vim привычнее и быстрее получается.
                                  0
                                  А что Вам мешает запускать ssh с ключем -X и QtCreator на удаленной машине с X11 Forwarding? Или он так тормозит?
                                  0
                                  Вообще он пока не очень пригоден, тк умеет только проекты с CMake
                                    +6
                                    Вы так говорите, будто vim и прочие emacs устарели.
                                      –3
                                      Судя по тому, что в них практически «из коробки» (я имею в виду, в виде плагинов, которые можно установить за 10 секунд, а не как у автора топика) нет таких очевидных и нужных вещей, как поиск по символам, отладка и т.д., они и правда либо устарели (устаревают), либо же их подавляющее большинство людей используют для других целей. Как еще объяснить логически описанную автором обстановку?
                                        +3
                                        Vim выбирают те, кому не нужна эта ваша «коробка», он не для беспомощных юзеров, неспособных настроить инструмент под себя. И он не старается стать bloatware-комбаином, имеющим дистрибутив в 200Мб, содержащий всё-всё-всё. Отдельные нужные фичи разрабатываются в виде плагинов и подключаются по мере надобности. И я не увидел никаких смертельных препятствий по их установке в топике.
                                          –3
                                          Простите, но я не верю про «не для беспомощных юзеров». Популярные проекты обычно развиваются в сторону упрощения своего использования, потому что если сильно популярный проект сложно использовать, то рано или поздно основные усилия (даже неосознанно) начинают тратиться на поддержку пользователей (пусть даже и на ответы в листе рассылки). Представьте себя на месте разработчиков: если им приходит 100 обращений от пользователей с сообщением о неудобстве чего-то, то разработчику даже морально трудно это «что-то» не улучшить (в живом проекте). Если же жалоб на неудобство не приходит при объективном их наличии, то либо этих неудобств нет (т.е. продукт используют в контексте, где неудобства не возникают), либо же продукт не так уж и популярен на самом деле. О чем я и писал.

                                          Я не хочу сказать, что vim плохой — он хороший. Но только используют ли его массово для написани c++-кода в здоровом проекте без боли? Судя по описанному в статье состоянию с плагинами — вряд ли массово. (А вот чтобы «разово зайти на сервер корпоративного сайта напрямую и заговнокодить поправить 1 строчку в css» — это очень даже используют, тут вопросов нет.)
                                    0
                                    Я таким образом пытался пересесть с Qt Creator на emacs. Но так и не смог настроить в последнем удобную IDE с поддержкой cmake проектов для C++. Вроде как плагинов много, но все они какие-то кривые.

                                    А насчет интеграции с GDB, мне нравится CGDB консольная обертка с довольно приятным интерфейсом.
                                      0
                                      Советую вам загуглить fishman ctags — это форк ctags на гитхабе, наиболее активно поддерживаемый на данный момент. Также имеет смысл посмотреть форки этого форка — многие на его базе делают свои улучшения в парсерах разных языков. Но не всегда сливают эти изменения в upstream, потому что fishman ctags в каком-то роде ставит задачу убрать из ctags все парсеры на регулярках и сделать хотя бы на подобии грамматик.
                                        0
                                        А этот fishman ctags также делает просто синтаксический поиск, без семантического? Т.к. это пожалуй самая главная проблема ctags, когда в большом проекте он выдает много не релевантных ссылок…
                                          0
                                          Знаете, я тоже долгое время страдал от этой проблемы, но в PHP, в итоге просто немного переписал Ctags, чтобы оно генерировало тэги вида:

                                          getName:Student.php:27
                                          getName:Lector.php:3

                                          вместо

                                          getName:Student.php:27
                                          getName:Lector.php:3

                                          теперь клик по методу… не работает, но зато метод вставляется в строку поиска по тэгам(у меня emacs), и к нему достаточно дописать <L или <S, чтобы перейти на нужный метод нужного класса. Это выглядит криво, но довольно удобно.
                                            +2
                                            А в чём разница между тегами? Может, вы случайно вставили одно и то же, или я чего-то не вижу?
                                              +2
                                              Да, хабр съел часть тэгов:

                                              getName<Student>:Student.php:27
                                              getName<Lector>:Lector.php:3
                                              
                                              вместо
                                              
                                              getName:Student.php:27
                                              getName:Lector.php:3
                                              
                                            0
                                            А CtrlK как раз делает семантический поиск.
                                          –14
                                          Извините, Александр, я не увидел, или вы не написали, зачем же вам всё-таки приходится работать в VIM, а не в практически прекрасном CLion?
                                            +9
                                            Ну потому, что VIM лучше, вроде очевидно.
                                              +8
                                              CLion ещё очень далеко от понятия «прекрасный».
                                                +1
                                                Как минимум нетривиально запустить CLion на удаленном сервере или настраивать удаленную компиляцию или что-то такое.
                                                  0
                                                  А зачем настраивать удалённую компиляцию с помощью IDE, когда для этого есть другие инструменты (CI)?
                                                    0
                                                    Например, поправить пару строк, собрать, перезапустить бинарник на серваке и подебагать его. Неочевидно как такое сделать с IDE.
                                                      +2
                                                      Удалённая компиляция это одно, а CI совершенно другое.
                                                        –1
                                                        Что именно вы понимаете под удалённой компиляцией, чего какой-нибудь TeamCity не может?
                                                          +1
                                                          Ну например есть код, который надо скомпилировать, но рабочий компьютер делает это медленно. Настраиваем компилятор на другом компьютере, который только компиляцией и занимается, собираем код там, запускаем у себя. Вот так как-то.

                                                          Team City он вообще про другое.
                                                            0
                                                            Разве это не тоже самое, что рабочий компьютер -> commit -> TS подбирает все изменения и билдит проект?

                                                            P.S. А почему мы вообще про удалённую компиляцию говорим? Что нам мешает сделать тоже самое из CLion?
                                                              +2
                                                              Нет, не тоже самое. Прежде всего потому, что результаты появятся прямо на рабочем компьютере, как будто именно на нём шёл процесс компиляции. Ну и комитить код для каждой компиляции — несколько экстравагантно :).

                                                              Разговор про удалённую компиляцию начал не я. Я просто отметил, что это не CI. Наверняка можно CLion настроить так, чтобы он это делал. Правда наверное это нетривиальная задача. Хотя кто его знает, я больше по Идее.

                                                              Однако с IDE вообще есть одна проблема — если поддержки чего-то там нет — то остаётся только сидеть и ждать, когда она появится. Если есть привычка обходиться консолью, мощным текстовым редактором и скриптами автоматизации — такой проблемы как правило нет.
                                                                0
                                                                Вот кстати не совсем согласен с тем, что «если поддержки чего-то там нет — то остаётся только сидеть и ждать». Это уж точно не про продукты JB. Ведь есть прекрасный репозиторий плагинов. Кроме того, вы можете написать и свой плагин. Это, во-первых, решит вашу текущую задачу, а, во-вторых, увеличит шанс попасть к этим парням на работу. Насколько я понимаю, JB любит хантить тех, кто делает добро для них.

                                                                И, кажется, TS всё-таки умеет удалённую компиляцию — confluence.jetbrains.com/display/TW/How+to+make+a+remote+run+from+IntelliJ+IDEA
                                                                  0
                                                                  Вариант «сделать самому» есть всегда и везде. Тут вопрос в трудоёмкости задачи. Вот не не нравится вам как в Идее реальзован поиск класса по имени. Хотя нет, это плохой пример, этот поиск в Идее реализован прекрасно. А вот простой поиск в идее проблемный. И хочется его заменить на другой — хороший. И как быть дальше? Подсказываю — придётся программировать.

                                                                  В случае с vim или emacs стронние поисковые утилиты прикручиваются на раз. На раз же, как показал автор, прикручивается и поиск классов и методов.

                                                                  Ну а прикрутить к Идее текстовый редактор типа вима — вообще задача на годы.

                                                                  P. S. То, что вы показали — не совсем то. Совсем то это distcc по моему.
                                                            0
                                                            Она я думаю может сделать все что нужно, но это будет неудобнее, то есть нужно либо будет както собранный пакет или во что оно там соберет копировать на рабочий сервер, либо поднимать этот TeamCity на сервере, куда нужно быстро поставить дебажную версию программы. В общем целое дело. Собрать пакет из искодников прямо на целевом сервере с нужными правками сильно проще и быстрее.
                                                              0
                                                              У меня кофьюз случается вот на месте «собрать пакет из исходников на сервере». Я не особо знаком со спецификой продакшен разработки на С++, но как-то это не вяжется в моей голове, когда такое придётся делать.

                                                              Как мне всегда казалось, обычно всё проходит по следующему сценарию:
                                                              Коммиты -> CI-сервер -> build -> tests -> deploy. Но, видимо, и другие жизненные циклы случаются.
                                                                0
                                                                Я конкртено описывал вариант, когда нужно что-то попробовать быстро и проверить, без обычного цикла и раскатки на тысячи серваков дебажного кода.
                                                                  0
                                                                  Ну, допустим, есть у меня embedded железка с linux на борту. Мне нужно отдебажить код на ней.

                                                                  Закинув туда свой конфиг от emacs'а, я получаю по SSH редактов, идентичный тому, который использую на десктопе и могу полноценно работать на той железяке.

                                                                  Разрекламированный в комментах CLion я, скорей всего, на этой железке даже запустить не смогу, не то, что получить его GUI через SSH.
                                                                    0
                                                                    Вот, наконец-то мы дошли до внятного места, где приходится использовать «не нормальную» IDE, а нечто простое. В принципе, в своём первом комментарии я у автора про это и спрашивал: пишет он для эмбеда, или какая ещё причина, почему VIM.
                                                                      0
                                                                      И вам сразу и ответили, что VIM банально лучше. Далее разговор шёл о том, что такого может VIM, чего не может IDE. Ну и в общем через пень-колоду IDE может всё, что может вим. За исключением редакторивания кода конечно :).
                                                      +1
                                                      А чего Вам удалось со всем этим зоопарком добиться принципиально такого, чего нет в Qt Creator? Всё, что Вы так упорно настраивали, там есть из коробки, а Vim-режим включается в настройках. Этот режим чего-то нужного не эмулирует?
                                                        0
                                                        Включив FakeVim ломается Ctrl+B, Ctrl+R (билд и запуск проекта), нельзя с клавиатуры перенести фокус в область дерева исходников, ну и в этой области FakeVim уже не работает (например навигация j,k).
                                                          –3
                                                          Vim-режим включается в настройках. Этот режим чего-то нужного не эмулирует?

                                                          Это сложно объяснить тому, для кого «модальное редактирование», имеет два состояния: бибикать после нажатия и все портить после .

                                                          vim — единственный на сегодня редактор, делающий упор на модальное редактирование. Современные IDE очень далеко шагнули в плане рефакторинга, навигации, дополнения кода — без всего этого они просто notepad.exe, а модальный режим там реализован убого и, скорее, «для галочки». Эти notepad'ные кишки постоянно вылезают в самое неподходящее время: в коде символ «some_long_function_name», а нужно сделать из нее «some_not_so_short_name»? Жмем «f_lc2t_not_so_short», чтобы перейти к началу «long», а затем удалить все до «_» перед «name» понадобилось всего три команды:
                                                          1. найти «_» (f_)
                                                          2. двинуться на символ вправо (l)
                                                          3. удалить весь текст до второго «_» и перейти в режим редактирования (c2t_)

                                                          Когда начинаешь воспринимать редактирование не как «удалить 20 символов», а «удалить три следующих слова» или «очистить до «)», все становится значительно быстрее и, главное, ошибок становится меньше.
                                                            +9
                                                            Ага, только вот как-раз эта привязка к уровню слов, абзацев, поиску до ")" и является тем камнем, который тянет на дно. Я хочу мыслить более высокоуровневыми терминами. Мне не нужно текст «some_long_function_name» заменить на «some_not_so_short_name». Мне нужно в классе А переименовать пол Х в поле У, причём так, чтобы это произошло и в заголовочном файле и в файле кода, и в 28 местах других файлов, где на это поле ссылаются, с учётом полиморфизма в классах-наследниках. И при этом чтобы поле с тем же именем Х у класса B и ссылки на него не поменялись.

                                                            Ещё мне нужно вынести часть кода метода в отдельный метод. И нет, не «вырезать эти 5 строк и вставить выше», а с автоматическим выводом передаваемых аргументов и типа возврата и правкой кода.

                                                            Ну-ка расскажите, как vim со своим отличным модальным редактированием всё это сделает? А IDE справляются.

                                                            Текстовый редактор — он как раз для текста. А код — это не столько текст, сколько отображение абстракций на плоскость терминов языка программирования. Vim может быть и даёт удобные средства ползания по этой плоскости, но поднять голову вверх и взглянуть, что же за сущности отбрасывают эти тени — не позволяет.

                                                              –1
                                                              Я долго пользоват продукцию Jet Brains (даже бесплатную лицензию для OpenSource проектов от них получил), восхищался автодополнением, системой рефакторинга, даже интеграция с git нравилась. После перехода (часть проектов я все еще пишу с помощью этих IDE) на vim я понял, что проекту с хорошей архитектурой не требуется изменят имена классов, их полей, методов и аргументов, так же им не требуется выносить часть кода в другие методы и так далее. Для «чистых» проектов, я пользую Vim и ни разу у меня не возникало проблем с рефакторингом, а для «грязных» пользую IDE.
                                                                0
                                                                Хорошо, конечно, жить, если в проекте не меняются требования и архитектура, только где же в реальном мире такие проекты взять?
                                                                  0
                                                                  Я не говорил, что требования и архитектура не меняется, это вы сказали.
                                                                    0
                                                                    Ну ок, и как в проекте, где по требованию заказчика на 40% была изменена вообще предметная область решаемой задачи обойтись без хороших инструментов рефакторинга?
                                                                      0
                                                                      На 40%? Вытащить из проекта компоненты, которые можно использоваться в новом и написать остальное заново.
                                                                        0
                                                                        А «вытащить компоненты» — это рефакторинг и есть. Ну и плюс всё, что случается в промежутке с изменениями требований от 0 до 20%.
                                                                          0
                                                                          Нет, это не рефакторинг. Рефакторинг это изменение архитектуры или структуры программы так, что внешне она кажется неизменной.
                                                                            0
                                                                            Вот только само по себе, «в вакууме» это не происходит, а делается для дальнейшего изменения\улучшения архитектуры.
                                                                              0
                                                                              Давайте называть вещи своими именами. Как уже было сказано выше, если клиент меняет требования кардинально, то часть ваших пакетов в неизменном виде (никакие имена не меняются) переносятся в новую структуру, и функциональности рефакторинга IDE здесь не нужно. Если в процессе XP вы решили изменить архитектуру пакета, то рефакторинг даст малую прибавку к скорости.
                                                                0
                                                                Переименование методов и переменных? Можно найти строннюю утилиту, которая этим занимается и прикрутить к редактору. Clang, кстати, по моему может. Вон в Go вообще из коробки такой функционал.

                                                                Выделение кода в метод мне удобнее делать руками. Это не сильно трудоёмкая операция.

                                                                Но вернёмся к переименованию методов и переменных. Зачастую бывает так, что названия методов и свойств java класса используются в хитром джаваскрипте и там они никак не привязаны к самим классам и инструмент для рефакторинга их проигнорирует. И собственно всё — уверенности в безопасности рефакторинга не больше, чем в случае с вимом.
                                                                  0
                                                                  Иногда мне кажется, что еще чуть-чуть и я буду готов доплатить, чтобы меня взяли в контору, где большую часть времени не пишут код, не меняют бизнес-логику, а именно переименовывают методы и меняют их сигнатуры. Просто чтобы посмотреть что же я упускаю в жизни.

                                                                  Vim может быть и даёт удобные средства ползания по этой плоскости, но поднять голову вверх и взглянуть, что же за сущности отбрасывают эти тени — не позволяет.


                                                                  Уровень абстракции человека — это те самые сущности, которые он описывает в виде текста. Уровень абстракции IDE — это AST, символы, связи между символами. Это даже не нечто среднее между текстом и сущностями, это просто способ, который бы позволил хоть как-то обрабатывать код автоматическими инструментами.
                                                                    0
                                                                    Ещё мне нужно вынести часть кода метода в отдельный метод

                                                                    А еще не помешало бы научиться читать и усваивать прочитанное: русским по белому было написано, что рефакторинг и навигация в IDE (пока) лучше.
                                                                      0
                                                                      Да, например, почти никто не использует Vim, чтобы писать на Java. Потому что у нее есть хорошая среда, возможности которой покрывают удобство привычного текстового редактора.
                                                                      Но в С++ все эти рефакторинги работают не очень хорошо, особенно если есть templates. Поэтому привычный Vim с плагинами более чем достаточен для того, чтобы разрабатывать на С++.

                                                                      Ну и добавить рефакторинги в CtrlK — это, скажем, не так сложно. Просто никто пока не сделал.
                                                                        0
                                                                        Вообще-то в одной известной IDE упомянутое вами весьма толково реализовано с помощью внешнего дополнения (где не надкушенное яблоко, а целый помидор). Равно как и в vim также можно подключать всевозможные плагины. Сейчас, конечно, они пытаются сделать свой вариант, но имхо добраться до уровня того дополнения им пока не удалось.

                                                                        Единственная проблема — что конкретно толкового дополнения для рефакторинга пока нет. Но проблема, думаю, там не в vim а в маркетинге (как-то нужно будет мотивировать любителей vim купить такой плагин)
                                                                      +1
                                                                      Ага, он не эмулирует Vim.
                                                                        0
                                                                        Эмулятор в Qt Creator слабый, но он развивается. Когда я пересаживался на vim, я открыл баги на некоторые вещи, которых тогда не хватало, их к следующему релизу добавили.
                                                                        Задача была не в том, чтобы сделать лучше, чем Qt Creator, задача была в том, чтобы сделать достаточно для нормальной работы.
                                                                        Как я выше сказал, один из больших плюсов Vim — это возможность зайти по SSH, запустить его и работать. Помимо этого, мне просто удобнее работать в полноценном Vim, с макросами, Easy Motion и другими плюшками.
                                                                        +4
                                                                        Понял все прелести Vim после месяца работы с ним. Теперь ощущение, что мой мозг сам принимает решения о том, как сделать манипуляции с текстом минимом клавиш. А скорость работы такая, что самое медленное в написании кода, это я, а не редактор.
                                                                          0
                                                                          Исторически сложилось так, что pip package для ctrlk принадлежит не мне. В текущем package есть две недоработки — не указана зависимость от ez_setup, ее можно разрешить руками
                                                                          Если вас не устраивает текущий владелец пакета, а добавить вас в качестве владельца он отказывается, то вы можете попросить людей из PyPI, чтобы они добавили вас сами: по этой ссылке я делал такое для powerline-status.
                                                                            0
                                                                            Мы уже эту проблему решили, но спасибо за совет.
                                                                            0
                                                                            /me никогда не умел готовить CTags, еще со времен сидения на emacs (до того был немодный gvim), и вот в чем дело: словарный автокомплит и переходы по коду оно-то умеет, но вот контекста, определения того, что можно сделать с только что введенным токеном, — у него нет. Или я ошибаюсь? )
                                                                              0
                                                                              Да, именно эту проблему и решает CtrlK, он использует libclang чтобы проиндексировать все файлы, и его же, чтобы понять контекст в текущем файле, поэтому переходы и поиск упоминаний семантические.

                                                                              YouCompleteMe, плагин для автодополнения, тоже использует libclang, поэтому автодополнения у него тоже семантические, с пониманием контекста.
                                                                              0
                                                                              Не осилил установку CtrlK. Не понимаю как мне согласовать pip, vundle и мой пакетный менеджер (emerge в gentoo) — простите, питонист из меня пока плохой.

                                                                              gdb-шный плагин интересный. Пальцы кровоточат от разных хоткеев переключения между окнами (ctrl-b+стрелки для tmux, winkey+«hjkl» для awesome-wm и Ctlr-o+«hjkl» для vim-а), но главное сама идея.
                                                                                0
                                                                                Автор плагина для GDB проблему с хоткеями частично решил, сделав, что хоткей для переключения в vim между окнами и для tmux одинаковый. При этом в виме если переключиться левее самого левого окна, он переключится в следующее окно слева в TMux. Смотрите в этом репозитории конфиг tmux, конфиг вима, и tmux_vim_intergration.sh в bin
                                                                                https://github.com/ManOfTeflon/config

                                                                                По-поводу CtrlK, надо сначала установить clang через пакетный менеджер, если его еще нет, затем leveldb, clang и ctrlk через pip (сейчас ctrlk должен устанавливаться без проблем), после чего добавить плагин в Vundle. Пишите в личку, если какой-то шаг не работает, помогу разобраться.
                                                                                  0
                                                                                  Я просто переживаю, что мне pip намусорит в системе (там и snappy и tornado и ещё что-то).
                                                                                0
                                                                                cd ~/devel/my-project
                                                                                mkdir build
                                                                                cd build
                                                                                cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
                                                                                gvim ../src/mysource.cpp
                                                                                


                                                                                Именно так, чтобы можно было из vim-а делать mak, не мусоря в корне проекта.

                                                                                В gvim'е: CtrlK — работает как часы, от F2 и F12 никакой реакции.

                                                                                F3:
                                                                                Index: Initializing / Current: Initializing / Jump: normal
                                                                                


                                                                                Что я делаю не так? И что я должен бы делать?
                                                                                  0
                                                                                  При попытке:
                                                                                  cd ~/devel/my-project
                                                                                  cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
                                                                                  gvim ../src/mysource.cpp
                                                                                  

                                                                                  gvim мертво виснет ctrlk_server.py вот уже 7 минут жрёт 100% одного из ядер CPU и под 120Мб оперативки.

                                                                                  Простите, пока придётся остаться на связке Indexator+CtrlP. Но очень заинтересовали и буду рад, если починитесь.
                                                                                    0
                                                                                    Все действия, которые вы сделали, выглядят правильно. Проблему попробую воспроизвести и исправить.
                                                                                      0
                                                                                      Пробовал на трёх разных проектах — везде одно и то же.
                                                                                      версии используемого ПО
                                                                                      ☭ tmp/survey/build [devel] clang --version
                                                                                      clang version 3.3 (tags/RELEASE_33/final)
                                                                                      Target: x86_64-pc-linux-gnu
                                                                                      Thread model: posix
                                                                                      ☭ tmp/survey/build [devel] python --version
                                                                                      Python 2.7.7
                                                                                      ☭ tmp/survey/build [devel] pip --version
                                                                                      pip 1.4.1 from /usr/lib64/python2.7/site-packages (python 2.7)
                                                                                      ☭ tmp/survey/build [devel] gvim --version
                                                                                      VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 29 2014 02:48:34)
                                                                                      Заплатки: 1-527
                                                                                      С изменениями, внесёнными Gentoo-7.4.527
                                                                                      Скомпилирован  hoxnox@localhost
                                                                                      Огромная версия с графическим интерфейсом GTK2.  Включённые (+) и отключённые (-) особенности:
                                                                                      +acl             +farsi           +mouse_netterm   +syntax
                                                                                      +arabic          +file_in_path    +mouse_sgr       +tag_binary
                                                                                      +autocmd         +find_in_path    -mouse_sysmouse  +tag_old_static
                                                                                      +balloon_eval    +float           +mouse_urxvt     -tag_any_white
                                                                                      +browse          +folding         +mouse_xterm     -tcl
                                                                                      ++builtin_terms  -footer          +multi_byte      +terminfo
                                                                                      +byte_offset     +fork()          +multi_lang      +termresponse
                                                                                      +cindent         +gettext         -mzscheme        +textobjects
                                                                                      +clientserver    -hangul_input    -netbeans_intg   +title
                                                                                      +clipboard       +iconv           +path_extra      +toolbar
                                                                                      +cmdline_compl   +insert_expand   +perl            +user_commands
                                                                                      +cmdline_hist    +jumplist        +persistent_undo +vertsplit
                                                                                      +cmdline_info    +keymap          +postscript      +virtualedit
                                                                                      +comments        +langmap         +printer         +visual
                                                                                      +conceal         +libcall         +profile         +visualextra
                                                                                      +cryptv          +linebreak       +python          +viminfo
                                                                                      +cscope          +lispindent      -python3         +vreplace
                                                                                      +cursorbind      +listcmds        +quickfix        +wildignore
                                                                                      +cursorshape     +localmap        +reltime         +wildmenu
                                                                                      +dialog_con_gui  +lua             +rightleft       +windows
                                                                                      +diff            +menu            -ruby            +writebackup
                                                                                      +digraphs        +mksession       +scrollbind      +X11
                                                                                      +dnd             +modify_fname    +signs           -xfontset
                                                                                      -ebcdic          +mouse           +smartindent     +xim
                                                                                      +emacs_tags      +mouseshape      -sniff           +xsmp_interact
                                                                                      +eval            +mouse_dec       +startuptime     +xterm_clipboard
                                                                                      +ex_extra        -mouse_gpm       +statusline      -xterm_save
                                                                                      +extra_search    -mouse_jsbterm   -sun_workshop    +xpm
                                                                                                  общесистемный файл vimrc: "/etc/vim/vimrc"
                                                                                               пользовательский файл vimrc: "$HOME/.vimrc"
                                                                                        второй пользовательский файл vimrc: "~/.vim/vimrc"
                                                                                                пользовательский файл exrc: "$HOME/.exrc"
                                                                                                 общесистемный файл gvimrc: "/etc/vim/gvimrc"
                                                                                              пользовательский файл gvimrc: "$HOME/.gvimrc"
                                                                                       второй пользовательский файл gvimrc: "~/.vim/gvimrc
                                                                                      "
                                                                                                   общесистемный файл меню: "
                                                                                      $VIMRUNTIME/menu.vim"
                                                                                                значение $VIM по умолчанию: "/usr/share/vim"
                                                                                      Параметры компиляции: x86_64-pc-linux-gnu-gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -pthread -I/usr/include/gtk-2.0 -I/usr/lib64/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libdrm -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/freetype2    -O2 -pipe -fomit-frame-pointer -mtune=native -march=native -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1      
                                                                                      Сборка: x86_64-pc-linux-gnu-gcc   -Wl,-E  -Wl,-O1 -L/usr/local/lib -Wl,--as-needed -o gvim   -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfreetype -lfontconfig  -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE  -lm -lncurses -lelf   -lacl -lattr -ldl  -L/usr/lib -lluajit-5.1 -Wl,-E -Wl,-O1 -Wl,--as-needed  -L/usr/lib64/perl5/5.18.2/x86_64-linux/CORE -lperl -lnsl -ldl -lm -lcrypt -lutil -lc -L/usr/lib64/python2.7/config -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic  
                                                                                      

                                                                                Only users with full accounts can post comments. Log in, please.