Spacemacs + go layer + LSP + DAP + Delve で快適Go!

# EmacsでGo書いてデバッグする

かなり前から`Emacs` + (C/C++) + `gdb` = IDEとしても使える`Emacs`ですのでGo言語でも同じようにできます。


# Emacs

お好きなディストリビューションをお使い下さい。

このエントリーでは`Spacemacs`を前提に進めます。

- [Spacemacs](https://develop.spacemacs.org/layers/+lang/go/README.html "README.html")
	- Code repository: [syl20bnr/spacemacs](https://github.com/syl20bnr/spacemacs "syl20bnr/spacemacs")


# Go言語

`go layer`を使います。

- [Go layer](https://develop.spacemacs.org/layers/+lang/go/README.html "README.html")
    - 利用しているpackageを確認: [layers/+lang/go/package.el](https://github.com/syl20bnr/spacemacs/blob/develop/layers/%2Blang/go/packages.el "go/package.el")


# Language Server Protocol (LSP)

もちろんLSPも有効にしましょう。

`lsp layer`を使います。

- [LSP Layer](https://develop.spacemacs.org/layers/+tools/lsp/README.html "README.html")
	- 利用しているpackageを確認: [layers/+tools/lsp/package.el](https://github.com/syl20bnr/spacemacs/blob/develop/layers/%2Btools/lsp/packages.el "lsp/package.el")


`lsp-mode`がEmacs用のクライアントです。

- [LSP Mode](https://emacs-lsp.github.io/lsp-mode/)
	- Code repository: [emacs-lsp/lsp-mode](https://github.com/emacs-lsp/lsp-mode "lsp-mode")


# Debug Adapter Protocol (DAP)

今回の目的達成にはこの機能を`Spacemacs`に追加します。

`lsp-mode`も勿論DAPをサポートしています。

- [DAP Layer](https://github.com/syl20bnr/spacemacs/blob/develop/layers/%2Btools/dap/packages.el "dap/package.el")
	- DAPとは: [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/ "Debug Adapter Protocol")


対応言語が増えていますので一度確認されることをおすすめします。

- [Debug Adapter Protocol Server Implementations](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/ "Debug Adapters")


# Delve

Go言語用のデバッガです。

C/C++でいう`gdb`に相当します。 (CLIも同じ!!)

- [Delve](https://github.com/go-delve/delve "Delve")
	- Installation: [Installation](https://github.com/go-delve/delve/tree/master/Documentation/installation "Installation")


# init.el

Layerの設定例です。


```elisp
(setq-default dotspacemacs-configuration-layers
              '(
                (lsp :variables
                     lsp-navigation 'peek)
                (go :variables
                    go-backend 'lsp
                    )
                dap
                ))
```


# さっそくEmacs IDEでデバッグ

の前にもう少し設定が必要です。

dap + delve がどのようにデバッグ対象を起動するかを登録します。


```elisp
(dap-register-debug-template "dap sample config"
                             (list :type "go"
                                   :request "launch"
                                   :name "sample launch"
                                   :mode "debug"
                                   :program: "~/src/github.com/dap-sample"
                                   :buildFlags "-tags sample_tag"
                                   :args '()
                                   :env '() ; '(("DEV" . "1"))
                                   :envFile ".envrc"
                                   )
                             )
```

`eval`するとこうなります。

```org
| dap sample config                                 | :type | go | :request | launch | :name | sample launch                    | :mode | debug  | :program: | ~/src/github.com/dap-sample | :buildFlags | -tags sample_tag | :args | nil | :env     | nil | :envFile | .envrc |
| Go Connect Remote dlv Configuration               | :type | go | :request | launch | :name | Connect to Remote dlv            | :mode | remote | :program  | nil                         | :args       | nil              | :env  | nil | :envFile | nil |          |        |
| Go Attach Executable Configuration                | :type | go | :request | attach | :name | Attach to Executable             | :mode | local  | :program  | nil                         | :args       | nil              | :env  | nil | :envFile | nil |          |        |
| Go Launch Executable Configuration                | :type | go | :request | launch | :name | Launch Executable                | :mode | exec   | :program  | nil                         | :args       | nil              | :env  | nil | :envFile | nil |          |        |
| Go Launch Unoptimized Debug Package Configuration | :type | go | :request | launch | :name | Launch Unoptimized Debug Package | :mode | debug  | :program  | nil                         | :buildFlags | -gcflags '-N -l' | :args | nil | :env     | nil | :envFile | nil    |
| Go Launch Debug Package Configuration             | :type | go | :request | launch | :name | Launch Debug Package             | :mode | debug  | :program  | nil                         | :buildFlags | nil              | :args | nil | :env     | nil | :envFile | nil    |
| Go Launch File Configuration                      | :type | go | :request | launch | :name | Launch File                      | :mode | auto   | :program  | nil                         | :buildFlags | nil              | :args | nil | :env     | nil | :envFile | nil    |
```

"dap sample config" 以外はデフォルト用意されているものです。

登録したら`SPC d d d`:`(dap-debug)`で起動します。

登録した内容の修正は`SPC d d e`:`(dap-debug-edit-template)`です。

修正したら忘れずに`(eval-buffer)`してください。


**参考:**

- [dap-modeでEmacs上でgoをデバッグする - PartyIX](https://h3poteto.hatenablog.com/entry/2020/09/24/211553 "dap-modeでEmacs上でgoをデバッグする - PartyIX")


# launch.json

`(dap-register-debug-template)`の内容はVS CodeでGo + Delveを使う際に参照される`launch.json`と同じ内容になります。


```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "MyGet",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "/home/h3poteto/src/github.com/h3poteto/package-name",
            "env": {},
            "args": "get"
        }
    ]
}
```

**参考:**

- [LLDB VSCode - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=lanza.lldb-vscode "LLDB VSCode - Visual Studio Marketplace" )

- [Goのデバッガ(Delve)のいろいろな起動のしかた(引数を渡して起動、起動中のプロセスにアタッチして起動 etc...) - My External S...](https://budougumi0617.github.io/2018/04/08/debug-by-delve/ "Goのデバッガ(Delve)のいろいろな起動のしかた(引数を渡して起動、起動中のプロセスにアタッチして起動 etc...) - My External S..." )

- [Visual Studio CodeでGo言語のデバッグ環境を整える - Qiita](https://qiita.com/momotaro98/items/7fbcad57a9d8488fe999 "Visual Studio CodeでGo言語のデバッグ環境を整える - Qiita" )


# さいごに

中々うまくいかなかったこの組み合わせのデバッグですが、できるようになると作業が捗りますので是非トライしてみてください。

Let's enjoy ! Happy Hacking !


### 参考リンク

- [好みのエディタに快適な開発環境を提供するLSP - Qiita](https://qiita.com/Ladicle/items/e666e3fb9fae9d807969 "好みのエディタに快適な開発環境を提供するLSP - Qiita" )