[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Draft new Guix Cookbook section on Emacs
From: |
Mekeor Melire |
Subject: |
Draft new Guix Cookbook section on Emacs |
Date: |
Sun, 04 Jun 2023 23:32:44 +0000 |
Hello :)
I'd like to contribute to the Guix Cookbook.
The Cookbook is written in Texinfo format but as I'm not fluent in
it, I decided I'd first draft my contribution in Org-Mode which
I'd later export as Texinfo and adapt appropriately. I'm sorry
that this also means that the hereby submitted draft does not come
as a Git patch for now.
Find below a first draft of a new chapter entitled "Emacs",
including two subchapters, "Beginners Guide to the Perfect Setup"
and "Mu4e".
Regarding the Perfect Setup, I'm convinced that it makes sense to
have a more beginner-friendly tutorial supplementing the
instructions which are already present in the Guix manual. It's
meant to have more background information and more, non-essential
configuration tips, as well as details on usage, including
keybindings.
Regarding emails, in the long-term, I'd also like to contribute a
new chapter on how to use the mailing-lists, elaborating on how to
get local maildir copies of the mailing-lists with tools like
isync/mbsync or public-inbox etc. But that's for the future!
I'm looking forward to your feedback.
Kindly
Mekeor
* Emacs
** Beginners Guide to the Perfect Setup
# Why this tutorial?
The GNU Guix manual includes contains a chapter on "The Perfect Setup" of Emacs
for hacking on Guix. It is the primary and main resource on this topic. In
contrast, this tutorial is just a supplement, dedicated towards beginners as it
offers more background information, details on usage as well as non-essential,
optional configuration.
# What is Emacs and why is it well suited for Guix?
GNU Emacs is a text editor and, at its core, an interpreter of its own Lisp
dialect, Emacs-Lisp. It's well suited for hacking on Guix (and Guix-related)
code because of its advanced Lisp editing features and since as part of the GNU
project, it's free software, just like GNU Guix.
# Do you have to use Emacs for hacking on Guix?
Using Emacs is not a precondition for hacking on Guix(-related) code. For
example, there's at least one Guix maintainer who rather uses Vim. But if
you're interested in Emacs or already using it, keep on reading.
# Installation
To install Emacs into your Guix user profile, run:
#+begin_src sh
guix install emacs
#+end_src
*** Geiser
# What is Geiser?
Geiser is a package for GNU Emacs that helps with editing code written in the
Scheme programming language. In particular, it supports the GNU Guile Scheme
interpreter on which GNU Guix is heavily based.
# Why Geiser?
Using Geiser is recommended not only because it enhances your Scheme editing
experience with features like automatic documentation, but also it works with
the ~guix-devel-mode~ described later on.
# Installation
To install Geiser into your Guix user profile, run:
#+begin_src sh
guix install emacs-geiser emacs-geiser-guile
#+end_src
Afterwards, (re)start Emacs in order to make sure that Geiser finds its way
into Emacs' ~load-path~.
**** Load Geiser
To load Geiser by default add this to your Emacs initialization file:
#+begin_src elisp
(require 'geiser)
#+end_src
Note that this not only loads Geiser but – through Geiser's autoloads – also
hooks Geiser minor-mode onto ~scheme-mode~. I.e. Geiser will start when you
open any Scheme file.
**** Geiser Guile Load Path
If you maintain a local clone of the Guix source code repository, it already
contains a =.dir-locals.el= file which ensures that the path of your local
clone is added to ~geiser-guile-load-path~ whenever you open a Scheme file in
there. But nevertheless, it makes sense to add the path to your local Guix
repository to ~geiser-guile-load-path~ in your Emacs initialization file so
that it's set correctly in other directories as well.
Make sure that the compiled files in your local Guix repository are up-to-date.
I.e. whenever your local working directory of the repository changes (for
example, after running ~git pull~), rebuild Guix as described in the Guix
manual. Otherwise, Guile would auto-compile all Guix sources which leads to
misconfiguration[fn:1] and likely hits Geiser's timeout. Consider having two
Git worktree of the Guix repository, keeping one always compiled.
If you have other Guix-related source code directories on your machine (and you
want to load Guile modules from there), you need to put those in the
~geiser-guile-load-path~ variable. (Geiser will then add those paths to Guile's
~%load-path~ and ~%load-compiled-path~ variables.)
#+begin_src elisp
(setq geiser-guile-load-path
(list
"~/src/guix"
"~/src/some/channel"))
#+end_src
**** REPL Configuration
You may find handy to make Geiser automatically start a REPL
(read-eval-print-loop) in the background when a Scheme file is opened:
#+begin_src elisp
(setq geiser-mode-start-repl-p t)
#+end_src
If you want to speed up Geiser, let it open a single REPL per project (instead
of per file) and forgo version compatibility checks:
#+begin_src elisp
(setq geiser-repl-per-project-p t)
(setq geiser-repl-skip-version-check-p nil)
#+end_src
**** Using Multiple Schemes
If you not only have =emacs-geiser-guile= installed, but also Geiser backends
for other Scheme implementations, adjust the ~geiser-implementations-alist~
variable. For example:
#+begin_src elisp
(setq geiser-implementations-alist
'(
((regexp "/minlog/") chez)
((regexp "\\.scm$") guile)))
#+end_src
*** Emacs-Guix
=emacs-guix= is a package for interacting with Guix through Emacs. It has been
originally developed by Alex Kost and is now maintained within the Guix
project. It not only offers an interactive interface to Guix features, but also
ships some modes for viewing and editing Guix-related files, which are covered
in the following.
To install Emacs-Guix into your Guix user profile, run:
#+begin_src sh
guix install emacs-guix
#+end_src
**** Guix Development Mode
=guix-devel-mode= offers Guix-specific syntax highlighting, linting and
loading, by utilizing Geiser. To enable it in all Scheme buffers, put this in
your Emacs initialization file:
#+begin_src elisp
(require 'guix-devel)
(require 'scheme)
(add-hook 'scheme-mode-hook #'guix-devel-mode)
#+end_src
But if you occasionally open Scheme files in Emacs that are unrelated to Guix,
you might instead enable ~guix-devel-mode~ conditionally, for example like this:
#+begin_src elisp
(require 'guix-devel)
(require 'scheme)
(defun maybe-turn-on-guix-devel-mode ()
(when
(string-match-p "guix" (buffer-file-name))
(guix-devel-mode)))
(add-hook 'scheme-mode-hook #'maybe-turn-on-guix-devel-mode)
#+end_src
**** Other Modes
Emacs-Guix ships with a many more mode that are useful when hacking on Guix,
including ~guix-build-log-mode~, ~guix-derivation-mode~ and
~guix-prettify-mode~. Check out Emacs-Guix' Info manual for more information.
# TODO: perhaps add more usage instructions about these modes here.
*** Snippets
There are many Emacs packages for managing and inserting code snippets. The
Guix repository includes snippets for two of them: Tempel and Yasnippet. Both
are distributed through the GNU ELPA (Emacs Lisp Package Archive).
Pick and use just one of them. There's no advantage of setting up both snippet
packages since the Guix repository offers almost equal snippets for them. (As
of writing, there are slightly more snippets for Tempel.) Generally speaking,
the biggest difference between them is that Tempel uses ~lisp-data-mode~ to
define snippets while Yasnippet uses a its own format that embeds Emacs-Lisp
into plain text.
For both packages, the list of available snippets depends on the current major
mode. The Guix source code repository offers snippets for ~scheme-mode~ and for
editing Git commit messages.
**** Tempel
To install Tempel into your Guix user profile, run:
#+begin_src sh
guix install emacs-tempel
#+end_src
In your Emacs initialization file, load the =tempel= feature and add the path
to Guix' proper Tempel snippets to the ~tempel-path~ variable.
#+begin_src elisp
(require 'tempel)
;; ensure that tempel-path is a list because it may also be a string:
(setq tempel-path (ensure-list tempel-path))
(add-to-list 'tempel-path "~/src/guix/etc/snippets/tempel/*"))
#+end_src
There are many further configuration options described by Tempel itself. (Type
=C-x P tempel RET= (~describe-package~) to read them in Emacs.)
The most important commands are ~tempel-complete~ (for completing possibly
incomplete input at point), ~tempel-expand~ (for completing exactly matching
input at point), ~tempel-insert~ (for inserting a snippet chosen in
minibuffer). For example, in a Scheme buffer, type =pack= and call =M-x
tempel-complete RET=. This will replace =pack= with a snippet for package
definition. This snippet is interactive. It has some logic implemented in it.
E.g. when you specify ~git-fetch~ as method for fetching the packages source
code, Tempel automatically adapts the ~uri~ field to a S-expression around
~git-reference~. By default, you can move point to previous or next snippet
field with =M-UP= and =M-DOWN= keys (~tempel-previous~ and ~tempel-next~)
respectively.
**** Yasnippet
To install Yasnippet into your Guix user profile, run:
#+begin_src sh
guix install emacs-yasnippet
#+end_src
In your Emacs initialization file, load the =yasnippet= feature; make sure the
respective snippets directory from your local Guix repository is member of the
~yas-snippet-dirs~ variable; and somehow turn on Yasnippet mode, e.g. globally.
Here's an example:
#+begin_src elisp
(require 'yasnippet)
(add-to-list 'yas-snippet-dirs "~/src/guix/etc/snippets/yas")
(yas-global-mode 1)
#+end_src
To choose and insert a snippet, type =C-c & C-s=, bound to ~yas-insert-snippet~.
Snippets have a short "key". When there's a valid Yasnippet key before point,
pressing =TAB= (~yas-expand~) will expand it to the full snippet. E.g. when
editing a Git commit message, you can type =a d d TAB= to insert a snippet that
describes the addition of a new package according to Guix' commit conventions.
If you use completion frameworks like Consult.el, Helm or Ivy, search the web
for packages that integrate Yasnippet into it.
*** Usage
Let's assume you opened a Guix-related Scheme file in Emacs and ~scheme-mode~,
~geiser-mode~ and ~guix-devel-mode~ are turned on. Let's further assume
~geiser-autodoc-mode~ has been enabled, as Geiser does by default.
To load the Guile module, that is defined by the current file, into the
Geiser's Guile REPL, type =C-c . u= which runs ~guix-devel-use-module~.
Similarly, when editing a package definition, =C-c . l= will lint current
package definition at point using =guix lint=. Thus, it will also run some
security checks and make sure the package builds etc.
Now, move the point to Guix-related identifiers and Geiser Autodoc Mode will
echo helpful information. For more detailed information on the symbol at point,
type =C-c C-d d= (or =C-c C-d C-d=), bound to ~geiser-doc-symbol-at-point~.
To view a full list of keybindings, e.g. for linting, type =C-h b=.
** Mu4e
Mu is a tool for dealing with maildirs. Mu4e is integrates Mu into Emacs as
mail reader. To install Mu and Mu4e into your Guix user profile, run:
#+begin_src sh
guix install mu
#+end_src
Mu4e includes an /action/ to apply a Git patch that is attached to the email
that you are viewing. The action is not enabled by default. In order to enable
it, put the following in your Emacs initialization file:
#+begin_src elisp
(add-to-list 'mu4e-view-actions
'("apply git patch" . mu4e-action-git-apply-mbox))
#+end_src
Now, you can apply the patch by typing =a a=.
* Footnotes
[fn:1] Guile might compile the Scheme code into its own cache instead of
putting the resulting =.go= files next to their sources. You might then remove
the ~/.cache/guile~ directory.
- Draft new Guix Cookbook section on Emacs,
Mekeor Melire <=