shtaxxx日記

コンピュータアーキテクチャについて研究している研究者の日記や技術紹介

emacsでGo言語(golang)の補完と定義ジャンプをするにはgocodeとgodefを使う

emacs (24.3) 上でgolang (1.3.3) の補完とコードジャンプを利用する方法をまとめました.
ターミナルのシェルにはbashを使っていますが,他のシェルでも変わらないはず.

PATH各種を設定する

まず,emacs上でexec-pathが$GOPATH (Goコマンドでインストールしたバイナリがあるディレクトリのパス) を含むことを確認する.*scratch*で

exec-path

とタイプしてからC-j (Ctrl + j) とすれば確認できる.

シェルからemacsを起動すれば自動的に$PATHをexec-pathとして取り込むので,予めシェルで$PATHが$GOPATHを含むように設定しておけばOK.

Macなどでアプリケーションのアイコンから直接emacsを起動してしまうとexec-pathに$PATHが取り込まれないので注意.
また,OSX Yosemite上で起動したemacs 24.4では,うまくexec-pathに$PATHを取り込めていない模様.
かたついさんの記事の通りに,exec-path-from-shell を使いましょう.

package.el等でemacsの環境にexec-path-from-shellをインストールし,inits/30-exec-path-from-shell.elを

(exec-path-from-shell-initialize)

と設定.

あとは,シェルの設定をする.bashなら.bashrcに

if [ -x "`which go`" ]; then
    export GOROOT=`go env GOROOT`
    export GOPATH=~/.go
    export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
fi

としておけば良いし,tcshなら.cshrcに

if (-x "`which go`") then
    set GOROOT=`go env GOROOT`
    set GOPATH=~/.go
    set path= ( \
        $GOROOT/bin \
        $GOPATH/bin \
        $path \
        )
endif

としておけば,ターミナルからemacsを起動した際に$PATHがexec-pathに取り込まれる.

もし,$GOPATHの実体となるディレクトリがなければ,作成する.

mkdir -p $GOPATH

gocode, godef, goimportsをインストールする

hgやgitが必要になるかもしれないので,予めインストールしておく.
MacでHomebrewを使っているなら

brew install git hg

Ubuntuでapt-getなら

sudo apt-get install hg git

godefをインストールする.

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

gocodeをインストールする.

go get -u github.com/nsf/gocode

goimportsをインストールする.

go get code.google.com/p/go.tools/cmd/goimports

emacs lispの設定

emacsに auto-complete, go-mode, go-autocomplete のパッケージを追加する.
僕はemacs24系でinit-loader.el+package.elを使ってパッケージ管理をしているので,inits/20-package.el がこんな感じになっている.パッケージがなければ自動的にダウンロードし,インストールされる.
init-loader.el+package.elの詳しい使い方はかたついさんの記事を参照しましょう.

(require 'package)
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))
(package-initialize)

(require 'cl)
(defvar installing-package-list
  '(
    auto-complete
    exec-path-from-shell
    gtags
    flymake
    flymake-cursor
    markdown-mode
    markdown-mode+
    python-mode
    epc
    python-environment
    jedi
    jinja2-mode
    go-mode
    go-autocomplete
    scala-mode2
    haskell-mode
    ))

(let ((not-installed (loop for x in installing-package-list
                           when (not (package-installed-p x))
                           collect x)))
  (when not-installed
    (package-refresh-contents)
    (dolist (pkg not-installed)
      (package-install pkg))))

auto-completeの設定をする.inits/50-auto-complete.elはこんな感じ.

(require 'auto-complete)
;(add-to-list 'ac-dictionary-directories "~/.emacs.d/elpa/auto-complete-20130724.1750/dict")
(require 'auto-complete-config)
(ac-config-default)
(global-auto-complete-mode t)

最後に,inits/70-go-mode.elを用意し,go-modeと補完機能を設定する.

;; go-mode
;; In advance, install godef, gocode, and goimports in $GOPATH.
;;   go get code.google.com/p/rog-go/exp/cmd/godef
;;   go get -u github.com/nsf/gocode
;;   go get code.google.com/p/go.tools/cmd/goimports
;; exec-path should include a path to .go/bin.
;; So DO NOT launch an emacs from App icon, DO launch an emacs from terminal (shell).

(autoload 'go-mode "go-mode" nil t)
(eval-after-load "go-mode" '(progn (require 'go-autocomplete)))
(add-hook 'go-mode-hook
          '(lambda()
             (setq gofmt-command "goimports")
             (add-hook 'before-save-hook 'gofmt-before-save)
             (setq c-basic-offset 4)
             (setq indent-tabs-mode t)
             (local-set-key (kbd "M-.") 'godef-jump)
             (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)
             (local-set-key (kbd "C-c i") 'go-goto-imports)
             (local-set-key (kbd "C-c d") 'godoc)
             (define-key ac-mode-map (kbd "M-TAB") 'auto-complete)))

go-modeの設定の仕方はこちらを参照しました.ありがとうございました.

完成

こんな感じで補完ができるようになったはず.
M-Tabで補完メニューが出て,M-.でカーソルのキーワードの定義にジャンプできる.便利.