unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH 2/2] emacs: Add interface for comparing generations.
@ 2014-11-02 11:21 Alex Kost
  2014-11-02 17:59 ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Kost @ 2014-11-02 11:21 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

In short, now (with this patch) after marking 2 generations (by pressing
"m" in a “generation-list” buffer), you can perform diff/ediff on
generation packages or manifests.  Thanks to Ludovic for the idea.


[-- Attachment #2: 0002-emacs-Add-interface-for-comparing-generations.patch --]
[-- Type: text/x-diff, Size: 15459 bytes --]

From 2b98ab3243e5d79f9787442bd1bfdceb76bf72a8 Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Sun, 2 Nov 2014 13:58:21 +0300
Subject: [PATCH 2/2] emacs: Add interface for comparing generations.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Suggested by Ludovic Courtès.

* doc/emacs.texi (Emacs List buffer): Document new key bindings.
* emacs/guix-base.el (guix-generation-packages-buffer-name-function): New
  variable.
  (guix-generation-file, guix-manifest-file, guix-generation-packages,
  guix-generation-packages-buffer-name-default,
  guix-generation-packages-buffer-name-long,
  guix-generation-packages-buffer-name, guix-generation-packages-buffer,
  guix-profile-generation-manifest-file,
  guix-profile-generation-packages-buffer): New procedures.
* emacs/guix-list.el: Add key bindings for comparing generations.
  (guix-generation-list-generations-to-compare,
  guix-generation-list-show-added-packages,
  guix-generation-list-show-removed-packages, guix-generation-list-compare,
  guix-generation-list-ediff-manifests, guix-generation-list-diff-manifests,
  guix-generation-list-ediff-packages, guix-generation-list-diff-packages,
  guix-generation-list-ediff, guix-generation-list-diff): New procedures.
* emacs/guix-messages.el (guix-messages): Add 'generation-diff' messages.
* emacs/guix-utils.el (guix-diff-switches): New variable.
  (guix-diff): New procedure.
* emacs/guix-main.scm (package/output-sexps): Handle 'generation-diff' search
  type.
  (manifest-entry->package-specification,
  manifest-entries->package-specifications, generation-package-specifications,
  generation-difference): New procedures.
---
 doc/emacs.texi         | 15 +++++++++
 emacs/guix-base.el     | 72 ++++++++++++++++++++++++++++++++++++++++++
 emacs/guix-list.el     | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-
 emacs/guix-main.scm    | 33 ++++++++++++++++++--
 emacs/guix-messages.el | 18 ++++++++++-
 emacs/guix-utils.el    | 10 ++++++
 6 files changed, 229 insertions(+), 4 deletions(-)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 17440e4..5fd9e61 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -239,6 +239,21 @@ Mark the current generation for deletion (with prefix, mark all
 generations).
 @item x
 Execute actions on the marked generations---i.e., delete generations.
+@item e
+Run Ediff (@pxref{Top,,, ediff, Ediff}) on package outputs installed in
+the 2 marked generations.  With prefix argument, run Ediff on manifests
+of the marked generations.
+@item D
+@itemx =
+Run Diff (@pxref{Diff Mode,,, emacs, The Emacs Editor}) on package
+outputs installed in the 2 marked generations.  With prefix argument,
+run Diff on manifests of the marked generations.
+@item +
+List package outputs added to the latest marked generation comparing
+with another marked generation.
+@item -
+List package outputs removed from the latest marked generation comparing
+with another marked generation.
 @end table
 
 @node Emacs Info buffer
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index eb88f37..abbd523 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -650,6 +650,78 @@ This function will not update the information, use
                        guix-search-type guix-search-vals))
 
 \f
