The Perfect Setup to hack on Guix is basically the perfect setup used for Guile hacking (see Using Guile in Emacs in Guile Reference Manual). First, you need more than an editor, you need Emacs, empowered by the wonderful Geiser. To set that up, run:
guix install emacs guile emacs-geiser emacs-geiser-guile
Geiser allows for interactive and incremental development from within Emacs: code compilation and evaluation from within buffers, access to on-line documentation (docstrings), context-sensitive completion, M-. to jump to an object definition, a REPL to try out your code, and more (see Introduction in Geiser User Manual). If you allow Emacs to load the .dir-locals.el file at the root of the project checkout, it will cause Geiser to automatically add the local Guix sources to the Guile load path.
To actually edit the code, Emacs already has a neat Scheme mode. But in addition to that, you must not miss Paredit. It provides facilities to directly operate on the syntax tree, such as raising an s-expression or wrapping it, swallowing or rejecting the following s-expression, etc.
We also provide templates for common git commit messages and package definitions in the etc/snippets directory. These templates can be used to expand short trigger strings to interactive text snippets. If you use YASnippet, you may want to add the etc/snippets/yas snippets directory to the yas-snippet-dirs variable. If you use Tempel, you may want to add the etc/snippets/tempel/* path to the tempel-path variable in Emacs.
;; Assuming the Guix checkout is in ~/src/guix. ;; Yasnippet configuration (with-eval-after-load 'yasnippet (add-to-list 'yas-snippet-dirs "~/src/guix/etc/snippets/yas")) ;; Tempel configuration (with-eval-after-load 'tempel ;; Ensure tempel-path is a list -- it may also be a string. (unless (listp 'tempel-path) (setq tempel-path (list tempel-path))) (add-to-list 'tempel-path "~/src/guix/etc/snippets/tempel/*"))
The commit message snippets depend on Magit to
display staged files. When editing a commit message type
followed by TAB to insert a commit message template for adding a
update followed by TAB to insert a template
for updating a package; type
https followed by TAB to
insert a template for changing the home page URI of a package to HTTPS.
The main snippet for
scheme-mode is triggered by typing
package... followed by TAB. This snippet also inserts the
origin..., which can be expanded further. The
origin snippet in turn may insert other trigger strings ending on
..., which also can be expanded further.
We additionally provide insertion and automatic update of a copyright in etc/copyright.el. You may want to set your full name, mail, and load a file.
(setq user-full-name "Alice Doe") (setq user-mail-address "email@example.com") ;; Assuming the Guix checkout is in ~/src/guix. (load-file "~/src/guix/etc/copyright.el")
To insert a copyright at the current line invoke
To update a copyright you need to specify a
(setq copyright-names-regexp (format "%s <%s>" user-full-name user-mail-address))
You can check if your copyright is up to date by evaluating
copyright-update. If you want to do it automatically after each buffer
save then add
(add-hook 'after-save-hook 'copyright-update) in
Emacs has a nice minor mode called
bug-reference, which, when
combined with ‘emacs-debbugs’ (the Emacs package), can be used to
open links such as ‘<https://bugs.gnu.org/58697>’ or
‘<https://issues.guix.gnu.org/58697>’ as bug report buffers. From
there you can easily consult the email thread via the Gnus interface,
reply or modify the bug status, all without leaving the comfort of
Emacs! Below is a sample configuration to add to your ~/.emacs
;;; Bug references. (require 'bug-reference) (add-hook 'prog-mode-hook #'bug-reference-prog-mode) (add-hook 'gnus-mode-hook #'bug-reference-mode) (add-hook 'erc-mode-hook #'bug-reference-mode) (add-hook 'gnus-summary-mode-hook #'bug-reference-mode) (add-hook 'gnus-article-mode-hook #'bug-reference-mode) ;;; This extends the default expression (the top-most, first expression ;;; provided to 'or') to also match URLs such as ;;; <https://issues.guix.gnu.org/58697> or <https://bugs.gnu.org/58697>. ;;; It is also extended to detect "Fixes: #NNNNN" git trailers. (setq bug-reference-bug-regexp (rx (group (or (seq word-boundary (or (seq (char "Bb") "ug" (zero-or-one " ") (zero-or-one "#")) (seq (char "Pp") "atch" (zero-or-one " ") "#") (seq (char "Ff") "ixes" (zero-or-one ":") (zero-or-one " ") "#") (seq "RFE" (zero-or-one " ") "#") (seq "PR " (one-or-more (char "a-z+-")) "/")) (group (one-or-more (char "0-9")) (zero-or-one (seq "#" (one-or-more (char "0-9")))))) (seq "<https://bugs.gnu.org/" (group-n 2 (one-or-more (char "0-9"))) ">"))))) (setq bug-reference-url-format "https://issues.guix.gnu.org/%s") (require 'debbugs) (require 'debbugs-browse) (add-hook 'bug-reference-mode-hook #'debbugs-browse-mode) (add-hook 'bug-reference-prog-mode-hook #'debbugs-browse-mode) ;; The following allows Emacs Debbugs user to open the issue directly within ;; Emacs. (setq debbugs-browse-url-regexp (rx line-start "http" (zero-or-one "s") "://" (or "debbugs" "issues.guix" "bugs") ".gnu.org" (one-or-more "/") (group (zero-or-one "cgi/bugreport.cgi?bug=")) (group-n 3 (one-or-more digit)) line-end))