(This information was current as of 1/11/2016. As of 2022, it's rotted pretty badly, so I suggest looking elsewhere -Ben)
In case you're interested, here's what I'm using in emacs now. I think these instructions will be at least somewhat repeatable.
1. First, use an up-to-date version of emacs (I'm on the latest version, 24.5.1); I have no idea how well this will work on older versions. I install it with macports (port install emacs-app); you can also get it from homebrew (brew install emacs --cocoa). I used to use the builds from emacsformacosx.com but they seem to have memory leaks that aren't present in the macports/homebrew builds.
2. Second, set up the emacs package manager if you haven't already. Put this in .emacs:
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives
'("marmalade" .
"http://marmalade-repo.org/packages/"))
(package-initialize)
3. Third, install the following packages with M-x package-install $PKG
: go-projectile, flycheck, gotest, company, company-go. (the emacs package manager is weird; there doesn't seem to be a non-clunky way to just declare packages as dependencies of your .emacs).
4. Fourth, add this to .emacs, adjusting as necessary for your environment:
; pkg go installation
(setq exec-path (append '("/usr/local/go/bin") exec-path))
(setenv "PATH" (concat "/usr/local/go/bin:" (getenv "PATH")))
; As-you-type error highlighting
(add-hook 'after-init-hook #'global-flycheck-mode)
(defun my-go-mode-hook ()
(setq tab-width 2 indent-tabs-mode 1)
; eldoc shows the signature of the function at point in the status bar.
(go-eldoc-setup)
(local-set-key (kbd "M-.") #'godef-jump)
(add-hook 'before-save-hook 'gofmt-before-save)
; extra keybindings from https://github.com/bbatsov/prelude/blob/master/modules/prelude-go.el
(let ((map go-mode-map))
(define-key map (kbd "C-c a") 'go-test-current-project) ;; current package, really
(define-key map (kbd "C-c m") 'go-test-current-file)
(define-key map (kbd "C-c .") 'go-test-current-test)
(define-key map (kbd "C-c b") 'go-run)))
(add-hook 'go-mode-hook 'my-go-mode-hook)
; Use projectile-test-project in place of 'compile'; assign whatever key you want.
(global-set-key [f9] 'projectile-test-project)
; "projectile" recognizes git repos (etc) as "projects" and changes settings
; as you switch between them.
(projectile-global-mode 1)
(require 'go-projectile)
(go-projectile-tools-add-path)
(setq gofmt-command (concat go-projectile-tools-path "/bin/goimports"))
; "company" is auto-completion
(require 'company)
(require 'go-mode)
(require 'company-go)
(add-hook 'go-mode-hook (lambda ()
(company-mode)
(set (make-local-variable 'company-backends) '(company-go))))
; gotest defines a better set of error regexps for go tests, but it only
; enables them when using its own functions. Add them globally for use in
(require 'compile)
(require 'gotest)
(dolist (elt go-test-compilation-error-regexp-alist-alist)
(add-to-list 'compilation-error-regexp-alist-alist elt))
(defun prepend-go-compilation-regexps ()
(dolist (elt (reverse go-test-compilation-error-regexp-alist))
(add-to-list 'compilation-error-regexp-alist elt t)))
(add-hook 'go-mode-hook 'prepend-go-compilation-regexps)
; end .emacs additions
5. Fifth, run M-x go-projectile-install-tools (one time only, although I think it would be harmless to put this in .emacs if you don't mind the extra startup time). From time to time you may need to run M-x go-projectile-update-tools.
I'm still learning all the features of this setup, but the key ones to me are:
C-c C-o
. For example, C-c C-o r
finds references to the function/variable at point.gorename
is bound to C-c p w