+;;; Generations
+
+(defvar guix-generation-packages-buffer-name-function
+  #'guix-generation-packages-buffer-name-default
+  "Function used to define name of a buffer with generation packages.
+This function is called with 2 arguments: PROFILE (string) and
+GENERATION (number).")
+
+(defun guix-generation-file (profile generation)
+  "Return the file name of a PROFILE's GENERATION."
+  (format "%s-%s-link" profile generation))
+
+(defun guix-manifest-file (profile &optional generation)
+  "Return the file name of a PROFILE's manifest.
+If GENERATION number is specified, return manifest file name for
+this generation."
+  (expand-file-name "manifest"
+                    (if generation
+                        (guix-generation-file profile generation)
+                      profile)))
+
+(defun guix-generation-packages (profile generation)
+  "Return a list of sorted outputs installed in PROFILE's GENERATION."
+  (let ((outputs (guix-eval-read (guix-make-guile-expression
+                                  'generation-package-specifications
+                                  profile generation))))
+    (sort outputs #'string<)))
+
+(defun guix-generation-packages-buffer-name-default (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs.
+Use base name of PROFILE path."
+  (let ((profile-name (file-name-base (directory-file-name profile))))
+    (format "*Guix %s: generation %s*"
+            profile-name generation)))
+
+(defun guix-generation-packages-buffer-name-long (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs.
+Use the full PROFILE path."
+  (format "*Guix generation %s (%s)*"
+          generation profile))
+
+(defun guix-generation-packages-buffer-name (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs."
+  (let ((fun (if (functionp guix-generation-packages-buffer-name-function)
+                 guix-generation-packages-buffer-name-function
+               #'guix-generation-packages-buffer-name-default)))
+    (funcall fun profile generation)))
+
+(defun guix-generation-packages-buffer (profile generation)
+  "Return buffer with package outputs installed in PROFILE's GENERATION.
+Create the buffer if needed."
+  (let ((buf-name (guix-generation-packages-buffer-name
+                   profile generation)))
+    (or (get-buffer buf-name)
+        (let ((buf (get-buffer-create buf-name)))
+          (with-current-buffer buf
+            (mapc (lambda (name)
+                    (insert name "\n"))
+                  (guix-generation-packages profile generation)))
+          buf))))
+
+(defun guix-profile-generation-manifest-file (generation)
+  "Return the file name of a GENERATION's manifest.
+GENERATION is a generation number of `guix-profile' profile."
+  (guix-manifest-file guix-profile generation))
+
+(defun guix-profile-generation-packages-buffer (generation)
+  "Insert GENERATION's package outputs in a buffer and return it.
+GENERATION is a generation number of `guix-profile' profile."
+  (guix-generation-packages-buffer guix-profile generation))
+
+\f
 ;;; Actions on packages and generations
 
 (defface guix-operation-option-key
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index 58c03b3..600f2bd 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -27,7 +27,6 @@
 (require 'cl-lib)
 (require 'tabulated-list)
 (require 'guix-info)
-(require 'guix-history)
 (require 'guix-base)
 (require 'guix-utils)
 
@@ -735,6 +734,11 @@ Also see `guix-package-info-type'."
 
 (let ((map guix-generation-list-mode-map))
   (define-key map (kbd "RET") 'guix-generation-list-show-packages)
+  (define-key map (kbd "+")   'guix-generation-list-show-added-packages)
+  (define-key map (kbd "-")   'guix-generation-list-show-removed-packages)
+  (define-key map (kbd "=")   'guix-generation-list-diff)
+  (define-key map (kbd "D")   'guix-generation-list-diff)
+  (define-key map (kbd "e")   'guix-generation-list-ediff)
   (define-key map (kbd "x")   'guix-generation-list-execute)
   (define-key map (kbd "i")   'guix-list-describe)
   (define-key map (kbd "s")   'guix-generation-list-switch)
@@ -761,6 +765,85 @@ VAL is a boolean value."
   (guix-get-show-entries guix-profile 'list guix-package-list-type
                          'generation (guix-list-current-id)))
 
+(defun guix-generation-list-generations-to-compare ()
+  "Return a sorted list of 2 marked generations for comparing."
+  (let ((numbers (guix-list-get-marked-id-list 'general)))
+    (if (/= (length numbers) 2)
+        (user-error "2 generations should be marked for comparing")
+      (sort numbers #'<))))
+
+(defun guix-generation-list-show-added-packages ()
+  "List package outputs added to the latest marked generation.
+If 2 generations are marked with \\[guix-list-mark], display
+outputs installed in the latest marked generation that were not
+installed in the other one."
+  (interactive)
+  (apply #'guix-get-show-entries
+         guix-profile 'list 'output 'generation-diff
+         (reverse (guix-generation-list-generations-to-compare))))
+
+(defun guix-generation-list-show-removed-packages ()
+  "List package outputs removed from the latest marked generation.
+If 2 generations are marked with \\[guix-list-mark], display
+outputs not installed in the latest marked generation that were
+installed in the other one."
+  (interactive)
+  (apply #'guix-get-show-entries
+         guix-profile 'list 'output 'generation-diff
+         (guix-generation-list-generations-to-compare)))
+
+(defun guix-generation-list-compare (diff-fun gen-fun)
+  "Run GEN-FUN on the 2 marked generations and run DIFF-FUN on the results."
+  (cl-multiple-value-bind (gen1 gen2)
+      (guix-generation-list-generations-to-compare)
+    (funcall diff-fun
+             (funcall gen-fun gen1)
+             (funcall gen-fun gen2))))
+
+(defun guix-generation-list-ediff-manifests ()
+  "Run Ediff on manifests of the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'ediff-files
+   #'guix-profile-generation-manifest-file))
+
+(defun guix-generation-list-diff-manifests ()
+  "Run Diff on manifests of the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'guix-diff
+   #'guix-profile-generation-manifest-file))
+
+(defun guix-generation-list-ediff-packages ()
+  "Run Ediff on package outputs installed in the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'ediff-buffers
+   #'guix-profile-generation-packages-buffer))
+
+(defun guix-generation-list-diff-packages ()
+  "Run Diff on package outputs installed in the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'guix-diff
+   #'guix-profile-generation-packages-buffer))
+
+(defun guix-generation-list-ediff (arg)
+  "Run Ediff on package outputs installed in the 2 marked generations.
+With ARG, run Ediff on manifests of the marked generations."
+  (interactive "P")
+  (if arg
+      (guix-generation-list-ediff-manifests)
+    (guix-generation-list-ediff-packages)))
+
+(defun guix-generation-list-diff (arg)
+  "Run Diff on package outputs installed in the 2 marked generations.
+With ARG, run Diff on manifests of the marked generations."
+  (interactive "P")
+  (if arg
+      (guix-generation-list-diff-manifests)
+    (guix-generation-list-diff-packages)))
+
 (defun guix-generation-list-mark-delete (&optional arg)
   "Mark the current generation for deletion and move to the next line.
 With ARG, mark all generations for deletion."
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index 1dd57bb..34901e9 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -106,6 +106,28 @@
    (manifest-entry-version entry)
    (manifest-entry-output  entry)))
 
+(define (manifest-entry->package-specification entry)
+  (call-with-values
+      (lambda () (manifest-entry->name+version+output entry))
+    make-package-specification))
+
+(define (manifest-entries->package-specifications entries)
+  (map manifest-entry->package-specification entries))
+
+(define (generation-package-specifications profile number)
+  "Return a list of package specifications for generation NUMBER."
+  (let ((manifest (profile-manifest
+                   (generation-file-name profile number))))
+    (manifest-entries->package-specifications
+     (manifest-entries manifest))))
+
+(define (generation-difference profile number1 number2)
+  "Return a list of package specifications for outputs installed in generation
+NUMBER1 and not installed in generation NUMBER2."
+  (let ((specs1 (generation-package-specifications profile number1))
+        (specs2 (generation-package-specifications profile number2)))
+    (lset-difference string=? specs1 specs2)))
+
 (define (manifest-entries->hash-table entries)
   "Return a hash table of name keys and lists of matching manifest ENTRIES."
   (let ((table (make-hash-table (length entries))))
@@ -625,8 +647,15 @@ See 'entry-sexps' for details."
                       (generation-file-name profile (car search-vals))
                       profile))
          (manifest (profile-manifest profile))
-         (patterns (apply (patterns-maker entry-type search-type)
-                          manifest search-vals))
+         (patterns (if (and (eq? entry-type 'output)
+                            (eq? search-type 'generation-diff))
+                       (match search-vals
+                         ((g1 g2)
+                          (map specification->output-pattern
+                               (generation-difference profile g1 g2)))
+                         (_ '()))
+                       (apply (patterns-maker entry-type search-type)
+                              manifest search-vals)))
          (->sexps ((pattern-transformer entry-type) manifest params)))
     (append-map ->sexps patterns)))
 
diff --git a/emacs/guix-messages.el b/emacs/guix-messages.el
index c77b5c0..09556be 100644
--- a/emacs/guix-messages.el
+++ b/emacs/guix-messages.el
@@ -101,7 +101,23 @@
       (1 "A single package output installed in generation %d of profile '%s'."
          val profile)
       (many "%d package outputs installed in generation %d of profile '%s'."
-            count val profile)))
+            count val profile))
+     (generation-diff
+      (0 ,(lambda (profile entries vals)
+            (message
+             (concat "No additional packages in generation %d "
+                     "comparing with generation %d of profile '%s'.")
+             (car vals) (cadr vals) profile)))
+      (1 ,(lambda (profile entries vals)
+            (message
+             (concat "A single additional package output in generation %d "
+                     "comparing with generation %d of profile '%s'.")
+             (car vals) (cadr vals) profile)))
+      (many ,(lambda (profile entries vals)
+               (message
+                (concat "%d additional package outputs in generation %d "
+                        "comparing with generation %d of profile '%s'.")
+                (length entries) (car vals) (cadr vals) profile)))))
 
     (generation
      (id
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
index 8787814..77ccb67 100644
--- a/emacs/guix-utils.el
+++ b/emacs/guix-utils.el
@@ -154,6 +154,16 @@ accessed with KEYS."
     (dolist (key keys val)
       (setq val (cdr (assq key val))))))
 
+\f
+;;; Diff
+
+(defvar guix-diff-switches "-u"
+  "A string or list of strings specifying switches to be passed to diff.")
+
+(defun guix-diff (old new &optional switches no-async)
+  "Same as `diff', but use `guix-diff-switches' as default."
+  (diff old new (or switches guix-diff-switches) no-async))
+
 (provide 'guix-utils)
 
 ;;; guix-utils.el ends here
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-02 11:21 [PATCH 2/2] emacs: Add interface for comparing generations Alex Kost
@ 2014-11-02 17:59 ` Ludovic Courtès
  2014-11-02 22:31   ` Alex Kost
  0 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2014-11-02 17:59 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> In short, now (with this patch) after marking 2 generations (by pressing
> "m" in a “generation-list” buffer), you can perform diff/ediff on
> generation packages or manifests.  Thanks to Ludovic for the idea.

I just tried it, and I like it!

There are cases where the output of ‘=’ is slightly confusing: the
buffers being compared don’t include the directory name of the packages,
so, when packages have been upgraded (different directory names, but
same version), it just says “no differences.”

Perhaps the fix would be to add the directory names in the buffers being
diffed, in a format similar to that of ‘guix package -I’?

I have another case where C-u = shows that the only difference is the
addition of one package, but = shows a diff with only minuses, as if
everything had been removed.  Any idea what could be wrong?

> +++ b/doc/emacs.texi
> @@ -239,6 +239,21 @@ Mark the current generation for deletion (with prefix, mark all
>  generations).
>  @item x
>  Execute actions on the marked generations---i.e., delete generations.
> +@item e
> +Run Ediff (@pxref{Top,,, ediff, Ediff}) on package outputs installed in
> +the 2 marked generations.  With prefix argument, run Ediff on manifests
> +of the marked generations.
> +@item D
> +@itemx =
> +Run Diff (@pxref{Diff Mode,,, emacs, The Emacs Editor}) on package
> +outputs installed in the 2 marked generations.  With prefix argument,
> +run Diff on manifests of the marked generations.
> +@item +
> +List package outputs added to the latest marked generation comparing
> +with another marked generation.
> +@item -
> +List package outputs removed from the latest marked generation comparing
> +with another marked generation.

Likewise, ‘u’ (for ‘upgraded’) could be added (possibly in a future
patch.)

Also, s/The Emacs Editor/GNU Emacs Manual/, which is the real title of
the Emacs manual as it appears in the texi source.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-02 17:59 ` Ludovic Courtès
@ 2014-11-02 22:31   ` Alex Kost
  2014-11-03 22:22     ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Kost @ 2014-11-02 22:31 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 3361 bytes --]

Ludovic Courtès (2014-11-02 20:59 +0300) wrote:

> Alex Kost <alezost@gmail.com> skribis:
>
>> In short, now (with this patch) after marking 2 generations (by pressing
>> "m" in a “generation-list” buffer), you can perform diff/ediff on
>> generation packages or manifests.  Thanks to Ludovic for the idea.
>
> I just tried it, and I like it!
>
> There are cases where the output of ‘=’ is slightly confusing: the
> buffers being compared don’t include the directory name of the packages,
> so, when packages have been upgraded (different directory names, but
> same version), it just says “no differences.”
>
> Perhaps the fix would be to add the directory names in the buffers being
> diffed, in a format similar to that of ‘guix package -I’?

Indeed, I added the store paths, thanks (the modified patch is attached).

> I have another case where C-u = shows that the only difference is the
> addition of one package, but = shows a diff with only minuses, as if
> everything had been removed.  Any idea what could be wrong?

No idea, sorry (unless you manually erased "*Guix <your-profile>:
generation <number>*" buffer).  Make sure that the following works in
Guix REPL:

  (generation-package-specifications "/your/profile" gen-number)

Also, kill "*Guix <your-profile>: generation <number>*" buffer and try
again.

Or maybe: did you experiment with different profiles with the same name?
I mean "/some/path/to/foo-profile" and "/another/path/to/foo-profile".

>> +++ b/doc/emacs.texi
>> @@ -239,6 +239,21 @@ Mark the current generation for deletion (with prefix, mark all
>>  generations).
>>  @item x
>>  Execute actions on the marked generations---i.e., delete generations.
>> +@item e
>> +Run Ediff (@pxref{Top,,, ediff, Ediff}) on package outputs installed in
>> +the 2 marked generations.  With prefix argument, run Ediff on manifests
>> +of the marked generations.
>> +@item D
>> +@itemx =
>> +Run Diff (@pxref{Diff Mode,,, emacs, The Emacs Editor}) on package
>> +outputs installed in the 2 marked generations.  With prefix argument,
>> +run Diff on manifests of the marked generations.
>> +@item +
>> +List package outputs added to the latest marked generation comparing
>> +with another marked generation.
>> +@item -
>> +List package outputs removed from the latest marked generation comparing
>> +with another marked generation.
>
> Likewise, ‘u’ (for ‘upgraded’) could be added (possibly in a future
> patch.)

Probably in the future, as that "upgraded" thing has a different nature
comparing with "added" and "removed".

> Also, s/The Emacs Editor/GNU Emacs Manual/, which is the real title of
> the Emacs manual as it appears in the texi source.

Oh, I thought it should be the title which appears in the info (I mean
the first line in the Top node).

Perhaps "s/The Emacs Editor/The GNU Emacs Manual/"?  As it's the most
common (but not the one) variant in the Emacs Lisp manual, for example here:
<http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/lispref/display.texi#n2065>

Also I used "The Emacs Editor" several times in “emacs.texi”.  Should I
replace all instances in this patch or make a separate commit for that?


Just out of curiosity.  Do you usually prefer "diff" over "ediff"?
(I find the latter much convenient)


[-- Attachment #2: 0001-emacs-Add-interface-for-comparing-generations.patch --]
[-- Type: text/x-diff, Size: 16624 bytes --]

From f63e575bc765c26494baa6bb1ec06f65bb05d007 Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Sun, 2 Nov 2014 13:58:21 +0300
Subject: [PATCH] emacs: Add interface for comparing generations.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Suggested by Ludovic Courtès.

* doc/emacs.texi (Emacs List buffer): Document new key bindings.
* emacs/guix-base.el (guix-generation-packages-buffer-name-function,
  guix-output-path-column): New variables.
  (guix-generation-file, guix-manifest-file, guix-generation-packages,
  guix-generation-packages-buffer-name-default,
  guix-generation-packages-buffer-name-long,
  guix-generation-packages-buffer-name, guix-generation-packages-buffer,
  guix-generation-insert-package, guix-profile-generation-manifest-file,
  guix-profile-generation-packages-buffer): New procedures.
* emacs/guix-list.el: Add key bindings for comparing generations.
  (guix-generation-list-generations-to-compare,
  guix-generation-list-show-added-packages,
  guix-generation-list-show-removed-packages, guix-generation-list-compare,
  guix-generation-list-ediff-manifests, guix-generation-list-diff-manifests,
  guix-generation-list-ediff-packages, guix-generation-list-diff-packages,
  guix-generation-list-ediff, guix-generation-list-diff): New procedures.
* emacs/guix-messages.el (guix-messages): Add 'generation-diff' messages.
* emacs/guix-utils.el (guix-diff-switches): New variable.
  (guix-diff): New procedure.
* emacs/guix-main.scm (package/output-sexps): Handle 'generation-diff' search
  type.
  (manifest-entry->package-specification,
  manifest-entries->package-specifications, generation-package-specifications,
  generation-package-specifications+paths, generation-difference): New
  procedures.
---
 doc/emacs.texi         | 15 +++++++++
 emacs/guix-base.el     | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
 emacs/guix-list.el     | 85 ++++++++++++++++++++++++++++++++++++++++++++++++-
 emacs/guix-main.scm    | 43 +++++++++++++++++++++++--
 emacs/guix-messages.el | 18 ++++++++++-
 emacs/guix-utils.el    | 10 ++++++
 6 files changed, 253 insertions(+), 4 deletions(-)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 17440e4..6459c7a 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -239,6 +239,21 @@ Mark the current generation for deletion (with prefix, mark all
 generations).
 @item x
 Execute actions on the marked generations---i.e., delete generations.
+@item e
+Run Ediff (@pxref{Top,,, ediff, Ediff}) on package outputs installed in
+the 2 marked generations.  With prefix argument, run Ediff on manifests
+of the marked generations.
+@item D
+@itemx =
+Run Diff (@pxref{Diff Mode,,, emacs, GNU Emacs Manual}) on package
+outputs installed in the 2 marked generations.  With prefix argument,
+run Diff on manifests of the marked generations.
+@item +
+List package outputs added to the latest marked generation comparing
+with another marked generation.
+@item -
+List package outputs removed from the latest marked generation comparing
+with another marked generation.
 @end table
 
 @node Emacs Info buffer
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index eb88f37..f16601c 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -650,6 +650,92 @@ This function will not update the information, use
                        guix-search-type guix-search-vals))
 
 \f
+;;; Generations
+
+(defvar guix-generation-packages-buffer-name-function
+  #'guix-generation-packages-buffer-name-default
+  "Function used to define name of a buffer with generation packages.
+This function is called with 2 arguments: PROFILE (string) and
+GENERATION (number).")
+
+(defvar guix-output-path-column 30
+  "Column at which an output path is inserted for comparing generations.")
+
+(defun guix-generation-file (profile generation)
+  "Return the file name of a PROFILE's GENERATION."
+  (format "%s-%s-link" profile generation))
+
+(defun guix-manifest-file (profile &optional generation)
+  "Return the file name of a PROFILE's manifest.
+If GENERATION number is specified, return manifest file name for
+this generation."
+  (expand-file-name "manifest"
+                    (if generation
+                        (guix-generation-file profile generation)
+                      profile)))
+
+(defun guix-generation-packages (profile generation)
+  "Return a list of sorted packages installed in PROFILE's GENERATION.
+Each element of the list is a list of the package specification and its path."
+  (let ((names+paths (guix-eval-read
+                        (guix-make-guile-expression
+                         'generation-package-specifications+paths
+                         profile generation))))
+    (sort names+paths
+          (lambda (a b)
+            (string< (car a) (car b))))))
+
+(defun guix-generation-packages-buffer-name-default (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs.
+Use base name of PROFILE path."
+  (let ((profile-name (file-name-base (directory-file-name profile))))
+    (format "*Guix %s: generation %s*"
+            profile-name generation)))
+
+(defun guix-generation-packages-buffer-name-long (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs.
+Use the full PROFILE path."
+  (format "*Guix generation %s (%s)*"
+          generation profile))
+
+(defun guix-generation-packages-buffer-name (profile generation)
+  "Return name of a buffer for displaying GENERATION's package outputs."
+  (let ((fun (if (functionp guix-generation-packages-buffer-name-function)
+                 guix-generation-packages-buffer-name-function
+               #'guix-generation-packages-buffer-name-default)))
+    (funcall fun profile generation)))
+
+(defun guix-generation-insert-package (name path)
+  "Insert package output NAME and PATH at point."
+  (insert name)
+  (indent-to guix-output-path-column 2)
+  (insert path "\n"))
+
+(defun guix-generation-packages-buffer (profile generation)
+  "Return buffer with package outputs installed in PROFILE's GENERATION.
+Create the buffer if needed."
+  (let ((buf-name (guix-generation-packages-buffer-name
+                   profile generation)))
+    (or (get-buffer buf-name)
+        (let ((buf (get-buffer-create buf-name)))
+          (with-current-buffer buf
+            (mapc (lambda (name+path)
+                    (guix-generation-insert-package
+                     (car name+path) (cadr name+path)))
+                  (guix-generation-packages profile generation)))
+          buf))))
+
+(defun guix-profile-generation-manifest-file (generation)
+  "Return the file name of a GENERATION's manifest.
+GENERATION is a generation number of `guix-profile' profile."
+  (guix-manifest-file guix-profile generation))
+
+(defun guix-profile-generation-packages-buffer (generation)
+  "Insert GENERATION's package outputs in a buffer and return it.
+GENERATION is a generation number of `guix-profile' profile."
+  (guix-generation-packages-buffer guix-profile generation))
+
+\f
 ;;; Actions on packages and generations
 
 (defface guix-operation-option-key
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index 58c03b3..600f2bd 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -27,7 +27,6 @@
 (require 'cl-lib)
 (require 'tabulated-list)
 (require 'guix-info)
-(require 'guix-history)
 (require 'guix-base)
 (require 'guix-utils)
 
@@ -735,6 +734,11 @@ Also see `guix-package-info-type'."
 
 (let ((map guix-generation-list-mode-map))
   (define-key map (kbd "RET") 'guix-generation-list-show-packages)
+  (define-key map (kbd "+")   'guix-generation-list-show-added-packages)
+  (define-key map (kbd "-")   'guix-generation-list-show-removed-packages)
+  (define-key map (kbd "=")   'guix-generation-list-diff)
+  (define-key map (kbd "D")   'guix-generation-list-diff)
+  (define-key map (kbd "e")   'guix-generation-list-ediff)
   (define-key map (kbd "x")   'guix-generation-list-execute)
   (define-key map (kbd "i")   'guix-list-describe)
   (define-key map (kbd "s")   'guix-generation-list-switch)
@@ -761,6 +765,85 @@ VAL is a boolean value."
   (guix-get-show-entries guix-profile 'list guix-package-list-type
                          'generation (guix-list-current-id)))
 
+(defun guix-generation-list-generations-to-compare ()
+  "Return a sorted list of 2 marked generations for comparing."
+  (let ((numbers (guix-list-get-marked-id-list 'general)))
+    (if (/= (length numbers) 2)
+        (user-error "2 generations should be marked for comparing")
+      (sort numbers #'<))))
+
+(defun guix-generation-list-show-added-packages ()
+  "List package outputs added to the latest marked generation.
+If 2 generations are marked with \\[guix-list-mark], display
+outputs installed in the latest marked generation that were not
+installed in the other one."
+  (interactive)
+  (apply #'guix-get-show-entries
+         guix-profile 'list 'output 'generation-diff
+         (reverse (guix-generation-list-generations-to-compare))))
+
+(defun guix-generation-list-show-removed-packages ()
+  "List package outputs removed from the latest marked generation.
+If 2 generations are marked with \\[guix-list-mark], display
+outputs not installed in the latest marked generation that were
+installed in the other one."
+  (interactive)
+  (apply #'guix-get-show-entries
+         guix-profile 'list 'output 'generation-diff
+         (guix-generation-list-generations-to-compare)))
+
+(defun guix-generation-list-compare (diff-fun gen-fun)
+  "Run GEN-FUN on the 2 marked generations and run DIFF-FUN on the results."
+  (cl-multiple-value-bind (gen1 gen2)
+      (guix-generation-list-generations-to-compare)
+    (funcall diff-fun
+             (funcall gen-fun gen1)
+             (funcall gen-fun gen2))))
+
+(defun guix-generation-list-ediff-manifests ()
+  "Run Ediff on manifests of the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'ediff-files
+   #'guix-profile-generation-manifest-file))
+
+(defun guix-generation-list-diff-manifests ()
+  "Run Diff on manifests of the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'guix-diff
+   #'guix-profile-generation-manifest-file))
+
+(defun guix-generation-list-ediff-packages ()
+  "Run Ediff on package outputs installed in the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'ediff-buffers
+   #'guix-profile-generation-packages-buffer))
+
+(defun guix-generation-list-diff-packages ()
+  "Run Diff on package outputs installed in the 2 marked generations."
+  (interactive)
+  (guix-generation-list-compare
+   #'guix-diff
+   #'guix-profile-generation-packages-buffer))
+
+(defun guix-generation-list-ediff (arg)
+  "Run Ediff on package outputs installed in the 2 marked generations.
+With ARG, run Ediff on manifests of the marked generations."
+  (interactive "P")
+  (if arg
+      (guix-generation-list-ediff-manifests)
+    (guix-generation-list-ediff-packages)))
+
+(defun guix-generation-list-diff (arg)
+  "Run Diff on package outputs installed in the 2 marked generations.
+With ARG, run Diff on manifests of the marked generations."
+  (interactive "P")
+  (if arg
+      (guix-generation-list-diff-manifests)
+    (guix-generation-list-diff-packages)))
+
 (defun guix-generation-list-mark-delete (&optional arg)
   "Mark the current generation for deletion and move to the next line.
 With ARG, mark all generations for deletion."
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index 1dd57bb..62eeabb 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -106,6 +106,38 @@
    (manifest-entry-version entry)
    (manifest-entry-output  entry)))
 
+(define (manifest-entry->package-specification entry)
+  (call-with-values
+      (lambda () (manifest-entry->name+version+output entry))
+    make-package-specification))
+
+(define (manifest-entries->package-specifications entries)
+  (map manifest-entry->package-specification entries))
+
+(define (generation-package-specifications profile number)
+  "Return a list of package specifications for generation NUMBER."
+  (let ((manifest (profile-manifest
+                   (generation-file-name profile number))))
+    (manifest-entries->package-specifications
+     (manifest-entries manifest))))
+
+(define (generation-package-specifications+paths profile number)
+  "Return a list of package specifications and paths for generation NUMBER.
+Each element of the list is a list of the package specification and its path."
+  (let ((manifest (profile-manifest
+                   (generation-file-name profile number))))
+    (map (lambda (entry)
+           (list (manifest-entry->package-specification entry)
+                 (manifest-entry-item entry)))
+         (manifest-entries manifest))))
+
+(define (generation-difference profile number1 number2)
+  "Return a list of package specifications for outputs installed in generation
+NUMBER1 and not installed in generation NUMBER2."
+  (let ((specs1 (generation-package-specifications profile number1))
+        (specs2 (generation-package-specifications profile number2)))
+    (lset-difference string=? specs1 specs2)))
+
 (define (manifest-entries->hash-table entries)
   "Return a hash table of name keys and lists of matching manifest ENTRIES."
   (let ((table (make-hash-table (length entries))))
@@ -625,8 +657,15 @@ See 'entry-sexps' for details."
                       (generation-file-name profile (car search-vals))
                       profile))
          (manifest (profile-manifest profile))
-         (patterns (apply (patterns-maker entry-type search-type)
-                          manifest search-vals))
+         (patterns (if (and (eq? entry-type 'output)
+                            (eq? search-type 'generation-diff))
+                       (match search-vals
+                         ((g1 g2)
+                          (map specification->output-pattern
+                               (generation-difference profile g1 g2)))
+                         (_ '()))
+                       (apply (patterns-maker entry-type search-type)
+                              manifest search-vals)))
          (->sexps ((pattern-transformer entry-type) manifest params)))
     (append-map ->sexps patterns)))
 
diff --git a/emacs/guix-messages.el b/emacs/guix-messages.el
index c77b5c0..09556be 100644
--- a/emacs/guix-messages.el
+++ b/emacs/guix-messages.el
@@ -101,7 +101,23 @@
       (1 "A single package output installed in generation %d of profile '%s'."
          val profile)
       (many "%d package outputs installed in generation %d of profile '%s'."
-            count val profile)))
+            count val profile))
+     (generation-diff
+      (0 ,(lambda (profile entries vals)
+            (message
+             (concat "No additional packages in generation %d "
+                     "comparing with generation %d of profile '%s'.")
+             (car vals) (cadr vals) profile)))
+      (1 ,(lambda (profile entries vals)
+            (message
+             (concat "A single additional package output in generation %d "
+                     "comparing with generation %d of profile '%s'.")
+             (car vals) (cadr vals) profile)))
+      (many ,(lambda (profile entries vals)
+               (message
+                (concat "%d additional package outputs in generation %d "
+                        "comparing with generation %d of profile '%s'.")
+                (length entries) (car vals) (cadr vals) profile)))))
 
     (generation
      (id
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
index 8787814..77ccb67 100644
--- a/emacs/guix-utils.el
+++ b/emacs/guix-utils.el
@@ -154,6 +154,16 @@ accessed with KEYS."
     (dolist (key keys val)
       (setq val (cdr (assq key val))))))
 
+\f
+;;; Diff
+
+(defvar guix-diff-switches "-u"
+  "A string or list of strings specifying switches to be passed to diff.")
+
+(defun guix-diff (old new &optional switches no-async)
+  "Same as `diff', but use `guix-diff-switches' as default."
+  (diff old new (or switches guix-diff-switches) no-async))
+
 (provide 'guix-utils)
 
 ;;; guix-utils.el ends here
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-02 22:31   ` Alex Kost
@ 2014-11-03 22:22     ` Ludovic Courtès
  2014-11-04  7:30       ` Alex Kost
  0 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2014-11-03 22:22 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> Ludovic Courtès (2014-11-02 20:59 +0300) wrote:
>
>> Alex Kost <alezost@gmail.com> skribis:
>>
>>> In short, now (with this patch) after marking 2 generations (by pressing
>>> "m" in a “generation-list” buffer), you can perform diff/ediff on
>>> generation packages or manifests.  Thanks to Ludovic for the idea.
>>
>> I just tried it, and I like it!
>>
>> There are cases where the output of ‘=’ is slightly confusing: the
>> buffers being compared don’t include the directory name of the packages,
>> so, when packages have been upgraded (different directory names, but
>> same version), it just says “no differences.”
>>
>> Perhaps the fix would be to add the directory names in the buffers being
>> diffed, in a format similar to that of ‘guix package -I’?
>
> Indeed, I added the store paths, thanks (the modified patch is attached).

Nice!

>> I have another case where C-u = shows that the only difference is the
>> addition of one package, but = shows a diff with only minuses, as if
>> everything had been removed.  Any idea what could be wrong?

I can’t seem to reproduce that problem.  I must have messed things up
before, sorry for the noise.

>> Also, s/The Emacs Editor/GNU Emacs Manual/, which is the real title of
>> the Emacs manual as it appears in the texi source.
>
> Oh, I thought it should be the title which appears in the info (I mean
> the first line in the Top node).
>
> Perhaps "s/The Emacs Editor/The GNU Emacs Manual/"?  As it's the most
> common (but not the one) variant in the Emacs Lisp manual, for example here:
> <http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/lispref/display.texi#n2065>

OK (I think they should add “The” in emacs.texi.)

> Also I used "The Emacs Editor" several times in “emacs.texi”.  Should I
> replace all instances in this patch or make a separate commit for that?

Yes, please.

> Just out of curiosity.  Do you usually prefer "diff" over "ediff"?
> (I find the latter much convenient)

The default behavior for ediff is to create another frame for control,
and that doesn’t work well with the tiling window manager I’m using.
Also, it’s really a mode that you enter and have to leave afterwards.
So I tend to prefer diff for simple diffs, and I resort to ediff in more
tricky situations (like when I have to compare two .drv files for
debugging, uh! ;-)).

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-03 22:22     ` Ludovic Courtès
@ 2014-11-04  7:30       ` Alex Kost
  2014-11-04  9:50         ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Kost @ 2014-11-04  7:30 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1711 bytes --]

Ludovic Courtès (2014-11-04 01:22 +0300) wrote:

> Alex Kost <alezost@gmail.com> skribis:

[...]

>> Perhaps "s/The Emacs Editor/The GNU Emacs Manual/"?  As it's the most
>> common (but not the one) variant in the Emacs Lisp manual, for example here:
>> <http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/lispref/display.texi#n2065>
>
> OK (I think they should add “The” in emacs.texi.)
>
>> Also I used "The Emacs Editor" several times in “emacs.texi”.  Should I
>> replace all instances in this patch or make a separate commit for that?
>
> Yes, please.

Sorry, yes for «replace all instances in this patch» or for «make a
separate commit»?  I think the latter, so I've attached a patch for
that.  OK to commit?

>> Just out of curiosity.  Do you usually prefer "diff" over "ediff"?
>> (I find the latter much convenient)
>
> The default behavior for ediff is to create another frame for control,
> and that doesn’t work well with the tiling window manager I’m using.
> Also, it’s really a mode that you enter and have to leave afterwards.
> So I tend to prefer diff for simple diffs, and I resort to ediff in more
> tricky situations (like when I have to compare two .drv files for
> debugging, uh! ;-)).

Oh, indeed; I forgot about the defaults.  Yeah, additional frame and
vertical splitting are evil :-)  So I use the following settings:

  (setq
   ediff-window-setup-function #'ediff-setup-windows-plain ; no new frame
   ediff-split-window-function #'split-window-horizontally
   ediff-grab-mouse nil)

But the most unpleasant default behaviour for me is that Ediff doesn't
restore the previous window configuration.  To "fix" it, I use:


[-- Attachment #2: ediff-tmp.el --]
[-- Type: application/emacs-lisp, Size: 582 bytes --]

[-- Attachment #3: Type: text/plain, Size: 174 bytes --]


Sorry for being verbose on an unrelated topic, but maybe someone who
will read it, find it useful (I also recommend to look at
<http://www.emacswiki.org/emacs/EdiffMode>).


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0001-doc-emacs-Fix-titles-of-the-printed-manuals.patch --]
[-- Type: text/x-diff, Size: 3879 bytes --]

From ae8f292fba3fee0b89a877a7ad61045d2bc91e2c Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Tue, 4 Nov 2014 10:20:41 +0300
Subject: [PATCH] doc: emacs: Fix titles of the printed manuals.

* doc/emacs.texi: Use the proper names of the printed manuals in the
  cross references.
---
 doc/emacs.texi | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 1b134d7..1d7711a 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -38,7 +38,7 @@ used for interacting with the Guile process.
 @end itemize
 
 When it is done, add the following into your init file (@pxref{Init
-File,,, emacs, The Emacs Editor}):
+File,,, emacs, The GNU Emacs Manual}):
 
 @example
 (require 'guix-init nil t)
@@ -47,7 +47,8 @@ File,,, emacs, The Emacs Editor}):
 However there is a chance that @code{load-path} of your Emacs does not
 contain a directory with ``guix.el'' (usually it is
 @file{/usr/share/emacs/site-lisp/}).  In that case you need to add it
-before requiring (@pxref{Lisp Libraries,,, emacs, The Emacs Editor}):
+before requiring (@pxref{Lisp Libraries,,, emacs, The GNU Emacs
+Manual}):
 
 @example
 (add-to-list 'load-path "/path/to/directory-with-guix.el")
@@ -56,7 +57,8 @@ before requiring (@pxref{Lisp Libraries,,, emacs, The Emacs Editor}):
 
 Do not worry about the efficiency of that @code{require} thing.  It will
 not load the whole ``guix.el'' package, it will just autoload the main
-interactive commands (@pxref{Autoload,,, elisp, Emacs Lisp}).
+interactive commands (@pxref{Autoload,,, elisp, The Emacs Lisp Reference
+Manual}).
 
 
 @node Emacs Usage
@@ -129,7 +131,7 @@ of generations.
 @item M-x guix-generations-by-time
 List generations matching time period.  You will be prompted for the
 period using Org mode time prompt based on Emacs calendar (@pxref{The
-date/time prompt,,, org, Org Mode Manual}).
+date/time prompt,,, org, The Org Manual}).
 
 @end table
 
@@ -187,7 +189,7 @@ was restarted, you may want to revert ``list'' buffer (by pressing
 @subsubsection ``List'' buffer
 
 An interface of a ``list'' buffer is similar to the interface provided
-by ``package.el'' (@pxref{Package Menu,,, emacs, The Emacs Editor}).
+by ``package.el'' (@pxref{Package Menu,,, emacs, The GNU Emacs Manual}).
 
 Default key bindings available for both ``package-list'' and
 ``generation-list'' buffers:
@@ -260,11 +262,11 @@ with another marked generation.
 @subsubsection ``Info'' buffer
 
 The interface of an ``info'' buffer is similar to the interface of
-@code{help-mode} (@pxref{Help Mode,,, emacs, The Emacs Editor}).
+@code{help-mode} (@pxref{Help Mode,,, emacs, The GNU Emacs Manual}).
 
 ``Info'' buffer contains some buttons (as usual you may use @key{TAB} /
 @kbd{S-@key{TAB}} to move between buttons---@pxref{Mouse References,,,
-emacs, The Emacs Editor}) which can be used to:
+emacs, The GNU Emacs Manual}) which can be used to:
 
 @itemize @bullet
 @item (in a ``package-info'' buffer)
@@ -294,8 +296,8 @@ emacs, The Emacs Editor}) which can be used to:
 There are many variables you can modify to change the appearance or
 behavior of Emacs user interface.  Some of these variables are described
 in this section.  Also you can use Custom Interface (@pxref{Easy
-Customization,,, emacs, The Emacs Editor}) to explore/set variables (not
-all) and faces.
+Customization,,, emacs, The GNU Emacs Manual}) to explore/set variables
+(not all) and faces.
 
 @menu
 * Guile and Build Options: Emacs Build Options.	Specifying how packages are built.
@@ -367,7 +369,7 @@ extensively), you may do it like this:
 @subsubsection Keymaps
 
 If you want to change default key bindings, use the following keymaps
-(@pxref{Init Rebinding,,, emacs, The Emacs Editor}):
+(@pxref{Init Rebinding,,, emacs, The GNU Emacs Manual}):
 
 @table @code
 @item guix-list-mode-map
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-04  7:30       ` Alex Kost
@ 2014-11-04  9:50         ` Ludovic Courtès
  2014-11-04 12:52           ` Alex Kost
  0 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2014-11-04  9:50 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> Ludovic Courtès (2014-11-04 01:22 +0300) wrote:
>
>> Alex Kost <alezost@gmail.com> skribis:
>
> [...]
>
>>> Perhaps "s/The Emacs Editor/The GNU Emacs Manual/"?  As it's the most
>>> common (but not the one) variant in the Emacs Lisp manual, for example here:
>>> <http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/lispref/display.texi#n2065>
>>
>> OK (I think they should add “The” in emacs.texi.)
>>
>>> Also I used "The Emacs Editor" several times in “emacs.texi”.  Should I
>>> replace all instances in this patch or make a separate commit for that?
>>
>> Yes, please.
>
> Sorry, yes for «replace all instances in this patch» or for «make a
> separate commit»?  I think the latter, so I've attached a patch for
> that.

Yes, I meant the latter; sorry for the confusion.

>> The default behavior for ediff is to create another frame for control,
>> and that doesn’t work well with the tiling window manager I’m using.
>> Also, it’s really a mode that you enter and have to leave afterwards.
>> So I tend to prefer diff for simple diffs, and I resort to ediff in more
>> tricky situations (like when I have to compare two .drv files for
>> debugging, uh! ;-)).
>
> Oh, indeed; I forgot about the defaults.  Yeah, additional frame and
> vertical splitting are evil :-)  So I use the following settings:

Thanks for the tips!

>  Do not worry about the efficiency of that @code{require} thing.  It will
>  not load the whole ``guix.el'' package, it will just autoload the main
> -interactive commands (@pxref{Autoload,,, elisp, Emacs Lisp}).
> +interactive commands (@pxref{Autoload,,, elisp, The Emacs Lisp Reference
> +Manual}).

lispref.texi has:

  @settitle GNU Emacs Lisp Reference Manual

So make it “The GNU Emacs Lisp Reference Manual” (or without “The”, as
you prefer.)

OK to commit with this change!

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-04  9:50         ` Ludovic Courtès
@ 2014-11-04 12:52           ` Alex Kost
  2014-11-04 16:50             ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Kost @ 2014-11-04 12:52 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Ludovic Courtès (2014-11-04 12:50 +0300) wrote:

> Alex Kost <alezost@gmail.com> skribis:

[...]

>>  Do not worry about the efficiency of that @code{require} thing.  It will
>>  not load the whole ``guix.el'' package, it will just autoload the main
>> -interactive commands (@pxref{Autoload,,, elisp, Emacs Lisp}).
>> +interactive commands (@pxref{Autoload,,, elisp, The Emacs Lisp Reference
>> +Manual}).
>
> lispref.texi has:
>
>   @settitle GNU Emacs Lisp Reference Manual
>
> So make it “The GNU Emacs Lisp Reference Manual” (or without “The”, as
> you prefer.)

And again, *.texi files from
<http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/emacs> have several
dozens of "The Emacs Lisp Reference Manual" references and only a couple
of "(The) GNU Emacs Lisp Reference Manual".  Does it really matter so
much?

> OK to commit with this change!

Anyway, I have changed it to "The GNU Emacs Lisp Reference Manual" and
commited, thanks.

-- 
Alex

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] emacs: Add interface for comparing generations.
  2014-11-04 12:52           ` Alex Kost
@ 2014-11-04 16:50             ` Ludovic Courtès
  0 siblings, 0 replies; 8+ messages in thread
From: Ludovic Courtès @ 2014-11-04 16:50 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> Ludovic Courtès (2014-11-04 12:50 +0300) wrote:
>
>> Alex Kost <alezost@gmail.com> skribis:
>
> [...]
>
>>>  Do not worry about the efficiency of that @code{require} thing.  It will
>>>  not load the whole ``guix.el'' package, it will just autoload the main
>>> -interactive commands (@pxref{Autoload,,, elisp, Emacs Lisp}).
>>> +interactive commands (@pxref{Autoload,,, elisp, The Emacs Lisp Reference
>>> +Manual}).
>>
>> lispref.texi has:
>>
>>   @settitle GNU Emacs Lisp Reference Manual
>>
>> So make it “The GNU Emacs Lisp Reference Manual” (or without “The”, as
>> you prefer.)
>
> And again, *.texi files from
> <http://git.savannah.gnu.org/cgit/emacs.git/tree/doc/emacs> have several
> dozens of "The Emacs Lisp Reference Manual" references and only a couple
> of "(The) GNU Emacs Lisp Reference Manual".  Does it really matter so
> much?

No, probably not.  :-)

I usually look at @settitle, but apparently it’s not always the “real
title” that’s in there.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-11-04 16:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-02 11:21 [PATCH 2/2] emacs: Add interface for comparing generations Alex Kost
2014-11-02 17:59 ` Ludovic Courtès
2014-11-02 22:31   ` Alex Kost
2014-11-03 22:22     ` Ludovic Courtès
2014-11-04  7:30       ` Alex Kost
2014-11-04  9:50         ` Ludovic Courtès
2014-11-04 12:52           ` Alex Kost
2014-11-04 16:50             ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).