Ludovic Courtès (2014-10-05 00:23 +0400) wrote:

> Hi!
>
> Alex Kost <alez...@gmail.com> skribis:
>
>> What about the attached patch?  Some comments and questions:
>>
>> - I added 'store' argument to the exported procedures, however it is
>>   used only in one particular case: when we need to create an empty
>>   profile (i.e. to call ‘link-to-empty-profile’).  Is there a way to
>>   avoid using 'store' argument there or is it fine to leave it like
>>   this?
>
> For now it’s fine to leave it like this, with the ‘store’ argument.
> Eventually it should be changed to use the monadic style, though.

I read the info manual about gexps and monads.  However I don't really
understand how to use monadic style here, sorry.

>> - I actually need only ‘delete-generations’ procedure for Emacs UI, but
>>   I think other procedures are also worth to be exported or not?
>
> Yes, sure.

Thanks.

>> - Perhaps there is a better place for those functions than
>>   (guix scripts package)?
>
> Yes, (guix profiles) would be a better place IMO.

OK.

>> - (Not related to this patch, but still …)  Currently with “roll-back”,
>>   we can only switch to the previous generation.  What about adding a
>>   possibility to switch to any generation?  So that we could use
>>   something like this:
>>
>>     guix package --switch-generation=7
>>
>>   Also such functionality can be added to Emacs UI: for example pressing
>>   "C" on a generation in *Guix Generation List* will make this
>>   generation the current one.
>>
>>   So ‘roll-back’ procedure may become a special case of the
>>   ‘switch-generation’ one.  WDYT?
>
> I think it’s a good idea!  (I think it was suggested in earlier
> discussions, but never implemented.)

Great, I think I can make it, but without monads :-(

>> From c50d1674d3be699198afb649a2a9932ca44c89bc Mon Sep 17 00:00:00 2001
>> From: Alex Kost <alez...@gmail.com>
>> Date: Sat, 4 Oct 2014 20:45:35 +0400
>> Subject: [PATCH] guix package: Export generation procedures.
>>
>> * guix/scripts/package.scm: Export 'roll-back', 'delete-generation',
>>   'delete-generations'.
>>   (link-to-empty-profile, roll-back): Add 'store' argument.
>>   (delete-generations): New procedure.
>>   (guix-package): Adjust accordingly.
>>   [delete-generation]: Move to the top level.  Add 'store' and 'profile'
>>   arguments.
>>   [display-and-delete]: Move to 'delete-generation'.
>
> OK to commit.
>
> To sum up, I would imagine two followups to this:
>
>   1. Move these procedures to (guix profiles).
>   2. Convert them to monadic style.
>
> WDYT?

I like the idea of using monads there, but as I said I'm too week (I
mean "month" (I mean "weak")) for writing that.

Also those followups would make my commit totally redundant, no?
Wouldn't it be better to make a commit for adding the monadic functions
to (guix profiles) directly?

However if you still allow me to push this commit, I think I can also
push the attached one with the changes for Emacs UI now (if it looks OK
for you).

>From c335cdf17a97d07cc3d4149fa7dc13882d16cc87 Mon Sep 17 00:00:00 2001
From: Alex Kost <alez...@gmail.com>
Date: Sun, 5 Oct 2014 12:31:23 +0400
Subject: [PATCH] emacs: Add support for deleting generations.

* doc/emacs.texi (emacs List buffer): Mention new key bindings.
* emacs/guix-base.el (guix-delete-generations): New procedure.
* emacs/guix-info.el (guix-generation-info-insert-number): Use it.
* emacs/guix-list.el (guix-generation-list-mark-delete,
  guix-generation-list-execute): New procedures.
* emacs/guix-main.scm (delete-generations*): New procedure.
---
 doc/emacs.texi      |  5 +++++
 emacs/guix-base.el  | 14 ++++++++++++++
 emacs/guix-info.el  |  6 ++++--
 emacs/guix-list.el  | 19 ++++++++++++++++++-
 emacs/guix-main.scm |  6 ++++++
 5 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 3c5698f..4176f2e 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -205,6 +205,11 @@ List packages installed in the current generation.
 @item i
 Describe marked generations (display available information in a
 ``generation-info'' buffer).
+@item d
+Mark the current generation for deletion (with prefix, mark all
+generations).
+@item x
+Execute actions on the marked generations (i.e.@: delete generations).
 @end table
 
 @node emacs Info buffer
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index 8da7835..d31fb79 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -801,6 +801,20 @@ Return non-nil, if the operation should be continued; nil otherwise."
                  guix-operation-option-separator)))
   (force-mode-line-update))
 
+(defun guix-delete-generations (&rest generations)
+  "Delete GENERATIONS.
+Each element from GENERATIONS is a generation number."
+  (when (or (not guix-operation-confirm)
+              (y-or-n-p
+               (let ((count (length generations)))
+                 (if (> count 1)
+                     (format "Delete %d generations? " count)
+                   (format "Delete generation number %d? "
+                           (car generations))))))
+    (guix-eval-in-repl
+     (guix-make-guile-expression
+      'delete-generations* guix-current-profile generations))))
+
 (provide 'guix-base)
 
 ;;; guix-base.el ends here
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
index d0a320f..d5226b1 100644
--- a/emacs/guix-info.el
+++ b/emacs/guix-info.el
@@ -627,8 +627,10 @@ ENTRY is an alist with package info."
   (guix-info-insert-indent)
   (guix-info-insert-action-button
    "Delete"
-   (lambda (btn) (error "Sorry, not implemented yet"))
-   "Delete this generation"))
+   (lambda (btn)
+     (guix-delete-generations (button-get btn 'number)))
+   "Delete this generation"
+   'number number))
 
 (provide 'guix-info)
 
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index 6a4cdfc..4b4b9c5 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -728,8 +728,9 @@ 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 "x")   'guix-generation-list-execute)
   (define-key map (kbd "i")   'guix-list-describe)
-  (define-key map (kbd "d")   'guix-generation-list-mark-delete-simple))
+  (define-key map (kbd "d")   'guix-generation-list-mark-delete))
 
 (defun guix-generation-list-show-packages ()
   "List installed packages for the generation at point."
@@ -737,6 +738,22 @@ Also see `guix-package-info-type'."
   (guix-get-show-entries 'list guix-package-list-type 'generation
                          (guix-list-current-id)))
 
+(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."
+  (interactive "P")
+  (if arg
+      (guix-list-mark-all 'delete)
+    (guix-list-mark 'delete t)))
+
+(defun guix-generation-list-execute ()
+  "Delete marked generations."
+  (interactive)
+  (let ((marked (guix-list-get-marked-id-list 'delete)))
+    (or marked
+        (user-error "No generations marked for deletion"))
+    (apply #'guix-delete-generations marked)))
+
 (provide 'guix-list)
 
 ;;; guix-list.el ends here
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index 026a9e9..24ca4d1 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -815,3 +815,9 @@ OUTPUTS is a list of package outputs (may be an empty list)."
                                   "~a packages in profile~%"
                                   count)
                            count)))))))))
+
+(define (delete-generations* profile generations)
+  "Delete GENERATIONS from PROFILE.
+GENERATIONS is a list of generation numbers."
+  (let ((store (open-connection)))
+    (delete-generations store profile generations)))
-- 
2.1.2

Reply via email to