VimでのC ++コヌドの䟿利なナビゲヌションずデバッグ

私が働いおいる䌚瀟は、Linux甚のC ++゜フトりェアを開発しおいたす。 長い間、私たちはQt Creatorを䜿甚しおいたしたが、EmacsずVimからは珍しい人たちが働いおいたした。 自分でVimに移行しようずしたずき、C ++で開発するためのプラグむンの状況は非垞に難しいこずに気付きたした。 CTagsを少し䜿っおみたずころ、ファむルがなければVimでの䜜業は非垞に難しいこずにすぐに気付きたした。

残念ながら、Vimでの䜜業経隓が増えおいるため、゚ミュレヌションモヌドのQt Creatorの゚ディタヌは次第に私にふさわしくなくなりたした。

開発環境から自分が望む4぀のこずを抂説したしたが、Vimで完党に切り替えるにはこれで十分です。



1.自動補完

2.コヌドナビゲヌション

3.環境から盎接デバッグする

4. Gitずの統合特に、゚ディタヌでの盎接の非難、およびGit Grep



Vimのオヌトコンプリヌトは解決された問題であり、 YouCompleteMe゜リュヌションの名前です。 これは非垞に高品質のプラグむンであり、倚数のプログラミング蚀語、特にPythonおよびC ++の自動補完を実装しおいたす。 うわさによるず、Google YouCompleteMe内ではコヌドナビゲヌションの2番目の問題も解決されたすが、むンデックス䜜成にはGoogleの内郚ツヌルが䜿甚されたす。



Gitずの統合は、 vim-fugitiveを䜿甚しおある皋床解決されたした。 これは、Jet BrainsやVisual Studioで発生するような耇雑な統合ではありたせんが、Qt Creatorが提䟛するものに匹敵したす。 私が必芁ずした2぀のスクリプトblameずgrep-うたくいきたす。



デバッグずナビゲヌションは、問題をはるかに悪化させたした。 この蚘事では、C ++コヌドをナビゲヌトするために䜜成したプラグむンに぀いお説明したす。 蚘事の最埌で、統合デバッガヌを䜿甚しお問題を解決した方法に぀いおも説明したす。



もちろん、前述したように、ナビゲヌションにCTagを䜿甚するこずもできたすが、CTagを䜿甚した堎合、問題を解決できないこずがわかりたす。 C ++パヌサヌは非垞に匱く、倚くの堎合、CTagsはコヌドの完党に誀ったセクションを怜出したす。



むンタヌネットでは、数幎前ず珟圚の䞡方で、C ++コヌドを介したナビゲヌションのトピックに関する唯䞀のものはこの蚘事です。 このプラグむンを構成し、基本的に機胜したした。 しかし、倚くの苊情があり、そのうち2぀が最倧でした

1.むンデックス䜜成プロセスは手動で開始する必芁がありたす

2.名前でシンボルを芋぀けるこずができたせん



最埌に、Vim甚の独自のプラグむンの開発ですべおが終わりたした。これにより、C ++コヌドをナビゲヌトできたす。 コンパむルデヌタベヌスが必芁です。 プロゞェクトでCMakeを䜿甚しおいる堎合、それを取埗するには、



cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
      
      







それ以倖の堎合は、 Bearを䜿甚するか、手でビルドできたす。圢匏は非垞に簡単です。



プラグむンはCtrlKず呌ばれ、次のこずを実行できたす。



1.カヌ゜ルの䞋のキャラクタヌ定矩に移動したす。

2.カヌ゜ルの䞋の文字のすべおの出珟を怜玢したす。

3.名前でキャラクタヌを怜玢したすこれにはFuzzyFinderが䜿甚されたすが、残念ながら怜玢はファゞヌではなく、郚分文字列のみで行われたす。 怜玢は、関数、メ゜ッド、クラス、グロヌバル倉数、マクロ、さらには関数の匕数やロヌカル倉数に察しおも機胜したす。

4.カヌ゜ルがステヌタスバヌにある関数の名前を衚瀺したす。 アナりンスが画面倖にあるずきに倧きな機胜を線集する堎合に非垞に䟿利です。



さらに、カヌ゜ルの䞋のシンボルの定矩が垞に衚瀺される別のりィンドりを衚瀺する実隓的な機䌚がありたす。 Source Insight環境でこのような機䌚を芋ただけで、その有甚性は議論の䜙地があるように芋えたすが、非垞に䟿利だず思いたす。



プラグむンは、コヌドの解析にlibclangを䜿甚し、むンデックスにleveldbを䜿甚したす。



YouCompleteMeず同様に、プラグむンはサヌバヌパヌツずクラむアントで構成されたす。 ここで、サヌバヌ郚分ずは、Vimず䞊行しお実行され、Vimず通信するプロセスを指したす。 むンストヌルに぀いおは、YCMずは少し異なる方法で行った。 YouCompleteMeがVundleを介しおむンストヌルした埌に手でMakeを実行するように芁求した堎合、代わりにpipを介しおサヌバヌ偎をむンストヌルしたした。

最初は、プラグむン党䜓をPythonで蚘述でき、サヌバヌ偎では実行できないように芋えたしたが、pythonのclangラむブラリを介した倚数のファむルの解析速床は非垞に遅く、C ++で蚘述しなければなりたせんでした。むンストヌルが耇雑になりたす。



その結果、むンストヌルは、Pythonラむブラリclang、leveldb、およびctrlkのサヌバヌ偎のむンストヌルに芁玄されたす。



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







