GNU bug report logs - #64620
[PATCH] gnu: home: Add home-emacs-service-type.

Previous Next

Package: guix-patches;

Reported by: fernseed <at> fernseed.me

Date: Fri, 14 Jul 2023 15:50:02 UTC

Severity: normal

Tags: patch

Full log


View this message in rfc822 format

From: Ludovic Courtès <ludo <at> gnu.org>
To: fernseed <at> fernseed.me
Cc: , 64620 <at> debbugs.gnu.org
Subject: [bug#64620] [PATCH] gnu: home: Add home-emacs-service-type.
Date: Wed, 23 Aug 2023 12:01:51 +0200
Hi Kierin,

This is a truly impressive piece of work!

fernseed <at> fernseed.me skribis:

> This patch builds on patches from ( and David Wilson for a
> `home-emacs-service-type' (https://issues.guix.gnu.org/58693,
> https://issues.guix.gnu.org/60753, https://issues.guix.gnu.org/62549).
>
> Many of the features of the prior patches have been included, but the
> major focus here is to configure Emacs in Scheme rather than symlinking
> to existing configuration files.

OK, interesting.  This seems to be one of the main questions: how far
should we go on the Scheme side?

In <https://issues.guix.gnu.org/62549>, unmatched-paren chose to not
generate elisp at all from Scheme.  The advantage is that the
implementation is simpler; as a user, the model one has to have in mind
is also simpler: you’re still configuring most things the traditional
way in elisp.  That’s also its downside: you have to do plumbing on the
elisp side, when Guix Home in some cases would know what to do.

I don’t have the answer and I’m not sure what I’d prefer, but I’m trying
to see the tradeoffs and to map out the design space.

> Here are some of the broad strokes:
>
> * The following record types have been introduced to encapsulate
>   configuration for Emacs: `emacs-configuration' (for general
>   configuration), `emacs-package' (for package-specific configuration),
>   `emacs-keymap' (for configuration of local keymaps), and
>   `emacs-server' (for configuration of Emacs servers).

Why special-case keymaps, of all the things one might one to configure
in Emacs?  I understand it’s one of the first things one may want to
tweak, but then why not add <emacs-theme> as well, etc.; IOW, where do
we draw the line?

> * Most configuration fields are either flat lists or alists that are
>   considerably abstracted from their final serialized Elisp
>   representation, but escape hatches are provided for both pulling in
>   existing configuration files and specifying s-expressions directly.

Are seasoned Emacsers not going to be frustrated because of this?  :-)

They might prefer to have full access to elisp.

> * All serialized Elisp is pretty-printed much how we would expect to see
>   it in Emacs (for example, with proper indentation according to the
>   `lisp-indent-function' symbol property, etc.).  This has been
>   accomplished by adding a new keyword argument to
>   `pretty-print-with-comments' from `(guix read-print)', among other
>   improvements.

Fun.  I’d like to see how we can avoid spreading elisp conditionals in
(guix read-print).

> * Emacs package configuration can either be serialized as `use-package'
>   forms or as equivalent, more minimalist s-expressions.  Users can
>   define their own package serializers, too.
>
> * For specifying s-expressions, an "Elisp expression" syntax has been
>   implemented that is essentially a lighter-weight version G-expressions.
>   (I try to explain why this is helpful in the documentation.)
>
> * A reader extension has been implemented that allows for "Elisp
>   expressions" to be specified directly with Elisp read syntax, and
>   Scheme values (including file-like objects or G-expressions) can in
>   turn be "unquoted" within that Elisp code.  Also, comments and
>   whitespace can be included within the Elisp code via the `#;'
>   (comment), `#>' (newline), and `;^L' (page break) forms.

Great that you’re putting (language elisp parser) to good use!

> * Each Emacs server has its own user init and early init files, which
>   can optionally inherit configuration from the init files used by
>   non-server Emacsen.  Each server can also inherit the "main"
>   `user-emacs-directory', or it can use its own subdirectory.
>
> * The `home-emacs-service-type' can be extended, with subordinate
>   configuration records being merged intelligently when possible.

Very nice.

> * A utility function has been provided for generating the aforementioned
>   Scheme records from an existing Emacs init file:
>   `elisp-file->home-emacs-configuration'.

Neat; perhaps ‘guix home import’ could use it?

> (define %gnus-init-file
>   (elisp-file "gnus.el"
>               (list
>                (elisp (setq gnus-select-method '(nnnil "")))
>                (elisp (setq gnus-secondary-select-methods
>                             '((nnml "")
>                               (nntp "news.gmane.io"))))
>                (elisp (setq mail-sources
>                             '((imap :server "mail.example.net"
>                                     :user "user <at> example.net"
>                                     :port 993
>                                     :stream tls))))
>                ;; Elisp reader extension
>                #%(define-key global-map [remap compose-mail] #;comment
>                    '#$%my-function-name nil))))

Could I write:

  #%(progn
      (setq x …)
      (setq y …)
      (define-key …))

?  That would seem nicer.

#%(body …) is short for (elisp body …) right?


[...]

>      (configured-packages
>       (list
>        (emacs-package
>         (name 'windmove)
>         ;; Autoload a function used by `my--display-buffer-down'.
>         (autoloads '(windmove-display-in-direction))
>         (keys-override
>          '(("C-M-<left>" . windmove-left)
>            ("C-M-<right>" . windmove-right)
>            ("C-M-<up>" . windmove-up)
>            ("C-M-<down>" . windmove-down)
>            ("C-x <down>"
>             . my--display-buffer-down)))
>         (keys-local
>          (list
>           (emacs-keymap
>            (name 'windmove-repeat-map)
>            (repeat? #t)
>            (keys '(("<left>" . windmove-left)
>                    ("<right>" . windmove-right)
>                    ("<up>" . windmove-up)
>                    ("<down>" . windmove-down))))))

My first reaction is that I don’t see myself my 2K lines (or a subset
thereof) of .emacs and .gnus in that style.  I can foresee potential
benefits in terms of composability, but the barrier to entry looks too
high.  WDYT?

> Finally, unit tests have been added for the new `(guix read-print)'
> functionality, and for the "Elisp expression" syntax.  I couldn't make
> unit tests for anything that builds derivations serializing Elisp,
> because '%bootstrap-guile' is apparently too old to load `(guix
> read-print)' on the derivation side.  But most of this has gotten quite
> a bit of testing, as all of my personal Emacs config is now generated
> from Scheme.

I think you could write tests using ‘guix home container’ and the host’s
store, similar to what ‘tests/guix-home.sh’ is doing.  We don’t have a
testing strategy for Home services yet, but we should definitely work on
it.

That’s it for my initial feedback.  I hope others in the Home and Emacs
teams will chime in!

Thanks,
Ludo’.




This bug report was last modified 106 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.