Ludovic Courtès (2014-10-12 01:57 +0400) wrote:

> Alex Kost <alez...@gmail.com> skribis:
>
>> OK, I have not pushed anything yet, as the commits were changed a bit.
>> I'm attaching all 3 patches for adding “Switch to generation” support.
>> Everything seems OK now (at least “make check” does not fail anymore),
>> so if you don't have final comments, I would like to commit them.
>> Thanks for the patience.
>
> Looks good from a quick skim, go ahead!

Thanks, pushed.  Now I would like to add support for switching
generations from Emacs UI.  The patches for that are attached.

Currently there is no way to see what generation is the current one –
the first patch will fix it (additional column is added to *Guix
Generation List*).

>From 67089dfee7d212863ad18204bd1ec1b51e0f29db Mon Sep 17 00:00:00 2001
From: Alex Kost <alez...@gmail.com>
Date: Fri, 10 Oct 2014 23:50:15 +0400
Subject: [PATCH 1/2] emacs: Add 'current' generation parameter.

* emacs/guix-main.scm (generation-param-alist): Add 'current' parameter.
* emacs/guix-base.el (guix-param-titles): Add title for 'current' parameter.
* emacs/guix-info.el: Display 'current' parameter.
  (guix-generation-info-current, guix-generation-info-not-current): New faces.
  (guix-generation-info-insert-current): New procedure.
* emacs/guix-list.el: Display 'current' column.
  (guix-generation-list-get-current): New procedure.
---
 emacs/guix-base.el  |  1 +
 emacs/guix-info.el  | 19 ++++++++++++++++++-
 emacs/guix-list.el  | 11 +++++++++--
 emacs/guix-main.scm | 15 ++++++++-------
 4 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index d31fb79..aafa220 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -107,6 +107,7 @@ Interactively, prompt for PATH.  With prefix, use
      (id                . "ID")
      (number            . "Number")
      (prev-number       . "Previous number")
+     (current           . "Current")
      (path              . "Path")
      (time              . "Time")))
   "List for defining titles of entry parameters.
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
index d5226b1..fc1b585 100644
--- a/emacs/guix-info.el
+++ b/emacs/guix-info.el
@@ -136,6 +136,7 @@ number of characters, it will be split into several lines.")
      (location          guix-package-info-insert-location))
     (generation
      (number            guix-generation-info-insert-number)
+     (current           guix-generation-info-insert-current)
      (path              guix-info-insert-file-path)
      (time              guix-info-insert-time)))
   "Methods for inserting parameter values.
@@ -161,7 +162,7 @@ argument.")
     (output name version output synopsis path dependencies location home-url
             license inputs native-inputs propagated-inputs description)
     (installed path dependencies)
-    (generation number prev-number time path))
+    (generation number prev-number current time path))
   "List of displayed entry parameters.
 Each element of the list should have a form:
 
@@ -613,6 +614,16 @@ ENTRY is an alist with package info."
   "Face used for a number of a generation."
   :group 'guix-generation-info)
 
