You will notice how much I use “me” and “I” on this post. This because your emacs configuration is extremely personal. You are creating a “dream editor”, and the options that I pick might not be of your preference. Feel free to make it your own!
Back on topic. I started writing Go in late 2015. At first, I used Sublime Text, which I like a lot, but I was a little jealous of those using vim-go and I figured there would be a way to make myself at home writing Go in Emacs. This is how the adventure began.
The first thing I had to do was find a major mode for Go on emacs. It didn’t take me long to find go-mode. Installation is not hard, as it’s available as a package in the MELPA repository. A simple M-x package-install go-mode
sufficed. Configuring it was a bit harder.
.emacs
configuration for Go.</p>
;;Load Go-specific language syntax
;;For gocode use https://github.com/mdempsky/gocode
;;Custom Compile Command
(defun go-mode-setup ()
(linum-mode 1)
(go-eldoc-setup)
(setq gofmt-command "goimports")
(add-hook 'before-save-hook 'gofmt-before-save)
(local-set-key (kbd "M-.") 'godef-jump)
(setq compile-command "echo Building... && go build -v && echo Testing... && go test -v && echo Linter... && golint")
(setq compilation-read-command nil)
;; (define-key (current-local-map) "\C-c\C-c" 'compile)
(local-set-key (kbd "M-,") 'compile)
(add-hook 'go-mode-hook 'go-mode-setup)
;;Load auto-complete
(ac-config-default)
(require 'auto-complete-config)
(require 'go-autocomplete)
;;Go rename
(require 'go-rename)
;;Configure golint
(add-to-list 'load-path (concat (getenv "GOPATH") "/src/github.com/golang/lint/misc/emacs"))
(require 'golint)
;;Smaller compilation buffer
(setq compilation-window-height 14)
(defun my-compilation-hook ()
(when (not (get-buffer-window "*compilation*"))
(save-selected-window
(save-excursion
(let* ((w (split-window-vertically))
(h (window-height w)))
(select-window w)
(switch-to-buffer "*compilation*")
(shrink-window (- h compilation-window-height)))))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)
;;Other Key bindings
(global-set-key (kbd "C-c C-c") 'comment-or-uncomment-region)
;;Compilation autoscroll
(setq compilation-scroll-output t)
That’s a lot! Yeah, I know, but before you freak out, I’ll give you a run down of what each block is for (although the comments should help a lot).
;;Load Go-specific language syntax
;;For gocode use https://github.com/mdempsky/gocode
;;Goimports
(defun go-mode-setup ()
(go-eldoc-setup)
(add-hook 'before-save-hook 'gofmt-before-save))
(setq gofmt-command "goimports")
(add-hook 'before-save-hook 'gofmt-before-save))
(add-hook 'go-mode-hook 'go-mode-setup)
This block enables go-mode
and makes sure it runs gofmt
before saving. gofmt
allows our code to be nice and tidy and to let go-mode
take care of importing the required packages. Nifty, huh? Makes coding nicer.
Some extra elements to make our lives easier. Not necessary, but nice to have.
(defun go-mode-setup ()
;; (setq compile-command "go build -v && go test -v && go vet && golint && errcheck")
(linum-mode 1)
(setq compile-command "echo Building... && go build -v && echo Testing... && go test -v && echo Linter... && golint")
(setq compilation-read-command nil)
;; (define-key (current-local-map) "\C-c\C-c" 'compile)
(local-set-key (kbd "M-,") 'compile)
(add-hook 'go-mode-hook 'go-mode-setup)
This is a good one. Here I’m configuring M-,
(Escape key + comma) to run go build
, go test
, and golint
. Extremely simple way make sure our code compiles.
;;Load auto-complete
(ac-config-default)
(require 'auto-complete-config)
(require 'go-autocomplete)
;;Go rename
(require 'go-rename)
;;Configure golint
(add-to-list 'load-path (concat (getenv "GOPATH") "/src/github.com/golang/lint/misc/emacs"))
(require 'golint)
Sets up go-autocomplete
and go-rename
. go-rename
only is used if you want to do project-level renames. Just between us, I barely use it.
The last block configures the path of the linter. Remember, Emacs is smart, but not that smart.
;;Smaller compilation buffer
(setq compilation-window-height 14)
(defun my-compilation-hook ()
(when (not (get-buffer-window "*compilation*"))
(save-selected-window
(save-excursion
(let* ((w (split-window-vertically))
(h (window-height w)))
(select-window w)
(switch-to-buffer "*compilation*")
(shrink-window (- h compilation-window-height)))))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)
All of this to make the compilation buffer smaller than a default buffer.
;;Other Key bindings
(global-set-key (kbd "C-c C-c") 'comment-or-uncomment-region)
How about a simple command to comment out big blocks of code? C-c C-c
. Also, compilation-scroll-output
simply scrolls the compilation buffer all the way to the end.
This is my current set up. It works really well for my needs, but it might not be yours. Something I’ll work on is to integrate delve
(golang debugger) into the editor, but I suppose I’m quite old school.
I also have Magit integrated into my workflow, but that’s a topic for a different episode. To be honest, I don’t miss anything from Sublime (or Atom or MS Code), plus it already makes use of my favorite editor. A simple .emacs
file gives me all the customization that I need and I know I always have MY set up everywhere.