GNU bug report logs - #58693
[PATCH 0/1] gnu: home: Add home-emacs-service-type.

Previous Next

Package: guix-patches;

Reported by: "(" <paren <at> disroot.org>

Date: Fri, 21 Oct 2022 19:24:02 UTC

Severity: normal

Tags: moreinfo, patch

Merged with 58652

Done: "(" <paren <at> disroot.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 58693 in the body.
You can then email your comments to 58693 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#58693; Package guix-patches. (Fri, 21 Oct 2022 19:24:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to "(" <paren <at> disroot.org>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Fri, 21 Oct 2022 19:24:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: "(" <paren <at> disroot.org>
To: guix-patches <at> gnu.org
Cc: "\(" <paren <at> disroot.org>
Subject: [PATCH 0/1] gnu: home: Add home-emacs-service-type.
Date: Fri, 21 Oct 2022 20:23:28 +0100
Hey Guix!

This patch finally adds a home-emacs-service-type, which supports:

  - Setting up the ``init.el'' and ``early-init.el'' files.
  - Automatically running the Emacs daemon.
  - Natively compiling the given Emacs packages if ``native-compile?''
    is enabled.
  - Loading the given Emacs packages *without* installing them into
    the profile, by setting EMACSLOADPATH and EMACSNATIVELOADPATH
    appropriately before launching the daemon.
  - Enabling ``--debug-init''.

I hope it'll see plenty of use :)

( (1):
  gnu: home: Add home-emacs-service-type.

 doc/guix.texi               |  51 ++++++++++++
 gnu/home/services/emacs.scm | 162 ++++++++++++++++++++++++++++++++++++
 gnu/local.mk                |   1 +
 3 files changed, 214 insertions(+)
 create mode 100644 gnu/home/services/emacs.scm


base-commit: 4716cea6256523a8ecf90a426d675bfb7620f3e4
-- 
2.38.0





Information forwarded to guix-patches <at> gnu.org:
bug#58693; Package guix-patches. (Fri, 21 Oct 2022 19:26:01 GMT) Full text and rfc822 format available.

Message #8 received at 58693 <at> debbugs.gnu.org (full text, mbox):

From: "(" <paren <at> disroot.org>
To: 58693 <at> debbugs.gnu.org
Cc: "\(" <paren <at> disroot.org>
Subject: [PATCH 1/1] gnu: home: Add home-emacs-service-type.
Date: Fri, 21 Oct 2022 20:24:58 +0100
* gnu/local.mk (GNU_SYSTEM_MODULES): Add gnu/home/services/emacs.scm.
* gnu/home/services/emacs.scm (home-emacs-configuration): New
  record type.
(home-emacs-service-type): New variable.
* doc/guix.texi: Document them.
---
 doc/guix.texi               |  51 ++++++++++++
 gnu/home/services/emacs.scm | 162 ++++++++++++++++++++++++++++++++++++
 gnu/local.mk                |   1 +
 3 files changed, 214 insertions(+)
 create mode 100644 gnu/home/services/emacs.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index 3bf2dee752..dc27b7437e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -40517,6 +40517,7 @@ services)}.
 * Shepherd: Shepherd Home Service.                     Managing User's Daemons.
 * SSH: Secure Shell.                                   Setting up the secure shell client.
 * Desktop: Desktop Home Services.                      Services for graphical environments.
+* Emacs: Emacs Home Service.                           Service for running Emacs.
 * Guix: Guix Home Services.                            Services for Guix.
 @end menu
 @c In addition to that Home Services can provide
@@ -41348,6 +41349,56 @@ The package providing the @code{/bin/dbus-daemon} command.
 @end table
 @end deftp
 
