Subject: Re: bug#41732: issue with emacs-lua-mode and emacs-next

From: zimoun <[email-masked]>
Date: Sun, 7 Jun 2020 11:31:41 +0200

Dear Maxim,

On Sun, 7 Jun 2020 at 06:39, Maxim Cournoyer <[email-masked]> wrote:

> Some people have been adding emacs-next-something packages (IIRC); I
> think it's OK for the big, complicated packages that need effort to
> port, but otherwise I wouldn't like seeing this happening for all
> packages.

I agree.  I am not suggesting to duplicate all the packages with
'emacs-next-something'.  There is already enough to do with the
current ones. :-)

> > Well, I am not suggesting to duplicate all the Emacs packages with
> > something like 'emacs-next-<package>' because it is too much.  I am
> > suggesting to provide 'package-with-emacs-next' and then for example
> > in my manifest file I would use this new procedure to generate
> > on-the-fly these next packages; as an expert Emacs mode.
>
> That sounds like a good idea; provide a way for users to rewrite their
> package at the level of their manifest file (which is already possible
> IIUC).

I propose to provide 'package-with-emacs-next' for the people in the
experimental mood. :-)  For example, the manifest looks like:

--8<---------------cut here---------------start------------->8---
(use-modules (guix build-system emacs)
             (gnu packages emacs)
             (gnu packages emacs-xyz))

(packages->manifest
 (cons emacs-next
       (map
        package-with-emacs-next
        (list
         emacs-lua-mode
         emacs-magit))))
--8<---------------cut here---------------end--------------->8---

Then the expert uses it with:

   guix package -m manifest.scm

Well, the attached patch does that.  And maybe, an entry to the
Cookbook could be worth.

> > I do not know if this proposal makes sense.  Probably not. :-)
> > (My regular Emacs is the current version and I very rarely use
> > emacs-next because I started Emacs with 23 therefore 24 was already a
> > so-nice improvement. :-))
>
> It does make sense. For those who would like to see our base Emacs
> package be updated to emacs-next, we need to iron out all the packages
> currently failing to build with it.  It is easy to try, by modifying
> slightly a local Guix checkout:
>
> --8<---------------cut here---------------start------------->8---
> 1 file changed, 1 insertion(+), 1 deletion(-)
> guix/build-system/emacs.scm | 2 +-
>
> modified   guix/build-system/emacs.scm
> @@ -52,7 +52,7 @@
>    "Return the default Emacs package."
>    ;; Lazily resolve the binding to avoid a circular dependency.
>    (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
> -    (module-ref emacs-mod 'emacs-minimal)))
> +    (module-ref emacs-mod 'emacs-next)))
>
>  (define* (lower name
>                  #:key source inputs native-inputs outputs system target
>
> --8<---------------cut here---------------end--------------->8---

What I propose simplifies because it avoids to recompile all Guix and
to use ./pre-inst-env.
Well, I do not know.  It is an half-cooked proposal. :-)

And the added 'package-with-explicit-emacs' procedure allows to use
any Emacs as the VM, so for example, it could be cool to see what
happens with REmacs (which is not packaged but that's another story
:-)).
Or for example with Gccemacs.

All the best,
simon

ps:
Note that 'package-with-explicite-emacs' and
'package-with-explicit-python' should be refactored, another story.
:-)
From 4038b0c53d5066facceea3c159a6510fa8a625d6 Mon Sep 17 00:00:00 2001
From: zimoun <[email-masked]>
Date: Sun, 7 Jun 2020 11:07:08 +0200
Subject: [PATCH] DRAFT: build-system: emacs: Add new
 'package-with-emacs-next'procedure.

* guix/build-system/emacs.scm: Add 'default-emacs-next'.
* guix/build-system/emacs.scm: Add 'package-with-emacs-next'.
---
 guix/build-system/emacs.scm | 66 +++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
index ef6d1b3397..8732678dca 100644
--- a/guix/build-system/emacs.scm
+++ b/guix/build-system/emacs.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Federico Beffa <[email-masked]>
+;;; Copyright © 2020 Simon Tournier <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,6 +30,7 @@
   #:use-module (ice-9 match)
   #:use-module (srfi srfi-26)
   #:export (%emacs-build-system-modules
+            package-with-emacs-next
             emacs-build
             emacs-build-system)
   #:re-export (%default-include         ;for convenience
@@ -54,6 +56,70 @@
   (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
     (module-ref emacs-mod 'emacs-minimal)))
 
+(define (default-emacs-next)
+  "Return the default Emacs-next package."
+  (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
+    (module-ref emacs-mod 'emacs-next)))
+
+(define* (package-with-explicit-emacs emacs old-prefix new-prefix
+                                       #:key variant-property)
+  "Return a procedure of one argument, P.  The procedure creates a package with
+the same fields as P, which is assumed to use EMACS-BUILD-SYSTEM, such that
+it is compiled with EMACS instead.  The inputs are changed recursively
+accordingly.  If the name of P starts with OLD-PREFIX, this is replaced by
+NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name.
+
+When VARIANT-PROPERTY is present, it is used as a key to search for
+pre-defined variants of this transformation recorded in the 'properties' field
+of packages.  The property value must be the promise of a package.  This is a
+convenient way for package writers to force the transformation to use
+pre-defined variants."
+  (define package-variant
+    (if variant-property
+        (lambda (package)
+          (assq-ref (package-properties package)
+                    variant-property))
+        (const #f)))
+
+  (define (transform p)
+    (cond
+     ;; If VARIANT-PROPERTY is present, use that.
+     ((package-variant p)
+      => force)
+
+     ;; Otherwise build the new package object graph.
+     ((eq? (package-build-system p) emacs-build-system)
+      (package
+        (inherit p)
+        (location (package-location p))
+        (name (let ((name (package-name p)))
+                (string-append new-prefix
+                               (if (string-prefix? old-prefix name)
+                                   (substring name
+                                              (string-length old-prefix))
+                                   name))))
+        (arguments
+         (let ((emacs (if (promise? emacs)
+                           (force emacs)
+                           emacs)))
+           (ensure-keyword-arguments (package-arguments p)
+                                     `(#:emacs ,emacs))))))
+     (else p)))
+
+  (define (cut? p)
+    (or (not (eq? (package-build-system p) emacs-build-system))
+        (package-variant p)))
+
+  (package-mapping transform cut?))
+
+(define package-with-emacs-next
+  ;; Note: delay call to 'default-emacs-next' until after the 'arguments' field
+  ;; of packages is accessed to avoid a circular dependency when evaluating
+  ;; the top-level of (gnu packages emacs).
+  (package-with-explicit-emacs (delay (default-emacs-next))
+                                "emacs-" "emacs-next-"
+                                #:variant-property 'emacs-next-variant))
+
 (define* (lower name
                 #:key source inputs native-inputs outputs system target
                 (emacs (default-emacs))
-- 
2.26.2