Literate Go in Spacemacs

Disclaimer

This is just a private wiki to (mostly) myself on setting up literate Go with org-babel in Spacemacs.

I might clean this up, and turn into an educational piece about the inner workings of Spacemacs, layers, packages, etc. and I might even follow best practices (once I find them).

But until that, here it is.

Layers, packages

Note: As a prerequisite, you should have org already set up.

First, add the Go layer to Spacemacs. To do this, press SPC f e d to go to your .spacemacs file.

   ;; List of configuration layers to load.
   dotspacemacs-configuration-layers
   '(
     ;; ----------------------------------------------------------------
     ;; Example of useful layers you may want to use right away.
     ;; Uncomment some layer names and press `SPC f e R' (Vim style) or
     ;; `M-m f e R' (Emacs style) to install them.
     ;; ----------------------------------------------------------------
     (go :variables go-backend 'lsp)
     ...
     )
     ...

Then, go to .emacs.d/layers/+lang/go/packages.el, and add ob-go to the packages:

(defconst go-packages
  '(
    company
    dap-mode
    (company-go :requires company)
    counsel-gtags
    eldoc
    flycheck
    (flycheck-golangci-lint :toggle (and go-use-golangci-lint
                                         (configuration-layer/package-used-p 'flycheck)))
    ggtags
    helm-gtags
    go-eldoc
    go-fill-struct
    go-gen-test
    go-guru
    go-impl
    go-mode
    go-rename
    go-tag
    godoctor
    ;; for org-babel
    (ob-go :location (recipe
                      :fetcher github
                      :repo "pope/ob-go"))
    popwin))

Alternatively, you can add this package to dotspacemacs-additional-packages '() as well, but it feels a bit more self explanatory to add it here. One of the advantages of adding it to the additional packages is to make your config more portable.

Then, there’s a third way, and that is just simply loading the ob-go.el file in your user config, e.g.:

(defun dotspacemacs/user-config ()
  (load-file "~/.dotfiles/ob-go.el")
)

Then, at the end of packages.el, you can init the package:

(defun go/init-ob-go ()
  (use-package ob-go
    :if (configuration-layer/layer-usedp 'org)))

After this, you can reload your config to install the package vith SPC f e R.

Finally, you can use it like this in your org files:

#+begin_src go
package main
import "fmt"

func main() {
    fmt.Println("This is " + "literate!")
    fmt.Println("1+1 =", 1+1)
}
#+end_src

Then, if you hit C-c C-c while being in the code block, it will execute your code, and print the results in the RESULTS block.

#+results:
: This is literate!
: 1+1 = 2

That’s it. Feel free to send an email to blog@krisztianfekete.org if you are aware of a better way of handling this.