Vimのgdbフロントエンドプラグイン紹介

#はじめに

この記事ではVimで使えるgdbフロントエンドプラグインを幾つか紹介します。

Vim8からはtermdebugが使えるようになりましたが、[cpiger/NeoDebug](https://github.com/cpiger/NeoDebug)も使い勝手がよかったので、それぞれの使用感と補足となるWindows環境構築([後述](#windows環境構築))についてを記載します[^1]。
[^1]: Windows環境といってもgdbとtermdebug対応Vimのビルドについてなので、依存は少ないはずです。

## termdebug

cgdbやgdbのtuiモードでデバッグしてた方はtermdebugへの乗り換えがオススメです、キビキビと動作してcgdbのような画面の乱れもありません。

### Demo

C++デバッグ時のデモです、breakpointの設定と変数操作をして通常だとありえないif文を通してみます。

![termdebug_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/51728/a5ba3831-a572-b83a-4b5b-078c822b9a08.gif)

### 補足

現時点の最新版termdebug.vimですが、ハイライト設定がプラグインロード時に設定されている関係で、カラースキームを変更している場合に.vimrcへの`packadd termdebug`の場所によってはハイライト設定が初期化されてしまいます、それが困るって方は暫定としてハイライト設定をtermdebugが開始される時に変更すれば動作します。

[記事作成時のtermdebug.vim変更箇所](https://github.com/vim/vim/blob/v8.1.0581/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim#L92)

```vimscript
" termdebug.vim変更方法
func s:Highlight(init, old, new)
  let default = a:init ? 'default ' : ''
  if a:new ==# 'light' && a:old !=# 'light'
    exe "hi " . default . "debugPC term=reverse ctermbg=lightblue guibg=lightblue"
  elseif a:new ==# 'dark' && a:old !=# 'dark'
    exe "hi " . default . "debugPC term=reverse ctermbg=darkblue guibg=darkblue"
  endif
+ hi default debugBreakpoint term=reverse ctermbg=red guibg=red
endfunc

- call s:Highlight(1, '', &background)
- hi default debugBreakpoint term=reverse ctermbg=red guibg=red

func s:StartDebug(bang, ...)
  " First argument is the command to debug, second core file or process ID.
  call s:StartDebug_internal({'gdb_args': a:000, 'bang': a:bang})
+ call s:Highlight(1, '', &background)
endfunc
```

## NeoDebug

NeoDebugはtermdebugよりも高機能で、標準でショートカットキー、変数やbreakpoint、watchやスレッドなどの状態をリアルタイムに表示するウィンドウが用意され、マウスオーバーでの変数表示などに対応しています。
ソースコードを確認したところ、ある時点からのtermdebug.vimのソースコードを元に拡張しているようでした、ただし触ってみたところ細かいバグらしきものがあったため[^2]、それらの修正をした自改造版を利用しています。

[wordijp/NeoDebug](https://github.com/wordijp/NeoDebug)

こちらでは修正の他に、cgdbに近い操作感を得るためのショートカットキーも追加しています。

[^2]: コンソールウィンドウ上のファイルパスからのEnterジャンプができない場合があったり、終了処理に漏れがあったため、NeoDebug終了時や再度開始した際に以前の設定が残ってしまっていた。

### Demo

termdebugデモと同じ操作の他に、watchの設定やマウスオーバー時の変数表示などもしています。

![neodebug_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/51728/9b677a24-1a48-c420-774f-8dba5c422cfe.gif)


## Windows環境構築

### gdbのビルドについて

ビルド用にMSYS2を用意します。

pacmanでインストールするgdb 7.12.1だと動かなかったため、[公式のソースコード](https://www.gnu.org/software/gdb/download/)からビルドします。
※記事作成時はバージョン8.2

MSYS2用のパッチの必要もなく、C++のビルド環境を整えてビルドするだけで済みます。

```
msys2 ターミナル
$ # 解凍したルートでmake(README 参照) ※わりと長い
$ ./configure
$ make [-j4]
```

### termdebug対応Vimのビルドについて

[こっち使いましょう](https://qiita.com/k-takata/items/343c5ee6abbe34e85571)

~~Kaoriya版Vimでの手順です。~~

~~termdebug.vimはつい先日のvimconf2018で修正が入ったばかりなので[最新版を取ってきます](https://github.com/vim/vim/tree/master/runtime/pack/dist/opt/termdebug/plugin)。
2018/12/14時点のKaoriya版Vimはバージョン8.1.0005ですが、termdebug.vimで利用されている`prompt_setprompt()`がまだ未実装のため、最新版のVimソースを自前でビルドします。
自前でビルドするとKaoriya版Vimのパッチが未対応になりますので、それが嫌だという方は対応まで待ちましょう。~~

~~現時点の最新はバージョン8.1.0581なので、それをgit clone~~

```
> git clone --depth=1 -b v8.1.0581 https://github.com/vim/vim
```

~~自分はKaoriya版と同じMS-Windowsビルド版のGVimが欲しかったのでVisual C++ 2017でビルド、Python2、Python3、Luaをリンクさせます、Python3は3.6を指定。~~

```
VS 2017 用 x86_x64 Cross Tools コマンドプロンプト
> @rem srcフォルダでnmake(INSTALLpc.txt 参照)
> nmake -f Make_mvc.mak GUI=yes ^
    PYTHON=path\to\Python27 ^
    PYTHON3=path\to\Python36 ^
    LUA=path\to\lua-5.3
```

~~生成された`gvim.exe`を差し替え後、[runtime](https://github.com/vim/vim/tree/master/runtime)も最新へ差し替えます。~~