Guix: Guile Load Path

The problem

Guile needs to have its load path updated in order to work with source files. The Guix Manual recomments using a Geiser feature to update Guile’s load path by evaluating code like the snippet below in Emacs (e.g., in the *Scratch* buffer):

;; Assuming the Guix checkout is in ~/src/guix.
(with-eval-after-load 'geiser-guile
  (add-to-list 'geiser-guile-load-path "~/src/guix"))

We can achieve the same result by customizing our project’s .dir-locals.el file as described in the Emacs manual to set geiser-guile-load-path to the directory with the source files.

The rest of the post relies on this blog entry by Rednosehacker. A better approach is to automate this step. We can achieve this by using a couple of packages:

direnv is an extension for shells, including Bash. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory. We want to use it to update the variable GUILE_LOAD_PATH with the directory of our project.

emacs-envrc is a GNU Emacs library which uses the direnv tool to determine per-directory/project environment variables and then set those environment variables on a per-buffer basis.

The combination of these two packages is powerful: we use direnv to set up the mechanism for updating Guile’s load path, and emacs-envrc to make sure the new settings are applied and correct as buffers are being visited:

Setup

We install the requisite packages:

guix install direnv emacs-envrc

Next, add this configuration bit to the end of .bashrc:

eval "$(direnv hook bash)"

and this other bit to the very end of our Emacs dot file:

(use-package envrc
  :hook (after-init . envrc-global-mode))

to enable emacs-envrc globally.

Finally, we add an .envrc file to each of our projects:

eval $(guix shell guile --search-paths)
export GUILE_LOAD_PATH="$PWD:$GUILE_LOAD_PATH"

The first line makes sure that we have the right path to the guile executable; the second line adds the current directory to the GUILE_LOAD_PATH.