EmacsでのGo言語編集環境

最近Go言語を始めた。MacにGoの実行環境を入れ、Emacsで編集するところまで、一通りまとめておく。

Goの導入 (for OS X)

いろいろ方法があるようだけど、僕はカジュアルに brew install go で済ませた。

GOPATH 環境変数は最初プロジェクト毎に設定して使おうかと思っていたんだけど、 後述するgocodeやgo-flymakeといったツールを使う場合、手元のGOPATHは1つにしてしまったほうが便利なので、

export GOPATH=$HOME/dev/go-workspace

というのをshellの設定に定義して、手元ではこの共通のPATHを使うようにした。 これは問題がでたらまた考える。

PATHを通す

homebrewで入れたツールをEmacsから使うためには、 homebrewのbinディレクトリを exec-path に追加する必要がある。

(add-to-list 'exec-path (expand-file-name "~/homebrew/bin"))

また、 go get で入れたツール郡もEmacsから使いたいので、 $GOPATH/bin も加えておく。

(add-to-list 'exec-path (expand-file-name "~/dev/go-workspace/bin"))

go-mode

さて、まず最初に導入するのが、go-mode.el。これはGo言語のためのメジャーモードで、 Goのレポジトリの misc/emacs 以下に同封されている。

でも、 el-get-list-packages してみたらgo-modeのレシピがすでにあったので、僕はそれをそのまま使ってel-getで入れた。

実際はautoloadのelispも別途あるのでそっちも使ったほうが良いとおもうのだけど、 el-getでそれをやるためにはrepositoryを全部とってくるようなrecipeに変更する必要がある(と思う)のであきらめた。

色分け、インデント

go-modeを導入すると、他の言語のメジャーモードと同じように、Go言語のsyntaxがハイライトされて読みやすくなる。 また、Go言語のsyntaxを理解したソースコードのインデント、コメントアウトなんかが行えるようになる。

go-mode

ドキュメントを引く

M-x godoc とするとGoのドキュメントを引く機能もある。

godoc

anything-read-string-mode している人なら、 package一覧をanythingインタフェースで絞りこんでドキュメントをさくさく引けて非常に便利である。

go-mode with anything godoc completion

整形

Goにはソースコードをよしなに整形してくれる go fmt というコマンドがあるみたいだけど、 go-mode はそれをEmacsから使う方法も提供してくれている(M-x gofmt)。

また、

(add-hook 'before-save-hook 'gofmt-before-save)

しておくと、ファイル保存時に自動でgofmtしてくれるようにもできるとのこと。[1]

定義ジャンプ

この機能を利用するにはあらかじめ、 godef コマンドのインストールが必要。

インストールするには

$ go get code.google.com/p/rog-go/exp/cmd/godef

すれば良い。[2]

あとは、 M-x godef-jump とすると関数などの定義位置に飛ぶことができるようになる。デフォルトでこれがあるのは大分便利だと思う。

(add-hook 'go-mode-hook (lambda ()
                          (local-set-key (kbd "M-.") 'godef-jump)))

とかすればetagsみたいな感じで使えるよ、とのこと。

あと、 godef-describe で引数や、戻り値などの定義を確認できる機能もあるのだけど、 これは後述のgocodeがあるからあんまり出番はなさそう。

import周りの機能

コードを書いていて新しいpackageに依存したくなったときに、わざわざコードの冒頭部まで移動してimportに1行追加、とかめんどくさい! というような時には go-import-add が使える。これを使うとコード上のどの位置にいても、新しいパッケージをimportリストに加えることができる。

また、Goはimportしていても実際にそれをコード内で使っていないとエラーになってしまうが、 そういう時には go-remove-unused-imports を使うと使用していないpackageたちをimportから一括で外してくれて便利だ。

Go Playground連携

Goには Go Playground というコードスニペットを共有できるサイトがあるが、go-modeはそこと連携する機能もある。

バッファ全体を Go Playground に投げる go-play-buffer 、 選択した部分だけ投げる go-play-region などの関数がそれだ。 実行すると投稿したURLを表示すると同時にそれをクリップボードにも入れてくれるようだ。 書いているコードを手軽に共有できるのでなかなか便利かもしれない。

gocode

Goのコードを auto-complete.el を使用して良い感じに補完することができるのが、 gocode だ。

gocode

インストール

  1. go get でgocodeをインストールする
    $ go get -u github.com/nsf/gocode
  2. auto-complete.el をインストールする
  3. $GOPATH/src/github.com/nsf/gocode/emacsload-path を通す。 もしくはそこにある go-autocomplete.elload-path の通っているところにコピーする。
  4. go-autocomplete.el をロードする
    (require 'go-autocomplete)
    (require 'auto-complete-config)

go-flymake

goflymake はgo-modeでflymake(ファイル保存する度に自動でsyntax checkをしてくれる)できるようにするためのツールだ。

インストール

  1. go get -u github.com/dougm/goflymake
  2. $GOPATH/src/github.com/dougm/goflymakeload-path を通す
  3. (require 'go-flymake) する

これだけで自動的にflymakeされるようになる。

また、 flycheckを使用している人はおなじレポジトリに go-flycheck.el があるので、 そちらを利用すると良いのかな。

まとめ

Goは新しい言語なのにも関わらず、Emacsでの開発環境がこんなにも整っていることにものすごく驚いた。 PerlやObjective-Cもこんな感じで開発できたらいいのになぁ、とまで思ってしまう。

言語自体の特徴や性能ももちろん重要だけど、このような周辺の環境整備も開発者を囲ううえで重要だと改めて感じた。