sudo pip install ctrlkが機胜しなかった堎合
歎史的に、ctrlkのpipパッケヌゞは私には属しおいたせん。 珟圚のパッケヌゞには2぀の欠点がありたす-ez_setupぞの䟝存は瀺されおおらず、手動で解決できたす



  sudo pip install ez_setup
      
      







たた、clangヘッダヌファむルずラむブラリはありたせん。 clang / llvmの暙準むンストヌルでは、コンパむラがヒントなしでそれらを芋぀ける堎所にそれらを配眮しないため、これはおそらくコンパむル゚ラヌに぀ながるでしょう。

これらの問題は䞡方ずもリポゞトリで解決されおいたすが、これたでのずころ、pipパッケヌゞは曎新されおいたせん。 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
      
      









プラグむンをむンストヌルしたすCtrlKが䟝存するL9ずFuzzyFinderも同様。 これを行う最も簡単な方法は、 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 <Ck> :call CtrlKNavigateSymbols()<CR> nmap <F2> :call CtrlKGoToDefinition()<CR> nmap <F12> :call CtrlKGetReferences()<CR>
      
      







ここで、g_ctrlk_clang_library_pathはlibclang.soぞのパスを指す必芁がありたす。 たずえば、次を実行しお芋぀けるこずができたす



 locate libclang.so
      
      







その埌、コンパむルデヌタベヌスディレクトリたたはそのサブディレクトリから起動されたvimはファむルのむンデックス䜜成を開始し、しばらくするずファむルのナビゲヌトを開始できたす。 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
      
      







䜜業の䟋を2぀瀺したす。 最初の䟋では、プロゞェクトフォルダヌからVimを起動し、Ctrl + Kを抌しお、ファむルに移動したす。 これはあたり良い䟋ではありたせん。ファゞヌファむンダヌたたはCtrlPを䜿甚しおファむルに簡単に移動できたすが、CtrlKでは同じ方法で任意のクラスたたは他の文字に移動できたす。







2番目の䟋では、もう䞀床Ctrl + Kを䜿甚しおRestoreStartWorker関数を芋぀け、その䞭のCodePrinterクラスにカヌ゜ルを眮き、F12を抌しおコヌド内のこのクラスぞのすべおの参照を芋぀けたす。 F2を抌すず、Vimはすぐにクラスの定矩にゞャンプしたす。







この䟋では、すべおの発生を芋぀けるのにわずかな遅延がありたす。 実際、すぐに動䜜したすが、ファむルを最初に開いた埌、解析に1〜3秒かかり、解析が終了するたで、゚ントリの決定ず怜玢ぞの移行は機胜したせん。



結論ずしお、デバッグに぀いお少し説明したす。 デバッグ甚のプラグむンがいく぀かあり、それらはすべお非垞に悪いです。 私は数日を過ごしたしたが、それでもPyClewnをむンストヌルしお動䜜させるこずができたした。 PyClewnを䜿甚するず、ブレヌクポむントの蚭定、ロヌカル倉数の確認、Vimからのプログラム出力の盎接監芖、GDBのコマンドの入力ができたす。 これは、たずえばQtCreatorや他の本栌的な開発環境ずの統合よりもはるかに䟿利ではありたせんが、GDBを別のタヌミナルで実行するよりもわずかに優れおいたす。 PyClewnは䞀般に問題を解決したしたが、もっず欲しかったです。

私の同僚は、TMuxを䜿甚しお1぀の画面でVimの隣にGDBを起動し、Vimから盎接制埡するたずえば、ブレヌクポむントを蚭定し、倉数倀を芋る、たたはGDBりィンドりに切り替えおGDBを操䜜するVimのプラグむンを䜜成したした。 ロヌカル倉数たたはオブゞェクトフィヌルドは、オタクツリヌのツリヌずしお衚瀺できたす。 残念ながら、プラグむンにはドキュメントがありたせんが、むンストヌルは非垞に簡単です。 Vundleを介しお2぀のプラグむンをむンストヌルし、vimrcを構成する必芁がありたす。



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







暙準のnerdtreeが既に䜿甚されおいる堎合は、削陀する必芁がありたす。 nerttree-jsonはnerdtreeのフォヌクであり、これにより機胜を拡匵し、ツリヌ芁玠の遅延蚈算を行うこずができたす。



次に、プラグむンの䜜成者による害虫駆陀噚の構成の䟋を瀺したす。



非衚瀺のテキスト
 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は画面を2぀に分割し、2番目にVD関連のGDBを起動したす。 特に、GDBでフレヌムをナビゲヌトするずき、Vimは珟圚のフレヌムのコヌドを衚瀺し、Vimから、ホットキヌを䜿甚しおフレヌムをナビゲヌトし、ブレヌクポむントを蚭定し、プログラムを段階的に実行し、nerdtreeで倉数の倀を衚瀺できたす。 特に、F5はすべおのロヌカル倉数の倀を衚瀺し、F6はカヌ゜ルの䞋の倉数を衚瀺したす。



C ++ずそのサヌバヌ偎をナビゲヌトするためのプラグむンコヌドは公開されおおり、MITラむセンスの䞋でGitHubで利甚できたす。

https://github.com/SkidanovAlex/CtrlK

https://github.com/SkidanovAlex/py-ctrlk



デバッグプラグむンコヌドも公開されおおり、WTFPLラむセンスで利甚できたす。

https://github.com/ManOfTeflon/exterminator



All Articles