emacs: Improve interface for working with multiple profiles.
Suggested by David Thompson, Ludovic Courtès and Mathieu Lirzin. * emacs/guix-base.el (guix-profile-prompt): New procedure. (guix-set-current-profile): Use it. (guix-buffer-name-simple, guix-buffer-name-default, guix-buffer-name): New procedures. (guix-buffer-name-function, guix-profile): New variables. (guix-set-vars, guix-get-entries, guix-get-show-entries, guix-set-buffer, guix-history-call, guix-process-package-actions, guix-continue-package-operation-p, guix-delete-generations, guix-switch-to-generation): Add 'profile' argument. * emacs/guix.el (guix-get-show-packages, guix-get-show-generations, guix-search-by-name, guix-search-by-regexp, guix-installed-packages, guix-obsolete-packages, guix-all-available-packages, guix-newest-available-packages, guix-generations, guix-generations-by-time): Likewise. (guix-last-generations): New command. * emacs/guix-info.el: Adjust for using 'profile' argument where needed. * emacs/guix-list.el: Likewise. * doc/emacs.texi (Emacs Commands): Document 'guix-last-generations' and using "C-u" for commands. (Emacs Buffer Names): Document 'guix-buffer-name-function'.
This commit is contained in:
parent
7c3c0374de
commit
23459fa59b
|
@ -76,19 +76,26 @@ can be displayed in a ``list'' or ``info'' buffer.
|
|||
@node Emacs Commands
|
||||
@subsubsection Commands
|
||||
|
||||
You may use the following commands to display packages and generations:
|
||||
All commands for displaying packages and generations use the current
|
||||
profile, which can be changed with
|
||||
@kbd{M-x@tie{}guix-set-current-profile}. Alternatively, if you call any
|
||||
of these commands with prefix argument (@kbd{C-u}), you will be prompted
|
||||
for a profile just for that command.
|
||||
|
||||
Commands for displaying packages:
|
||||
|
||||
@table @kbd
|
||||
|
||||
@item M-x guix-all-available-packages
|
||||
@itemx M-x guix-newest-available-packages
|
||||
Display all/newest available packages.
|
||||
|
||||
@item M-x guix-installed-packages
|
||||
Display all packages installed in the current profile.
|
||||
Display all installed packages.
|
||||
|
||||
@item M-x guix-obsolete-packages
|
||||
Display obsolete packages (the packages that are installed in the
|
||||
current profile but cannot be found among available packages).
|
||||
Display obsolete packages (the packages that are installed in a profile
|
||||
but cannot be found among available packages).
|
||||
|
||||
@item M-x guix-search-by-name
|
||||
Display package(s) with the specified name.
|
||||
|
@ -98,29 +105,33 @@ Search for packages by a specified regexp. By default ``name'',
|
|||
``synopsis'' and ``description'' of the packages will be searched. This
|
||||
can be changed by modifying @code{guix-search-params} variable.
|
||||
|
||||
@item M-x guix-generations
|
||||
List generations for the current profile. With numeric prefix, show so
|
||||
many last generations.
|
||||
|
||||
@item M-x guix-generations-by-time
|
||||
List generations matching time period. You'll be prompted for the
|
||||
period using Org mode time prompt based on Emacs calendar (@pxref{The
|
||||
date/time prompt,,, org, Org Mode Manual}).
|
||||
|
||||
@end table
|
||||
|
||||
By default commands for displaying packages display each output on a
|
||||
separate line. If you prefer to see a list of packages---i.e., a list
|
||||
with a package per line, use the following setting:
|
||||
By default, these commands display each output on a separate line. If
|
||||
you prefer to see a list of packages---i.e., a list with a package per
|
||||
line, use the following setting:
|
||||
|
||||
@example
|
||||
(setq guix-package-list-type 'package)
|
||||
@end example
|
||||
|
||||
It is possible to change the currently used profile with
|
||||
@kbd{M-x@tie{}guix-set-current-profile}. This has the same effect as
|
||||
specifying @code{--profile} option for @command{guix package}
|
||||
(@pxref{Invoking guix package}).
|
||||
Commands for displaying generations:
|
||||
|
||||
@table @kbd
|
||||
|
||||
@item M-x guix-generations
|
||||
List all the generations.
|
||||
|
||||
@item M-x guix-last-generations
|
||||
List the @var{N} last generations. You will be prompted for the number
|
||||
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}).
|
||||
|
||||
@end table
|
||||
|
||||
@node Emacs General info
|
||||
@subsubsection General information
|
||||
|
@ -304,10 +315,13 @@ changed with the following variables:
|
|||
@item guix-generation-info-buffer-name
|
||||
@item guix-repl-buffer-name
|
||||
@item guix-internal-repl-buffer-name
|
||||
@item guix-temp-buffer-name
|
||||
@end table
|
||||
|
||||
For example if you want to display all types of results in a single
|
||||
By default, the name of a profile is also displayed in a ``list'' or
|
||||
``info'' buffer name. To change this behavior, use
|
||||
@code{guix-buffer-name-function} variable.
|
||||
|
||||
For example, if you want to display all types of results in a single
|
||||
buffer (in such case you will probably use a history (@kbd{l}/@kbd{r})
|
||||
extensively), you may do it like this:
|
||||
|
||||
|
@ -319,7 +333,8 @@ extensively), you may do it like this:
|
|||
guix-generation-list-buffer-name name
|
||||
guix-package-info-buffer-name name
|
||||
guix-output-info-buffer-name name
|
||||
guix-generation-info-buffer-name name))
|
||||
guix-generation-info-buffer-name name
|
||||
guix-buffer-name-function #'guix-buffer-name-simple))
|
||||
@end example
|
||||
|
||||
@node Emacs Keymaps
|
||||
|
|
|
@ -48,6 +48,18 @@
|
|||
(defvar guix-current-profile guix-default-profile
|
||||
"Current profile.")
|
||||
|
||||
(defun guix-profile-prompt (&optional default)
|
||||
"Prompt for profile and return it.
|
||||
Use DEFAULT as a start directory. If it is nil, use
|
||||
`guix-current-profile'."
|
||||
(let* ((path (read-file-name "Profile: "
|
||||
(file-name-directory
|
||||
(or default guix-current-profile))))
|
||||
(path (directory-file-name (expand-file-name path))))
|
||||
(if (string= path guix-user-profile)
|
||||
guix-default-profile
|
||||
path)))
|
||||
|
||||
(defun guix-set-current-profile (path)
|
||||
"Set `guix-current-profile' to PATH.
|
||||
Interactively, prompt for PATH. With prefix, use
|
||||
|
@ -55,15 +67,10 @@ Interactively, prompt for PATH. With prefix, use
|
|||
(interactive
|
||||
(list (if current-prefix-arg
|
||||
guix-default-profile
|
||||
(read-file-name "Set profile: "
|
||||
(file-name-directory guix-current-profile)))))
|
||||
(let ((path (directory-file-name (expand-file-name path))))
|
||||
(setq guix-current-profile
|
||||
(if (string= path guix-user-profile)
|
||||
guix-default-profile
|
||||
path))
|
||||
(guix-profile-prompt))))
|
||||
(setq guix-current-profile path)
|
||||
(message "Current profile has been set to '%s'."
|
||||
guix-current-profile)))
|
||||
guix-current-profile))
|
||||
|
||||
|
||||
;;; Parameters of the entries
|
||||
|
@ -209,6 +216,56 @@ If `all', update all Guix buffers (not recommended)."
|
|||
(const :tag "Update all Guix buffers" all))
|
||||
:group 'guix)
|
||||
|
||||
(defcustom guix-buffer-name-function #'guix-buffer-name-default
|
||||
"Function used to define name of a buffer for displaying information.
|
||||
The function is called with 4 arguments: PROFILE, BUFFER-TYPE,
|
||||
ENTRY-TYPE, SEARCH-TYPE. See `guix-get-entries' for the meaning
|
||||
of the arguments."
|
||||
:type '(choice (function-item guix-buffer-name-default)
|
||||
(function-item guix-buffer-name-simple)
|
||||
(function :tag "Other function"))
|
||||
:group 'guix)
|
||||
|
||||
(defun guix-buffer-name-simple (_profile buffer-type entry-type
|
||||
&optional _search-type)
|
||||
"Return name of a buffer used for displaying information.
|
||||
The name is defined by `guix-ENTRY-TYPE-BUFFER-TYPE-buffer-name'
|
||||
variable."
|
||||
(symbol-value
|
||||
(guix-get-symbol "buffer-name" buffer-type entry-type)))
|
||||
|
||||
(defun guix-buffer-name-default (profile buffer-type entry-type
|
||||
&optional _search-type)
|
||||
"Return name of a buffer used for displaying information.
|
||||
The name is almost the same as the one defined by
|
||||
`guix-buffer-name-simple' except the PROFILE name is added to it."
|
||||
(let ((simple-name (guix-buffer-name-simple
|
||||
profile buffer-type entry-type))
|
||||
(profile-name (file-name-base (directory-file-name profile)))
|
||||
(re (rx string-start
|
||||
(group (? "*"))
|
||||
(group (*? any))
|
||||
(group (? "*"))
|
||||
string-end)))
|
||||
(or (string-match re simple-name)
|
||||
(error "Unexpected error in defining guix buffer name"))
|
||||
(let ((first* (match-string 1 simple-name))
|
||||
(name-body (match-string 2 simple-name))
|
||||
(last* (match-string 3 simple-name)))
|
||||
;; Handle the case when buffer name is wrapped by '*'.
|
||||
(if (and (string= "*" first*)
|
||||
(string= "*" last*))
|
||||
(concat "*" name-body ": " profile-name "*")
|
||||
(concat simple-name ": " profile-name)))))
|
||||
|
||||
(defun guix-buffer-name (profile buffer-type entry-type search-type)
|
||||
"Return name of a buffer used for displaying information.
|
||||
See `guix-buffer-name-function' for details."
|
||||
(let ((fun (if (functionp guix-buffer-name-function)
|
||||
guix-buffer-name-function
|
||||
#'guix-buffer-name-default)))
|
||||
(funcall fun profile buffer-type entry-type search-type)))
|
||||
|
||||
(defun guix-switch-to-buffer (buffer)
|
||||
"Switch to a 'list' or 'info' BUFFER."
|
||||
(pop-to-buffer buffer
|
||||
|
@ -246,6 +303,10 @@ See `guix-update-after-operation' for details."
|
|||
|
||||
;;; Common definitions for buffer types
|
||||
|
||||
(defvar-local guix-profile nil
|
||||
"Profile used for the current buffer.")
|
||||
(put 'guix-profile 'permanent-local t)
|
||||
|
||||
(defvar-local guix-entries nil
|
||||
"List of the currently displayed entries.
|
||||
Each element of the list is alist with entry info of the
|
||||
|
@ -273,9 +334,12 @@ VAL is a value of this parameter.")
|
|||
"Values of the current search.")
|
||||
(put 'guix-search-vals 'permanent-local t)
|
||||
|
||||
(defsubst guix-set-vars (entries buffer-type entry-type
|
||||
(defsubst guix-set-vars (profile entries buffer-type entry-type
|
||||
search-type search-vals)
|
||||
(setq guix-entries entries
|
||||
"Set local variables for the current Guix buffer."
|
||||
(setq default-directory profile
|
||||
guix-profile profile
|
||||
guix-entries entries
|
||||
guix-buffer-type buffer-type
|
||||
guix-entry-type entry-type
|
||||
guix-search-type search-type
|
||||
|
@ -416,7 +480,7 @@ information)."
|
|||
(const :tag "Display outputs" output))
|
||||
:group 'guix)
|
||||
|
||||
(defun guix-get-entries (entry-type search-type search-vals
|
||||
(defun guix-get-entries (profile entry-type search-type search-vals
|
||||
&optional params)
|
||||
"Search for entries of ENTRY-TYPE.
|
||||
|
||||
|
@ -432,26 +496,25 @@ SEARCH-TYPE may be one of the following symbols:
|
|||
`all-available', `newest-available', `installed', `obsolete',
|
||||
`generation'.
|
||||
|
||||
- If ENTRY-TYPE is `generation': `id', `last', `all'.
|
||||
- If ENTRY-TYPE is `generation': `id', `last', `all', `time'.
|
||||
|
||||
PARAMS is a list of parameters for receiving. If nil, get
|
||||
information with all available parameters."
|
||||
(guix-eval-read (guix-make-guile-expression
|
||||
'entries
|
||||
guix-current-profile params
|
||||
entry-type search-type search-vals)))
|
||||
profile params entry-type search-type search-vals)))
|
||||
|
||||
(defun guix-get-show-entries (buffer-type entry-type search-type
|
||||
(defun guix-get-show-entries (profile buffer-type entry-type search-type
|
||||
&rest search-vals)
|
||||
"Search for ENTRY-TYPE entries and show results in BUFFER-TYPE buffer.
|
||||
See `guix-get-entries' for the meaning of SEARCH-TYPE and SEARCH-VALS."
|
||||
(let ((entries (guix-get-entries entry-type search-type search-vals
|
||||
(let ((entries (guix-get-entries profile entry-type search-type search-vals
|
||||
(guix-get-params-for-receiving
|
||||
buffer-type entry-type))))
|
||||
(guix-set-buffer entries buffer-type entry-type
|
||||
(guix-set-buffer profile entries buffer-type entry-type
|
||||
search-type search-vals)))
|
||||
|
||||
(defun guix-set-buffer (entries buffer-type entry-type search-type
|
||||
(defun guix-set-buffer (profile entries buffer-type entry-type search-type
|
||||
search-vals &optional history-replace no-display)
|
||||
"Set up BUFFER-TYPE buffer for displaying ENTRY-TYPE ENTRIES.
|
||||
|
||||
|
@ -465,16 +528,16 @@ otherwise add the new one.
|
|||
|
||||
If NO-DISPLAY is non-nil, do not switch to the buffer."
|
||||
(when entries
|
||||
(let ((buf (if (eq major-mode (guix-get-symbol
|
||||
"mode" buffer-type entry-type))
|
||||
(let ((buf (if (and (eq major-mode
|
||||
(guix-get-symbol "mode" buffer-type entry-type))
|
||||
(equal guix-profile profile))
|
||||
(current-buffer)
|
||||
(get-buffer-create
|
||||
(symbol-value
|
||||
(guix-get-symbol "buffer-name"
|
||||
buffer-type entry-type))))))
|
||||
(guix-buffer-name profile buffer-type
|
||||
entry-type search-type)))))
|
||||
(with-current-buffer buf
|
||||
(guix-show-entries entries buffer-type entry-type)
|
||||
(guix-set-vars entries buffer-type entry-type
|
||||
(guix-set-vars profile entries buffer-type entry-type
|
||||
search-type search-vals)
|
||||
(funcall (if history-replace
|
||||
#'guix-history-replace
|
||||
|
@ -494,18 +557,18 @@ If NO-DISPLAY is non-nil, do not switch to the buffer."
|
|||
entries entry-type)
|
||||
(goto-char (point-min))))
|
||||
|
||||
(defun guix-history-call (entries buffer-type entry-type
|
||||
(defun guix-history-call (profile entries buffer-type entry-type
|
||||
search-type search-vals)
|
||||
"Function called for moving by history."
|
||||
(guix-show-entries entries buffer-type entry-type)
|
||||
(guix-set-vars entries buffer-type entry-type
|
||||
(guix-set-vars profile entries buffer-type entry-type
|
||||
search-type search-vals)
|
||||
(guix-result-message entries entry-type search-type search-vals))
|
||||
|
||||
(defun guix-make-history-item ()
|
||||
"Make and return a history item for the current buffer."
|
||||
(list #'guix-history-call
|
||||
guix-entries guix-buffer-type guix-entry-type
|
||||
guix-profile guix-entries guix-buffer-type guix-entry-type
|
||||
guix-search-type guix-search-vals))
|
||||
|
||||
(defun guix-get-params-for-receiving (buffer-type entry-type)
|
||||
|
@ -529,10 +592,11 @@ See `revert-buffer' for the meaning of NOCONFIRM."
|
|||
guix-buffer-type guix-entry-type))
|
||||
(y-or-n-p "Update current information? "))
|
||||
(let ((entries (guix-get-entries
|
||||
guix-entry-type guix-search-type guix-search-vals
|
||||
guix-profile guix-entry-type
|
||||
guix-search-type guix-search-vals
|
||||
(guix-get-params-for-receiving guix-buffer-type
|
||||
guix-entry-type))))
|
||||
(guix-set-buffer entries guix-buffer-type guix-entry-type
|
||||
(guix-set-buffer guix-profile entries guix-buffer-type guix-entry-type
|
||||
guix-search-type guix-search-vals t t))))
|
||||
|
||||
(defun guix-redisplay-buffer ()
|
||||
|
@ -719,8 +783,9 @@ VARIABLE is a name of an option variable.")
|
|||
guix-operation-option-true-string
|
||||
guix-operation-option-false-string))
|
||||
|
||||
(defun guix-process-package-actions (actions &optional operation-buffer)
|
||||
"Process package ACTIONS.
|
||||
(defun guix-process-package-actions (profile actions
|
||||
&optional operation-buffer)
|
||||
"Process package ACTIONS on PROFILE.
|
||||
Each action is a list of the form:
|
||||
|
||||
(ACTION-TYPE PACKAGE-SPEC ...)
|
||||
|
@ -738,23 +803,25 @@ PACKAGE-SPEC should have the following form: (ID [OUTPUT] ...)."
|
|||
((remove delete) (setq remove (append remove specs))))))
|
||||
actions)
|
||||
(when (guix-continue-package-operation-p
|
||||
profile
|
||||
:install install :upgrade upgrade :remove remove)
|
||||
(guix-eval-in-repl
|
||||
(guix-make-guile-expression
|
||||
'process-package-actions guix-current-profile
|
||||
'process-package-actions profile
|
||||
:install install :upgrade upgrade :remove remove
|
||||
:use-substitutes? (or guix-use-substitutes 'f)
|
||||
:dry-run? (or guix-dry-run 'f))
|
||||
(and (not guix-dry-run) operation-buffer)))))
|
||||
|
||||
(cl-defun guix-continue-package-operation-p (&key install upgrade remove)
|
||||
(cl-defun guix-continue-package-operation-p (profile
|
||||
&key install upgrade remove)
|
||||
"Return non-nil if a package operation should be continued.
|
||||
Ask a user if needed (see `guix-operation-confirm').
|
||||
INSTALL, UPGRADE, REMOVE are 'package action specifications'.
|
||||
See `guix-process-package-actions' for details."
|
||||
(or (null guix-operation-confirm)
|
||||
(let* ((entries (guix-get-entries
|
||||
'package 'id
|
||||
profile 'package 'id
|
||||
(append (mapcar #'car install)
|
||||
(mapcar #'car upgrade)
|
||||
(mapcar #'car remove))
|
||||
|
@ -768,6 +835,7 @@ See `guix-process-package-actions' for details."
|
|||
(setq-local cursor-type nil)
|
||||
(setq buffer-read-only nil)
|
||||
(erase-buffer)
|
||||
(insert "Profile: " profile "\n\n")
|
||||
(guix-insert-package-strings install-strings "install")
|
||||
(guix-insert-package-strings upgrade-strings "upgrade")
|
||||
(guix-insert-package-strings remove-strings "remove")
|
||||
|
@ -861,29 +929,32 @@ Return non-nil, if the operation should be continued; nil otherwise."
|
|||
guix-operation-option-separator)))
|
||||
(force-mode-line-update))
|
||||
|
||||
(defun guix-delete-generations (generations &optional operation-buffer)
|
||||
"Delete GENERATIONS.
|
||||
(defun guix-delete-generations (profile generations
|
||||
&optional operation-buffer)
|
||||
"Delete GENERATIONS from PROFILE.
|
||||
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))))))
|
||||
(format "Delete %d generations from profile '%s'? "
|
||||
count profile)
|
||||
(format "Delete generation %d from profile '%s'? "
|
||||
(car generations) profile)))))
|
||||
(guix-eval-in-repl
|
||||
(guix-make-guile-expression
|
||||
'delete-generations* guix-current-profile generations)
|
||||
'delete-generations* profile generations)
|
||||
operation-buffer)))
|
||||
|
||||
(defun guix-switch-to-generation (generation &optional operation-buffer)
|
||||
"Switch `guix-current-profile' to GENERATION number."
|
||||
(defun guix-switch-to-generation (profile generation
|
||||
&optional operation-buffer)
|
||||
"Switch PROFILE to GENERATION."
|
||||
(when (or (not guix-operation-confirm)
|
||||
(y-or-n-p (format "Switch current profile to generation %d? "
|
||||
generation)))
|
||||
(y-or-n-p (format "Switch profile '%s' to generation %d? "
|
||||
profile generation)))
|
||||
(guix-eval-in-repl
|
||||
(guix-make-guile-expression
|
||||
'switch-to-generation guix-current-profile generation)
|
||||
'switch-to-generation profile generation)
|
||||
operation-buffer)))
|
||||
|
||||
(provide 'guix-base)
|
||||
|
|
|
@ -334,8 +334,8 @@ VAL is a list, call the function on each element of this list."
|
|||
'face 'guix-package-info-name-button
|
||||
'help-echo "Describe this package"
|
||||
'action (lambda (btn)
|
||||
(guix-get-show-entries 'info guix-package-info-type 'name
|
||||
(button-label btn))))
|
||||
(guix-get-show-entries guix-profile 'info guix-package-info-type
|
||||
'name (button-label btn))))
|
||||
|
||||
(defun guix-info-insert-action-button (label action &optional message
|
||||
&rest properties)
|
||||
|
@ -558,6 +558,7 @@ ENTRY is an alist with package info."
|
|||
type-str
|
||||
(lambda (btn)
|
||||
(guix-process-package-actions
|
||||
guix-profile
|
||||
`((,(button-get btn 'action-type) (,(button-get btn 'id)
|
||||
,(button-get btn 'output))))
|
||||
(current-buffer)))
|
||||
|
@ -631,15 +632,15 @@ ENTRY is an alist with package info."
|
|||
(guix-info-insert-action-button
|
||||
"Packages"
|
||||
(lambda (btn)
|
||||
(guix-get-show-entries 'list guix-package-list-type 'generation
|
||||
(button-get btn 'number)))
|
||||
(guix-get-show-entries guix-profile 'list guix-package-list-type
|
||||
'generation (button-get btn 'number)))
|
||||
"Show installed packages for this generation"
|
||||
'number number)
|
||||
(guix-info-insert-indent)
|
||||
(guix-info-insert-action-button
|
||||
"Delete"
|
||||
(lambda (btn)
|
||||
(guix-delete-generations (list (button-get btn 'number))
|
||||
(guix-delete-generations guix-profile (list (button-get btn 'number))
|
||||
(current-buffer)))
|
||||
"Delete this generation"
|
||||
'number number))
|
||||
|
@ -653,7 +654,7 @@ ENTRY is an alist with package info."
|
|||
(guix-info-insert-action-button
|
||||
"Switch"
|
||||
(lambda (btn)
|
||||
(guix-switch-to-generation (button-get btn 'number)
|
||||
(guix-switch-to-generation guix-profile (button-get btn 'number)
|
||||
(current-buffer)))
|
||||
"Switch to this generation (make it the current one)"
|
||||
'number (guix-get-key-val entry 'number))))
|
||||
|
|
|
@ -441,7 +441,8 @@ This macro defines the following functions:
|
|||
(when (or (<= count guix-list-describe-warning-count)
|
||||
(y-or-n-p (format "Do you really want to describe %d entries? "
|
||||
count)))
|
||||
(apply #'guix-get-show-entries 'info entry-type 'id ids))))
|
||||
(apply #'guix-get-show-entries
|
||||
guix-profile 'info entry-type 'id ids))))
|
||||
|
||||
(defun guix-list-describe (&optional arg)
|
||||
"Describe entries marked with a general mark.
|
||||
|
@ -617,7 +618,8 @@ FUN should accept action-type as argument."
|
|||
(let ((actions (delq nil
|
||||
(mapcar fun '(install delete upgrade)))))
|
||||
(if actions
|
||||
(guix-process-package-actions actions (current-buffer))
|
||||
(guix-process-package-actions
|
||||
guix-profile actions (current-buffer))
|
||||
(user-error "No operations specified"))))
|
||||
|
||||
(defun guix-package-list-execute ()
|
||||
|
@ -751,13 +753,13 @@ VAL is a boolean value."
|
|||
(number (guix-get-key-val entry 'number)))
|
||||
(if current
|
||||
(user-error "This generation is already the current one")
|
||||
(guix-switch-to-generation number (current-buffer)))))
|
||||
(guix-switch-to-generation guix-profile number (current-buffer)))))
|
||||
|
||||
(defun guix-generation-list-show-packages ()
|
||||
"List installed packages for the generation at point."
|
||||
(interactive)
|
||||
(guix-get-show-entries 'list guix-package-list-type 'generation
|
||||
(guix-list-current-id)))
|
||||
(guix-get-show-entries guix-profile '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.
|
||||
|
@ -773,7 +775,7 @@ With ARG, mark all generations for deletion."
|
|||
(let ((marked (guix-list-get-marked-id-list 'delete)))
|
||||
(or marked
|
||||
(user-error "No generations marked for deletion"))
|
||||
(guix-delete-generations marked (current-buffer))))
|
||||
(guix-delete-generations guix-profile marked (current-buffer))))
|
||||
|
||||
(provide 'guix-list)
|
||||
|
||||
|
|
141
emacs/guix.el
141
emacs/guix.el
|
@ -50,99 +50,146 @@ If nil, show a single package in the info buffer."
|
|||
(defvar guix-search-history nil
|
||||
"A history of minibuffer prompts.")
|
||||
|
||||
(defun guix-get-show-packages (search-type &rest search-vals)
|
||||
(defun guix-get-show-packages (profile search-type &rest search-vals)
|
||||
"Search for packages and show results.
|
||||
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
|
||||
See `guix-get-entries' for the meaning of SEARCH-TYPE and
|
||||
SEARCH-VALS.
|
||||
|
||||
Results are displayed in the list buffer, unless a single package
|
||||
is found and `guix-list-single-package' is nil."
|
||||
(let ((packages (guix-get-entries guix-package-list-type
|
||||
(or profile (setq profile guix-current-profile))
|
||||
(let ((packages (guix-get-entries profile guix-package-list-type
|
||||
search-type search-vals
|
||||
(guix-get-params-for-receiving
|
||||
'list guix-package-list-type))))
|
||||
(if (or guix-list-single-package
|
||||
(cdr packages))
|
||||
(guix-set-buffer packages 'list guix-package-list-type
|
||||
(guix-set-buffer profile packages 'list guix-package-list-type
|
||||
search-type search-vals)
|
||||
(let ((packages (guix-get-entries guix-package-info-type
|
||||
(let ((packages (guix-get-entries profile guix-package-info-type
|
||||
search-type search-vals
|
||||
(guix-get-params-for-receiving
|
||||
'info guix-package-info-type))))
|
||||
(guix-set-buffer packages 'info guix-package-info-type
|
||||
(guix-set-buffer profile packages 'info guix-package-info-type
|
||||
search-type search-vals)))))
|
||||
|
||||
(defun guix-get-show-generations (search-type &rest search-vals)
|
||||
"Search for generations and show results."
|
||||
(defun guix-get-show-generations (profile search-type &rest search-vals)
|
||||
"Search for generations and show results.
|
||||
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
|
||||
See `guix-get-entries' for the meaning of SEARCH-TYPE and
|
||||
SEARCH-VALS."
|
||||
(apply #'guix-get-show-entries
|
||||
(or profile guix-current-profile)
|
||||
'list 'generation search-type search-vals))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-search-by-name (name)
|
||||
(defun guix-search-by-name (name &optional profile)
|
||||
"Search for Guix packages by NAME.
|
||||
NAME is a string with name specification. It may optionally contain
|
||||
a version number. Examples: \"guile\", \"guile-2.0.11\"."
|
||||
a version number. Examples: \"guile\", \"guile-2.0.11\".
|
||||
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (read-string "Package name: " nil 'guix-search-history)))
|
||||
(guix-get-show-packages 'name name))
|
||||
(list (read-string "Package name: " nil 'guix-search-history)
|
||||
(and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'name name))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-search-by-regexp (regexp &rest params)
|
||||
(defun guix-search-by-regexp (regexp &optional params profile)
|
||||
"Search for Guix packages by REGEXP.
|
||||
PARAMS are package parameters that should be searched.
|
||||
If PARAMS are not specified, use `guix-search-params'."
|
||||
If PARAMS are not specified, use `guix-search-params'.
|
||||
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (read-string "Regexp: " nil 'guix-search-history)))
|
||||
(or params (setq params guix-search-params))
|
||||
(guix-get-show-packages 'regexp regexp params))
|
||||
(list (read-regexp "Regexp: " nil 'guix-search-history)
|
||||
nil
|
||||
(and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'regexp regexp
|
||||
(or params guix-search-params)))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-installed-packages ()
|
||||
"Display information about installed Guix packages."
|
||||
(interactive)
|
||||
(guix-get-show-packages 'installed))
|
||||
(defun guix-installed-packages (&optional profile)
|
||||
"Display information about installed Guix packages.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'installed))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-obsolete-packages ()
|
||||
"Display information about obsolete Guix packages."
|
||||
(interactive)
|
||||
(guix-get-show-packages 'obsolete))
|
||||
(defun guix-obsolete-packages (&optional profile)
|
||||
"Display information about obsolete Guix packages.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'obsolete))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-all-available-packages ()
|
||||
"Display information about all available Guix packages."
|
||||
(interactive)
|
||||
(guix-get-show-packages 'all-available))
|
||||
(defun guix-all-available-packages (&optional profile)
|
||||
"Display information about all available Guix packages.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'all-available))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-newest-available-packages ()
|
||||
"Display information about the newest available Guix packages."
|
||||
(interactive)
|
||||
(guix-get-show-packages 'newest-available))
|
||||
(defun guix-newest-available-packages (&optional profile)
|
||||
"Display information about the newest available Guix packages.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-packages profile 'newest-available))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-generations (&optional number)
|
||||
(defun guix-generations (&optional profile)
|
||||
"Display information about all generations.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-generations profile 'all))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-last-generations (number &optional profile)
|
||||
"Display information about last NUMBER generations.
|
||||
If NUMBER is nil, display all generations.
|
||||
|
||||
Generations can be displayed in a list or info buffers depending
|
||||
on `guix-show-generations-function'.
|
||||
|
||||
Interactively, NUMBER is defined by a numeric prefix."
|
||||
(interactive "P")
|
||||
(if (numberp number)
|
||||
(guix-get-show-generations 'last number)
|
||||
(guix-get-show-generations 'all)))
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (read-number "The number of last generations: ")
|
||||
(and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-generations profile 'last number))
|
||||
|
||||
;;;###autoload
|
||||
(defun guix-generations-by-time (from to)
|
||||
(defun guix-generations-by-time (from to &optional profile)
|
||||
"Display information about generations created between FROM and TO.
|
||||
FROM and TO should be time values."
|
||||
FROM and TO should be time values.
|
||||
If PROFILE is nil, use `guix-current-profile'.
|
||||
Interactively with prefix, prompt for PROFILE."
|
||||
(interactive
|
||||
(list (guix-read-date "Find generations (from): ")
|
||||
(guix-read-date "Find generations (to): ")))
|
||||
(guix-get-show-generations 'time
|
||||
(guix-read-date "Find generations (to): ")
|
||||
(and current-prefix-arg
|
||||
(guix-profile-prompt))))
|
||||
(guix-get-show-generations profile 'time
|
||||
(float-time from)
|
||||
(float-time to)))
|
||||
|
||||
|
|
Loading…
Reference in New Issue