+(defface guix-generation-info-current
+  '((t :inherit guix-package-info-installed-outputs))
+  "Face used if a generation is the current one."
+  :group 'guix-generation-info)
+
+(defface guix-generation-info-not-current
+  '((t nil))
+  "Face used if a generation is not the current one."
+  :group 'guix-generation-info)
+
 (defun guix-generation-info-insert-number (number &optional _)
   "Insert generation NUMBER and action buttons."
   (guix-info-insert-val-default number 'guix-generation-info-number)
@@ -632,6 +643,12 @@ ENTRY is an alist with package info."
    "Delete this generation"
    'number number))
 
+(defun guix-generation-info-insert-current (val entry)
+  "Insert boolean value VAL showing whether this generation is current."
+  (if val
+      (guix-info-insert-val-default "Yes" 'guix-generation-info-current)
+    (guix-info-insert-val-default "No" 'guix-generation-info-not-current)))
+
 (provide 'guix-info)
 
 ;;; guix-info.el ends here
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index 9cc381b..f9d106b 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -65,6 +65,7 @@ entries, he will be prompted for confirmation."
      (number 5
              ,(lambda (a b) (guix-list-sort-numerically 0 a b))
              :right-align t)
+     (current 10 t)
      (time 20 t)
      (path 30 t)))
   "Columns displayed in list buffers.
@@ -93,8 +94,9 @@ this list have a priority.")
      (synopsis    . guix-list-get-one-line)
      (description . guix-list-get-one-line))
     (generation
-     (time . guix-list-get-time)
-     (path . guix-list-get-file-path)))
+     (current     . guix-generation-list-get-current)
+     (time        . guix-list-get-time)
+     (path        . guix-list-get-file-path)))
   "Methods for inserting parameter values in columns.
 Each element of the list has a form:
 
@@ -735,6 +737,11 @@ Also see `guix-package-info-type'."
   (define-key map (kbd "i")   'guix-list-describe)
   (define-key map (kbd "d")   'guix-generation-list-mark-delete))
 
+(defun guix-generation-list-get-current (val &optional _)
+  "Return string from VAL showing whether this generation is current.
+VAL is a boolean value."
+  (if val "(current)" ""))
+
 (defun guix-generation-list-show-packages ()
   "List installed packages for the generation at point."
   (interactive)
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index fe599fb..7e26876 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -638,13 +638,14 @@ See 'entry-sexps' for details."
 
 (define (generation-param-alist profile)
   "Return an alist of generation parameters and procedures for PROFILE."
-  (list
-   (cons 'id          identity)
-   (cons 'number      identity)
-   (cons 'prev-number (cut previous-generation-number profile <>))
-   (cons 'path        (cut generation-file-name profile <>))
-   (cons 'time        (lambda (gen)
-                        (time-second (generation-time profile gen))))))
+  (let ((current (generation-number profile)))
+    `((id          . ,identity)
+      (number      . ,identity)
+      (prev-number . ,(cut previous-generation-number profile <>))
+      (current     . ,(cut = current <>))
+      (path        . ,(cut generation-file-name profile <>))
+      (time        . ,(lambda (gen)
+                        (time-second (generation-time profile gen)))))))
 
 (define (matching-generations profile predicate)
   "Return a list of PROFILE generations matching PREDICATE."
-- 
2.1.2

>From 20d423b27381c562cc87fca4438832208f43f24f Mon Sep 17 00:00:00 2001
From: Alex Kost <alez...@gmail.com>
Date: Fri, 10 Oct 2014 23:58:30 +0400
Subject: [PATCH 2/2] emacs: Add support for switching generations.

* emacs/guix-base.el (guix-switch-to-generation): New procedure.
* emacs/guix-info.el (guix-generation-info-insert-current): Insert button for
  switching to generation.
* emacs/guix-list.el (guix-generation-list-switch): New procedure.
* doc/emacs.texi (emacs List buffer, emacs Info buffer): Document switching
  generations.
---
 doc/emacs.texi     |  3 +++
 emacs/guix-base.el |  9 +++++++++
 emacs/guix-info.el |  9 ++++++++-
 emacs/guix-list.el | 11 +++++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 2e6b60e..01a5712 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -205,6 +205,8 @@ List packages installed in the current generation.
 @item i
 Describe marked generations (display available information in a
 ``generation-info'' buffer).
+@item s
+Switch profile to the current generation.
 @item d
 Mark the current generation for deletion (with prefix, mark all
 generations).
@@ -236,6 +238,7 @@ emacs, The Emacs Editor}) which can be used to:
 
 @itemize @minus
 @item remove a generation;
+@item switch to a generation;
 @item list packages installed in a generation;
 @item jump to a generation directory.
 @end itemize
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index aafa220..5131eb0 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -816,6 +816,15 @@ Each element from GENERATIONS is a generation number."
      (guix-make-guile-expression
       'delete-generations* guix-current-profile generations))))
 
+(defun guix-switch-to-generation (generation)
+  "Switch `guix-current-profile' to GENERATION number."
+  (when (or (not guix-operation-confirm)
+            (y-or-n-p (format "Switch current profile to generation %d? "
+                              generation)))
+    (guix-eval-in-repl
+     (guix-make-guile-expression
+      'switch-to-generation guix-current-profile generation))))
+
 (provide 'guix-base)
 
 ;;; guix-base.el ends here
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
index fc1b585..7a60090 100644
--- a/emacs/guix-info.el
+++ b/emacs/guix-info.el
@@ -647,7 +647,14 @@ ENTRY is an alist with package info."
   "Insert boolean value VAL showing whether this generation is current."
   (if val
       (guix-info-insert-val-default "Yes" 'guix-generation-info-current)
-    (guix-info-insert-val-default "No" 'guix-generation-info-not-current)))
+    (guix-info-insert-val-default "No" 'guix-generation-info-not-current)
+    (guix-info-insert-indent)
+    (guix-info-insert-action-button
+     "Switch"
+     (lambda (btn)
+       (guix-switch-to-generation (button-get btn 'number)))
+     "Switch to this generation (make it the current one)"
+     'number (guix-get-key-val entry 'number))))
 
 (provide 'guix-info)
 
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index f9d106b..c3e8ef4 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -735,6 +735,7 @@ Also see `guix-package-info-type'."
   (define-key map (kbd "RET") 'guix-generation-list-show-packages)
   (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)
   (define-key map (kbd "d")   'guix-generation-list-mark-delete))
 
 (defun guix-generation-list-get-current (val &optional _)
@@ -742,6 +743,16 @@ Also see `guix-package-info-type'."
 VAL is a boolean value."
   (if val "(current)" ""))
 
+(defun guix-generation-list-switch ()
+  "Switch current profile to the generation at point."
+  (interactive)
+  (let* ((entry   (guix-list-current-entry))
+         (current (guix-get-key-val entry 'current))
+         (number  (guix-get-key-val entry 'number)))
+    (if current
+        (user-error "This generation is already the current one")
+      (guix-switch-to-generation number))))
+
 (defun guix-generation-list-show-packages ()
   "List installed packages for the generation at point."
   (interactive)
-- 
2.1.2

Reply via email to