Go & Emacs
Some useful hints for
editing Go source code in Emacs .
Tested with GNU Emacs 23.3.2
Build errors for Go files that import package "C" won't parse
correct in Emacs' compilation buffer. To fix this, follow these
steps:
- Type: M-x customize-variable RET compilation-error-regexp-alist RET
- At the bottom of the list, click: INS
- Select: ValueMenu: Predefined symbol: nil
- Select: ValueMenu: Error specification: ("^\\([^ \t\n:][^:\n]*go\\):\\([0-9][0-9]*\\)\\[[^]]*go:[0-9][0-9]*\\]:" 1 2 nil 2)
- Select: State: Save for future sessions
Some useful functions to add to your ~/.emacs file.
(add-hook
'go-mode-hook
'(lambda ()
;; Imenu & Speedbar
(setq imenu-generic-expression
'(("type" "^type *\\([^ \t\n\r\f]*\\)" 1)
("func" "^func *\\(.*\\) {" 1)))
(imenu-add-to-menubar "Index")
;; Outline mode
;; Level 3: //. use this to devide the file into major sections
;; Level 4: // followed by at least two characters
;; Level 4: package
;; Level 4: import
;; Level 4: const
;; Level 4: var followed by at least one character
;; Level 4: type
;; Level 4: func
;; Level 5 and above: tab-indented lines with at least five characters
(make-local-variable 'outline-regexp)
(setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var[^\r\n\f]\\|type\\|\t\t*[^\r\n\f]\\{4\\}")
(outline-minor-mode 1)
(local-set-key "\M-a" 'outline-previous-visible-heading)
(local-set-key "\M-e" 'outline-next-visible-heading)
;; Menu bar
(require 'easymenu)
(defconst go-hooked-menu
'("Go tools"
["Go run buffer" go t]
["Go build buffer" go-build t]
["Go build directory" go-build-dir t]
["Go reformat buffer" go-fmt-buffer t]
"---"
["Go check buffer" go-fix-buffer t]
"---"
["Go install package" go-install-package t]
["Go test package" go-test-package t]))
(easy-menu-define
go-added-menu
(current-local-map)
"Go tools"
go-hooked-menu)
;; Other
(setq tab-width 4)
(setq show-trailing-whitespace t)
))
;; helper variable
(defvar hook-go-pkg nil
"History variable for `go-install-package' and `go-test-package'.")
;; helper function
(defun go ()
"run current buffer"
(interactive)
(compile (concat "go run \"" (buffer-file-name) "\"")))
;; helper function
(defun go-build ()
"build current buffer"
(interactive)
(compile (concat "go build \"" (buffer-file-name) "\"")))
;; helper function
(defun go-build-dir ()
"build current directory"
(interactive)
(compile "go build ."))
;; helper function
(defun go-fmt-buffer ()
"run gofmt on current buffer"
(interactive)
(if buffer-read-only
(progn
(ding)
(message "Buffer is read only"))
(let ((p (line-number-at-pos))
(filename (buffer-file-name))
(old-max-mini-window-height max-mini-window-height))
(show-all)
(if (get-buffer "*Go Reformat Errors*")
(progn
(delete-windows-on "*Go Reformat Errors*")
(kill-buffer "*Go Reformat Errors*")))
(setq max-mini-window-height 1)
(if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t))
(progn
(erase-buffer)
(insert-buffer-substring "*Go Reformat Output*")
(goto-char (point-min))
(forward-line (1- p)))
(with-current-buffer "*Go Reformat Errors*"
(progn
(goto-char (point-min))
(while (re-search-forward "<standard input>" nil t)
(replace-match filename))
(goto-char (point-min))
(compilation-mode))))
(setq max-mini-window-height old-max-mini-window-height)
(delete-windows-on "*Go Reformat Output*")
(kill-buffer "*Go Reformat Output*"))))
;; helper function
(defun go-fix-buffer ()
"run gofix on current buffer"
(interactive)
(show-all)
(shell-command-on-region (point-min) (point-max) "go tool fix -diff"))
;; helper function
(defun go-install-package ()
"install package"
(interactive)
(let
((pkg (read-from-minibuffer "Install package: " nil nil nil 'hook-go-pkg)))
(if (not (string= pkg ""))
(compile (concat "go install \"" pkg "\"")))))
;; helper function
(defun go-test-package ()
"test package"
(interactive)
(let
((pkg (read-from-minibuffer "Test package: " nil nil nil 'hook-go-pkg)))
(if (not (string= pkg ""))
(compile (concat "go test \"" pkg "\"")))))
To enable Go in the Speedbar:
- Go to: Options → Customize Emacs → Specific Option...
- Choose: speedbar-supported-extension-expressions
- Add extension: .go
- Click on: State → Save for Future Sessions
To start the Speedbar:
Alt-X speedbar Enter
The following makes outline mode easy to use generally, not just when
editing Go. You may have to install outline-magic separately.
;; Show/hide parts by repeated pressing f10
(add-hook 'outline-minor-mode-hook
(lambda ()
(require 'outline-magic)
(define-key outline-minor-mode-map [(f10)] 'outline-cycle)))