+@node Emacs Home Service
+@subsection Emacs Home Service
+
+@defvr {Scheme Variable} home-emacs-service-type
+This is the service type for configuring the Emacs text editor and
+running its daemon.
+
+Note that if you have an existing @file{~/.emacs} and/or
+@file{~/.emacs.d}, the configuration aspect of this service will
+not function, as they take precedence over @file{~/.config/emacs},
+which this service uses in the interest of cleanliness.  To migrate
+to the XDG directory, run these commands:
+
+@example
+$ cp ~/.emacs.d $XDG_CONFIG_HOME/emacs
+$ cp ~/.emacs $XDG_CONFIG_HOME/emacs/init.el
+@end example
+@end defvr
+
+@deftp {Data Type} home-emacs-configuration
+The configuration record for @code{home-emacs-service-type}.
+
+@table @asis
+@item @code{emacs} (default: @code{emacs})
+The package providing the @file{/bin/emacs} and @file{/bin/emacsclient}
+commands.
+
+@item @code{packages} (default: @code{'()})
+Packages providing Emacs plugins to add to the daemon's load paths.
+
+@item @code{native-compile?} (default: @code{#f})
+Whether to recompile all @code{packages}, using the provided @code{emacs}
+package in place of @code{emacs-minimal}, which will enable native
+compilation if the @code{emacs} package supports it.  All
+non-@code{-minimal} Emacs packages at version 28 or above should support
+native compilation.
+
+@item @code{init-file} (default: @code{(plain-file "init.el" "")})
+The file-like to use as @file{init.el}, the main Emacs configuration
+file.
+
+@item @code{early-init-file} (default: @code{(plain-file "early-init.el" "")})
+The file-like to use as @file{early-init.el}, which is loaded early in
+the initialisation process, before the GUI is started.
+
+@item @code{debug?} (default: @code{#f})
+Whether to enable detailed debug log output with backtraces.
+@end table
+@end deftp
+
 @node Guix Home Services
 @subsection Guix Home Services
 
diff --git a/gnu/home/services/emacs.scm b/gnu/home/services/emacs.scm
new file mode 100644
index 0000000000..a727a2f246
--- /dev/null
+++ b/gnu/home/services/emacs.scm
@@ -0,0 +1,162 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 ( <paren <at> disroot.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu home services emacs)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:autoload   (gnu packages emacs) (emacs-minimal
+                                     emacs)
+  #:use-module (gnu services configuration)
+  #:use-module (guix gexp)
+  #:use-module (guix packages)
+  #:use-module (guix records)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+
+  #:export (home-emacs-configuration
+            home-emacs-service-type))
+
+(define list-of-file-likes?
+  (list-of file-like?))
+
+(define-configuration/no-serialization home-emacs-configuration
+  (emacs
+   (file-like emacs)
+   "The package providing @file{/bin/emacs}.")
+  (packages
+   (list-of-file-likes '())
+   "Packages to add to the Emacs plugin load path.")
+  (native-compile?
+   (boolean #f)
+   "Whether to compile the @code{packages} using the Emacs package
+provided as the value of the @code{emacs} field, which will enable
+native compilation if the @code{emacs} package supports it.")
+  (init-file
+   (file-like (plain-file "init.el" ""))
+   "File-like to use as the initialisation Lisp file.")
+  (early-init-file
+   (file-like (plain-file "early-init.el" ""))
+   "File-like to use as the pre-initialisation Lisp file.")
+  (debug?
+   (boolean #f)
+   "Whether to enable debugging."))
+
+(define (home-emacs-profile-packages config)
+  (list (home-emacs-configuration-emacs config)))
+
+(define (home-emacs-transformed-packages config)
+  (map (if (home-emacs-configuration-native-compile? config)
+           (package-input-rewriting
+            `((,emacs-minimal
+              . ,(home-emacs-configuration-emacs config))))
+           identity)
+       (let ((packages (home-emacs-configuration-packages config)))
+         (concatenate
+          (cons packages
+                (map (compose (cute map second <>)
+                              package-transitive-propagated-inputs)
+                     packages))))))
+
+(define (home-emacs-shepherd-services config)
+  (list (shepherd-service
+         (provision '(emacs))
+         (documentation "Start the Emacs daemon.")
+         (modules '((ice-9 ftw)
+                    (srfi srfi-1)
+                    (srfi srfi-26)))
+         (start
+          #~(make-forkexec-constructor
+             (list #$(file-append
+                      (home-emacs-configuration-emacs config)
+                      "/bin/emacs")
+                   "--fg-daemon" "--eval"
+                   (format #f "~s"
+                           `(progn
+                             (setq custom-file
+                                   (concat (or (getenv "XDG_CONFIG_HOME")
+                                               (concat (getenv "HOME")
+                                                       "/.config"))
+                                           "/emacs/custom.el"))
+                             (load custom-file)))
+                   #$@(if (home-emacs-configuration-debug? config)
+                          (list "--debug-init")
+                          '()))
+             #:log-file
+             (format #f "~a/emacs.log"
+                     (or (getenv "XDG_LOG_HOME")
+                         (format #f "~a/.local/var/log"
+                                 (getenv "HOME"))))
+             #:environment-variables
+             (let ((env-var
+                    (lambda (name path)
+                      (define (regular-directory? directory)
+                        (not (member directory (list "." ".."))))
+
+                      (define (package-paths package)
+                        (let ((directory (string-append package "/" path)))
+                          (if (file-exists? directory)
+                              (cons directory
+                                    (map (cute string-append directory "/" <>)
+                                         (scandir directory regular-directory?)))
+                              '())))
+
+                      (let ((old-value (getenv name)))
+                        (string-append
+                         name "="
+                         (string-join
+                          (append-map
+                           package-paths
+                           (list #$@(home-emacs-transformed-packages config)))
+                          ":" (if old-value
+                                  'suffix
+                                  'infix))
+                         (or old-value ""))))))
+               (append (default-environment-variables)
+                       (list (env-var "EMACSLOADPATH"
+                                      "share/emacs/site-lisp")
+                             (env-var "EMACSNATIVELOADPATH"
+                                      "lib/emacs/native-site-lisp"))))))
+         (stop
+          #~(make-forkexec-constructor
+             (list #$(file-append
+                      (home-emacs-configuration-emacs config)
+                      "/bin/emacsclient")
+                   "--eval" "(kill-emacs)"))))))
+
+(define (home-emacs-xdg-configuration-files config)
+  `(("emacs/early-init.el"
+     ,(home-emacs-configuration-early-init-file config))
+    ("emacs/init.el"
+     ,(home-emacs-configuration-init-file config))))
+
+(define home-emacs-service-type
+  (service-type
+   (name 'home-emacs)
+   (extensions
+    (list (service-extension
+           home-profile-service-type
+           home-emacs-profile-packages)
+          (service-extension
+           home-shepherd-service-type
+           home-emacs-shepherd-services)
+          (service-extension
+           home-xdg-configuration-files-service-type
+           home-emacs-xdg-configuration-files)))
+   (default-value (home-emacs-configuration))
+   (description
+    "Configure and run the GNU Emacs extensible text editor.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 8247180bef..3431c771b8 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -88,6 +88,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services.scm			\
   %D%/home/services/desktop.scm			\
   %D%/home/services/symlink-manager.scm		\
+  %D%/home/services/emacs.scm			\
   %D%/home/services/fontutils.scm		\
   %D%/home/services/guix.scm			\
   %D%/home/services/pm.scm			\
-- 
2.38.0





Information forwarded to guix-patches <at> gnu.org:
bug#58693; Package guix-patches. (Sat, 22 Oct 2022 09:42:02 GMT) Full text and rfc822 format available.

Message #11 received at 58693 <at> debbugs.gnu.org (full text, mbox):

From: Liliana Marie Prikler <liliana.prikler <at> gmail.com>
To: "(" <paren <at> disroot.org>, 58693 <at> debbugs.gnu.org
Cc: control <at> debbugs.gnu.org
Subject: Re: [PATCH 1/1] gnu: home: Add home-emacs-service-type.
Date: Sat, 22 Oct 2022 11:41:43 +0200
merge 58693 58652
thanks

Am Freitag, dem 21.10.2022 um 20:24 +0100 schrieb (:
> +(define-configuration/no-serialization home-emacs-configuration
> +  (emacs
> +   (file-like emacs)
> +   "The package providing @file{/bin/emacs}.")
> +  (packages
> +   (list-of-file-likes '())
> +   "Packages to add to the Emacs plugin load path.")
> +  (native-compile?
> +   (boolean #f)
> +   "Whether to compile the @code{packages} using the Emacs package
> +provided as the value of the @code{emacs} field, which will enable
> +native compilation if the @code{emacs} package supports it.")
> +  (init-file
> +   (file-like (plain-file "init.el" ""))
> +   "File-like to use as the initialisation Lisp file.")
> +  (early-init-file
> +   (file-like (plain-file "early-init.el" ""))
> +   "File-like to use as the pre-initialisation Lisp file.")
> +  (debug?
> +   (boolean #f)
> +   "Whether to enable debugging."))
> +
> +(define (home-emacs-profile-packages config)
> +  (list (home-emacs-configuration-emacs config)))
> +
> +(define (home-emacs-transformed-packages config)
> +  (map (if (home-emacs-configuration-native-compile? config)
> +           (package-input-rewriting
> +            `((,emacs-minimal
> +              . ,(home-emacs-configuration-emacs config))))
> +           identity)
> +       (let ((packages (home-emacs-configuration-packages config)))
> +         (concatenate
> +          (cons packages
> +                (map (compose (cute map second <>)
> +                              package-transitive-propagated-inputs)
> +                     packages))))))
> +
> +(define (home-emacs-shepherd-services config)
> +  (list (shepherd-service
> +         (provision '(emacs))
> +         (documentation "Start the Emacs daemon.")
> +         (modules '((ice-9 ftw)
> +                    (srfi srfi-1)
> +                    (srfi srfi-26)))
> +         (start
> +          #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-emacs-configuration-emacs config)
> +                      "/bin/emacs")
> +                   "--fg-daemon" "--eval"
You should probably use a systemd-style constructor/destructor pair.

> +                   (format #f "~s"
> +                           `(progn
> +                             (setq custom-file
> +                                   (concat (or (getenv
> "XDG_CONFIG_HOME")
> +                                               (concat (getenv
> "HOME")
> +                                                       "/.config"))
> +                                           "/emacs/custom.el"))
> +                             (load custom-file)))
This one should be customizable by the user using init.el or early-
init.el -- alternatively, you could set up a custom-file parameter and
use that *if given*.

> +                   #$@(if (home-emacs-configuration-debug? config)
> +                          (list "--debug-init")
> +                          '()))
> +             #:log-file
> +             (format #f "~a/emacs.log"
> +                     (or (getenv "XDG_LOG_HOME")
> +                         (format #f "~a/.local/var/log"
> +                                 (getenv "HOME"))))
XDG_LOG_HOME and ~/.local/var are guix home idiosyncrasies that ought
to be removed.  The XDG-supported variable/value pair is XDG_STATE_HOME
and ~/.local/state.

> +             #:environment-variables
> +             (let ((env-var
> +                    (lambda (name path)
> +                      (define (regular-directory? directory)
> +                        (not (member directory (list "." ".."))))
> +
> +                      (define (package-paths package)
> +                        (let ((directory (string-append package "/"
> path)))
> +                          (if (file-exists? directory)
> +                              (cons directory
> +                                    (map (cute string-append
> directory "/" <>)
> +                                         (scandir directory regular-
> directory?)))
> +                              '())))
> +
> +                      (let ((old-value (getenv name)))
> +                        (string-append
> +                         name "="
> +                         (string-join
> +                          (append-map
> +                           package-paths
> +                           (list #$@(home-emacs-transformed-packages
> config)))
> +                          ":" (if old-value
> +                                  'suffix
> +                                  'infix))
> +                         (or old-value ""))))))
> +               (append (default-environment-variables)
> +                       (list (env-var "EMACSLOADPATH"
> +                                      "share/emacs/site-lisp")
> +                             (env-var "EMACSNATIVELOADPATH"
> +                                      "lib/emacs/native-site-
> lisp"))))))
You should collect the emacs package plus lisp packages into a profile.
This will make it easier to set emacs-related variables. 
Alternatively, you could use (guix search-paths) directly.

> +         (stop
> +          #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-emacs-configuration-emacs config)
> +                      "/bin/emacsclient")
> +                   "--eval" "(kill-emacs)"))))))
> +
> +(define (home-emacs-xdg-configuration-files config)
> +  `(("emacs/early-init.el"
> +     ,(home-emacs-configuration-early-init-file config))
> +    ("emacs/init.el"
> +     ,(home-emacs-configuration-init-file config))))
You're missing an escape hatch for additional elisp files like
custom.el

Cheers

Merged 58652 58693. Request was from Liliana Marie Prikler <liliana.prikler <at> gmail.com> to control <at> debbugs.gnu.org. (Sat, 22 Oct 2022 09:42:02 GMT) Full text and rfc822 format available.

Added tag(s) moreinfo. Request was from Christopher Baines <mail <at> cbaines.net> to control <at> debbugs.gnu.org. (Thu, 03 Nov 2022 16:16:02 GMT) Full text and rfc822 format available.

Information forwarded to guix-patches <at> gnu.org:
bug#58693; Package guix-patches. (Tue, 08 Nov 2022 13:00:03 GMT) Full text and rfc822 format available.

Message #18 received at 58693 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: "(" <paren <at> disroot.org>
Cc: 58693 <at> debbugs.gnu.org
Subject: Re: bug#58693: [PATCH 0/1] gnu: home: Add home-emacs-service-type.
Date: Tue, 08 Nov 2022 13:59:10 +0100
Hi!

"(" <paren <at> disroot.org> skribis:

> +@defvr {Scheme Variable} home-emacs-service-type
> +This is the service type for configuring the Emacs text editor and
> +running its daemon.

I would happily use some Guix Home service to configure Emacs, but I
don’t want to start it as a daemon (currently I start it from
~/.xsession as I use EXWM).

Could we somehow decouple the daemon aspect from the rest?

Anyhow, I’m glad to see this work—thank you!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#58693; Package guix-patches. (Tue, 08 Nov 2022 16:31:01 GMT) Full text and rfc822 format available.

Message #21 received at 58693 <at> debbugs.gnu.org (full text, mbox):

From: "(" <paren <at> disroot.org>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 58693 <at> debbugs.gnu.org
Subject: Re: bug#58693: [PATCH 0/1] gnu: home: Add home-emacs-service-type.
Date: Tue, 08 Nov 2022 16:30:23 +0000
Heya,

On Tue Nov 8, 2022 at 12:59 PM GMT, Ludovic Courtès wrote:
> I would happily use some Guix Home service to configure Emacs, but I
> don’t want to start it as a daemon (currently I start it from
> ~/.xsession as I use EXWM).
>
> Could we somehow decouple the daemon aspect from the rest?

There's virtually no point in doing so. This service doesn't generate ELisp from
a Scheme config, as I think Emacs is too flexible for that; instead, it lets you
choose the packages, init file, etc to pass to the daemon (which is what is meant
by "configure", I suppose).

    -- (




bug closed, send any further explanations to 58693 <at> debbugs.gnu.org and "(" <paren <at> disroot.org> Request was from "(" <paren <at> disroot.org> to control <at> debbugs.gnu.org. (Thu, 30 Mar 2023 19:04:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 28 Apr 2023 11:24:14 GMT) Full text and rfc822 format available.

This bug report was last modified 357 days ago.

Previous Next


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