aboutsummaryrefslogtreecommitdiff
path: root/emacs
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-12-12 11:42:12 +0100
committerLudovic Courtès <ludo@gnu.org>2015-12-12 11:48:46 +0100
commite82e55e58c67b0215e768c4612ca542bc670f633 (patch)
tree856c4512fa1fbde59c1d9845c5a763ef8c4a14b4 /emacs
parent98bd851ee891ca4a84e061fe1e78ba78c292b096 (diff)
parente35dff973375266db253747140ddf25084ecddc2 (diff)
downloadpatches-e82e55e58c67b0215e768c4612ca542bc670f633.tar
patches-e82e55e58c67b0215e768c4612ca542bc670f633.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'emacs')
-rw-r--r--emacs/guix-backend.el2
-rw-r--r--emacs/guix-base.el18
-rw-r--r--emacs/guix-build-log.el58
-rw-r--r--emacs/guix-command.el159
-rw-r--r--emacs/guix-devel.el2
-rw-r--r--emacs/guix-emacs.el52
-rw-r--r--emacs/guix-info.el11
-rw-r--r--emacs/guix-init.el3
-rw-r--r--emacs/guix-list.el8
-rw-r--r--emacs/guix-main.scm7
-rw-r--r--emacs/guix-pcomplete.el21
-rw-r--r--emacs/guix-read.el6
-rw-r--r--emacs/guix-utils.el11
13 files changed, 291 insertions, 67 deletions
diff --git a/emacs/guix-backend.el b/emacs/guix-backend.el
index e7c158bef4..82383e48ff 100644
--- a/emacs/guix-backend.el
+++ b/emacs/guix-backend.el
@@ -202,7 +202,7 @@ this address (it should be defined by
;; A mix of the code from `geiser-repl--start-repl' and
;; `geiser-repl--to-repl-buffer'.
(let ((impl 'guile)
- (geiser-guile-load-path (cons guix-load-path
+ (geiser-guile-load-path (cons (expand-file-name guix-load-path)
geiser-guile-load-path))
(geiser-repl-startup-time guix-repl-startup-time))
(with-current-buffer buffer
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index e64e375e33..d9c70aae9e 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -186,6 +186,10 @@ For the meaning of location, see `guix-find-location'."
"Return a list of names of available graph node types."
(guix-eval-read (guix-make-guile-expression 'graph-type-names)))
+(guix-memoized-defun guix-refresh-updater-names ()
+ "Return a list of names of available refresh updater types."
+ (guix-eval-read (guix-make-guile-expression 'refresh-updater-names)))
+
(guix-memoized-defun guix-lint-checker-names ()
"Return a list of names of available lint checkers."
(guix-eval-read (guix-make-guile-expression 'lint-checker-names)))
@@ -1035,7 +1039,7 @@ Each element from GENERATIONS is a generation number."
profile generation)))
(guix-eval-in-repl
(guix-make-guile-expression
- 'switch-to-generation profile generation)
+ 'switch-to-generation* profile generation)
operation-buffer)))
(defun guix-package-source-path (package-id)
@@ -1083,9 +1087,10 @@ FILE. With a prefix argument, also prompt for PROFILE."
file profile)))
(guix-eval-in-repl
(guix-make-guile-expression
- 'guix-package
- (concat "--profile=" profile)
- (concat "--manifest=" file))
+ 'guix-command
+ "package"
+ (concat "--profile=" (expand-file-name profile))
+ (concat "--manifest=" (expand-file-name file)))
operation-buffer)))
@@ -1181,10 +1186,11 @@ The function is called with a single argument - a command line string."
(defun guix-pull (&optional verbose)
"Run Guix pull operation.
If VERBOSE is non-nil (with prefix argument), produce verbose output."
- (interactive)
+ (interactive "P")
(let ((args (and verbose '("--verbose"))))
(guix-eval-in-repl
- (apply #'guix-make-guile-expression 'guix-pull args)
+ (apply #'guix-make-guile-expression
+ 'guix-command "pull" args)
nil 'pull)))
(provide 'guix-base)
diff --git a/emacs/guix-build-log.el b/emacs/guix-build-log.el
index c0855b284c..e08a88f6cc 100644
--- a/emacs/guix-build-log.el
+++ b/emacs/guix-build-log.el
@@ -24,6 +24,8 @@
;;; Code:
+(require 'guix-utils)
+
(defgroup guix-build-log nil
"Settings for `guix-build-log-mode'."
:group 'guix)
@@ -102,10 +104,13 @@
"Face for the number of seconds for a phase."
:group 'guix-build-log-faces)
-(defcustom guix-build-log-mode-hook
- ;; Not using `compilation-minor-mode' because it rebinds some standard
- ;; keys, including M-n/M-p.
- '(compilation-shell-minor-mode view-mode)
+(defcustom guix-build-log-minor-mode-activate t
+ "If non-nil, then `guix-build-log-minor-mode' is automatically
+activated in `shell-mode' buffers."
+ :type 'boolean
+ :group 'guix-build-log)
+
+(defcustom guix-build-log-mode-hook '()
"Hook run after `guix-build-log-mode' is entered."
:type 'hook
:group 'guix-build-log)
@@ -178,9 +183,8 @@ STATE is a symbol denoting how a build phase was ended. It should be
(3 'guix-build-log-phase-seconds prepend)))
"A list of `font-lock-keywords' for `guix-build-log-mode'.")
-(defvar guix-build-log-mode-map
+(defvar guix-build-log-common-map
(let ((map (make-sparse-keymap)))
- (set-keymap-parent map special-mode-map)
(define-key map (kbd "M-n") 'guix-build-log-next-phase)
(define-key map (kbd "M-p") 'guix-build-log-previous-phase)
(define-key map (kbd "TAB") 'guix-build-log-phase-toggle)
@@ -188,8 +192,26 @@ STATE is a symbol denoting how a build phase was ended. It should be
(define-key map (kbd "<backtab>") 'guix-build-log-phase-toggle-all)
(define-key map [(shift tab)] 'guix-build-log-phase-toggle-all)
map)
+ "Parent keymap for 'build-log' buffers.
+For `guix-build-log-mode' this map is used as is.
+For `guix-build-log-minor-mode' this map is prefixed with 'C-c'.")
+
+(defvar guix-build-log-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent
+ map (make-composed-keymap (list guix-build-log-common-map)
+ special-mode-map))
+ (define-key map (kbd "c") 'compilation-shell-minor-mode)
+ (define-key map (kbd "v") 'view-mode)
+ map)
"Keymap for `guix-build-log-mode' buffers.")
+(defvar guix-build-log-minor-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c") guix-build-log-common-map)
+ map)
+ "Keymap for `guix-build-log-minor-mode' buffers.")
+
(defun guix-build-log-phase-start (&optional with-header?)
"Return the start point of the current build phase.
If WITH-HEADER? is non-nil, do not skip 'starting phase ...' header.
@@ -319,9 +341,12 @@ When Guix Build Log minor mode is enabled, it highlights build
log in the current buffer. This mode can be enabled
programmatically using hooks:
- (add-hook 'shell-mode-hook 'guix-build-log-minor-mode)"
+ (add-hook 'shell-mode-hook 'guix-build-log-minor-mode)
+
+\\{guix-build-log-minor-mode-map}"
:init-value nil
:lighter " Guix-Build-Log"
+ :keymap guix-build-log-minor-mode-map
:group 'guix-build-log
(if guix-build-log-minor-mode
(font-lock-add-keywords nil guix-build-log-font-lock-keywords)
@@ -329,6 +354,25 @@ programmatically using hooks:
(when font-lock-mode
(font-lock-fontify-buffer)))
+;;;###autoload
+(defun guix-build-log-minor-mode-activate-maybe ()
+ "Activate `guix-build-log-minor-mode' depending on
+`guix-build-log-minor-mode-activate' variable."
+ (when guix-build-log-minor-mode-activate
+ (guix-build-log-minor-mode)))
+
+(defun guix-build-log-find-file (file-or-url)
+ "Open FILE-OR-URL in `guix-build-log-mode'."
+ (guix-find-file-or-url file-or-url)
+ (guix-build-log-mode))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist
+ ;; Regexp for log files (usually placed in /var/log/guix/...)
+ (cons (rx "/guix/drvs/" (= 2 alnum) "/" (= 30 alnum)
+ "-" (+ (any alnum "-+.")) ".drv" string-end)
+ 'guix-build-log-mode))
+
(provide 'guix-build-log)
;;; guix-build-log.el ends here
diff --git a/emacs/guix-command.el b/emacs/guix-command.el
index 1a42594b68..ccd85d25b9 100644
--- a/emacs/guix-command.el
+++ b/emacs/guix-command.el
@@ -65,6 +65,7 @@
(require 'guix-help-vars)
(require 'guix-read)
(require 'guix-base)
+(require 'guix-build-log)
(require 'guix-guile)
(require 'guix-external)
@@ -131,7 +132,8 @@ to be modified."
(guix-command-define-argument-improver
guix-command-improve-action-argument
- '(("graph" :char ?G)
+ '(("container" :char ?C)
+ ("graph" :char ?G)
("environment" :char ?E)
("publish" :char ?u)
("pull" :char ?P)
@@ -173,7 +175,8 @@ to be modified."
(defvar guix-command-improve-common-build-argument
'(("--no-substitutes" :char ?s)
("--no-build-hook" :char ?h)
- ("--max-silent-time" :char ?x)))
+ ("--max-silent-time" :char ?x)
+ ("--rounds" :char ?R :fun read-number)))
(defun guix-command-improve-common-build-argument (argument)
(guix-command-modify-argument-from-alist
@@ -195,7 +198,11 @@ to be modified."
(guix-command-define-argument-improver
guix-command-improve-environment-argument
- '(("--exec" :fun read-shell-command)
+ '(("--ad-hoc"
+ :name "--ad-hoc " :fun guix-read-package-names-string
+ :switch? nil :option? t)
+ ("--expose" :char ?E)
+ ("--share" :char ?S)
("--load" :fun guix-read-file-name)))
(guix-command-define-argument-improver
@@ -234,6 +241,7 @@ to be modified."
:switch? nil :option? t)
("--install-from-file" :fun guix-read-file-name)
("--manifest" :fun guix-read-file-name)
+ ("--profile" :fun guix-read-file-name)
("--do-not-upgrade" :char ?U)
("--roll-back" :char ?R)
("--show" :char ?w :fun guix-read-package-name)))
@@ -241,6 +249,7 @@ to be modified."
(guix-command-define-argument-improver
guix-command-improve-refresh-argument
'(("--select" :fun guix-read-refresh-subset)
+ ("--type" :fun guix-read-refresh-updater-names-string)
("--key-server" :char ?S)))
(guix-command-define-argument-improver
@@ -364,11 +373,16 @@ to be modified."
:name "-- " :char ?= :option? t args)))
(let ((command (car commands)))
(cond
- ((member command '("archive" "build" "graph" "edit"
- "environment" "lint" "refresh"))
+ ((member command
+ '("archive" "build" "challenge" "edit"
+ "graph" "lint" "refresh"))
(argument :doc "Packages" :fun 'guix-read-package-names-string))
+ ((equal commands '("container" "exec"))
+ (argument :doc "PID Command [Args...]"))
((string= command "download")
(argument :doc "URL"))
+ ((string= command "environment")
+ (argument :doc "Command [Args...]" :fun 'read-shell-command))
((string= command "gc")
(argument :doc "Paths" :fun 'guix-read-file-name))
((member command '("hash" "system"))
@@ -382,10 +396,22 @@ to be modified."
(string= command "import"))
(argument :doc "Package name"))))))
+(defvar guix-command-additional-arguments
+ `((("environment")
+ ,(guix-command-make-argument
+ :name "++packages " :char ?p :option? t
+ :doc "build inputs of the specified packages"
+ :fun 'guix-read-package-names-string)))
+ "Alist of guix commands and additional arguments for them.
+These are 'fake' arguments that are not presented in 'guix' shell
+commands.")
+
(defun guix-command-additional-arguments (&optional commands)
"Return additional arguments for COMMANDS."
(let ((rest-arg (guix-command-rest-argument commands)))
- (and rest-arg (list rest-arg))))
+ (append (guix-assoc-value guix-command-additional-arguments
+ commands)
+ (and rest-arg (list rest-arg)))))
;; Ideally only `guix-command-arguments' function should exist with the
;; contents of `guix-command-all-arguments', but we need to make a
@@ -463,28 +489,113 @@ to be modified."
"Return actions from ARGUMENTS."
(cl-remove-if-not #'guix-command-argument-action? arguments))
-(defun guix-command-post-process-args (args)
- "Adjust appropriately command line ARGS returned from popup command."
- ;; XXX We need to split "--install foo bar" and similar strings into
- ;; lists of strings. But some commands (e.g., 'guix hash') accept a
- ;; file name as the 'rest' argument, and as file names may contain
- ;; spaces, splitting by spaces will break such names. For example, the
- ;; following argument: "-- /tmp/file with spaces" will be transformed
- ;; into the following list: ("--" "/tmp/file" "with" "spaces") instead
- ;; of the wished ("--" "/tmp/file with spaces").
- (let* (rest
- (rx (rx string-start
- (or "-- " "--install " "--remove ")))
+
+;;; Post processing popup arguments
+
+(defvar guix-command-post-processors
+ '(("environment"
+ guix-command-post-process-environment-packages
+ guix-command-post-process-environment-ad-hoc
+ guix-command-post-process-rest-multiple-leave)
+ ("hash"
+ guix-command-post-process-rest-single)
+ ("package"
+ guix-command-post-process-package-args)
+ ("system"
+ guix-command-post-process-rest-single))
+ "Alist of guix commands and functions for post-processing
+a list of arguments returned from popup interface.
+Each function is called on the returned arguments in turn.")
+
+(defvar guix-command-rest-arg-regexp
+ (rx string-start "-- " (group (+ any)))
+ "Regexp to match a string with the 'rest' arguments.")
+
+(defun guix-command-replace-args (args predicate modifier)
+ "Replace arguments matching PREDICATE from ARGS.
+Call MODIFIER on each argument matching PREDICATE and append the
+returned list of strings to the end of ARGS. Remove the original
+arguments."
+ (let* ((rest nil)
(args (mapcar (lambda (arg)
- (if (string-match-p rx arg)
- (progn (push (split-string arg) rest)
- nil)
+ (if (funcall predicate arg)
+ (progn
+ (push (funcall modifier arg) rest)
+ nil)
arg))
args)))
(if rest
(apply #'append (delq nil args) rest)
args)))
+(cl-defun guix-command-post-process-matching-args (args regexp
+ &key group split?)
+ "Modify arguments from ARGS matching REGEXP by moving them to
+the end of ARGS list. If SPLIT? is non-nil, split matching
+arguments into multiple subarguments."
+ (guix-command-replace-args
+ args
+ (lambda (arg)
+ (string-match regexp arg))
+ (lambda (arg)
+ (let ((val (match-string (or group 0) arg))
+ (fun (if split? #'split-string #'list)))
+ (funcall fun val)))))
+
+(defun guix-command-post-process-rest-single (args)
+ "Modify ARGS by moving '-- ARG' argument to the end of ARGS list."
+ (guix-command-post-process-matching-args
+ args guix-command-rest-arg-regexp
+ :group 1))
+
+(defun guix-command-post-process-rest-multiple (args)
+ "Modify ARGS by splitting '-- ARG ...' into multiple subarguments
+and moving them to the end of ARGS list.
+Remove '-- ' string."
+ (guix-command-post-process-matching-args
+ args guix-command-rest-arg-regexp
+ :group 1
+ :split? t))
+
+(defun guix-command-post-process-rest-multiple-leave (args)
+ "Modify ARGS by splitting '-- ARG ...' into multiple subarguments
+and moving them to the end of ARGS list.
+Leave '--' string as a separate argument."
+ (guix-command-post-process-matching-args
+ args guix-command-rest-arg-regexp
+ :split? t))
+
+(defun guix-command-post-process-package-args (args)
+ "Adjust popup ARGS for 'guix package' command."
+ (guix-command-post-process-matching-args
+ args (rx string-start (or "--install " "--remove ") (+ any))
+ :split? t))
+
+(defun guix-command-post-process-environment-packages (args)
+ "Adjust popup ARGS for specified packages of 'guix environment'
+command."
+ (guix-command-post-process-matching-args
+ args (rx string-start "++packages " (group (+ any)))
+ :group 1
+ :split? t))
+
+(defun guix-command-post-process-environment-ad-hoc (args)
+ "Adjust popup ARGS for '--ad-hoc' argument of 'guix environment'
+command."
+ (guix-command-post-process-matching-args
+ args (rx string-start "--ad-hoc " (+ any))
+ :split? t))
+
+(defun guix-command-post-process-args (commands args)
+ "Adjust popup ARGS for guix COMMANDS."
+ (let* ((command (car commands))
+ (processors
+ (append (guix-assoc-value guix-command-post-processors commands)
+ (guix-assoc-value guix-command-post-processors command))))
+ (guix-modify args
+ (or processors
+ (list #'guix-command-post-process-rest-multiple)))))
+
;;; 'Execute' actions
@@ -583,8 +694,7 @@ open the log file(s)."
(output (guix-command-output args))
(files (split-string output "\n" t)))
(dolist (file files)
- (guix-find-file-or-url file)
- (guix-build-log-mode))))
+ (guix-build-log-find-file file))))
(defun guix-run-view-graph (args)
"Run 'guix ARGS ...' graph command, make the image and open it."
@@ -640,7 +750,8 @@ EXECUTOR function is called with the current command line arguments."
,doc
(interactive (,arguments-fun))
(,executor (append ',commands
- (guix-command-post-process-args args))))))
+ (guix-command-post-process-args
+ ',commands args))))))
(defun guix-command-generate-popup-actions (actions &optional commands)
"Generate 'popup' commands from ACTIONS arguments for guix COMMANDS."
diff --git a/emacs/guix-devel.el b/emacs/guix-devel.el
index 170ce1ad54..8eb030942c 100644
--- a/emacs/guix-devel.el
+++ b/emacs/guix-devel.el
@@ -198,6 +198,7 @@ to find 'modify-phases' keywords."
"mbegin"
"mlet"
"mlet*"
+ "modify-services"
"munless"
"mwhen"
"run-with-state"
@@ -288,6 +289,7 @@ Each rule should have a form (SYMBOL VALUE). See `put' for details."
(mlet 2)
(mlet* 2)
(modify-phases 1)
+ (modify-services 1)
(munless 1)
(mwhen 1)
(operating-system 0)
diff --git a/emacs/guix-emacs.el b/emacs/guix-emacs.el
index 0e3e8c211c..2f809ed16e 100644
--- a/emacs/guix-emacs.el
+++ b/emacs/guix-emacs.el
@@ -37,6 +37,11 @@ they are successfully installed."
(defvar guix-emacs-autoloads nil
"List of the last loaded Emacs autoloads.")
+(defvar guix-emacs-autoloads-regexp
+ (rx (group (* any) "-autoloads")
+ ".el" (zero-or-one "c") string-end)
+ "Regexp to match Emacs 'autoloads' file.")
+
(defun guix-emacs-directory (&optional profile)
"Return directory with Emacs packages installed in PROFILE.
If PROFILE is nil, use `guix-user-profile'."
@@ -44,8 +49,15 @@ If PROFILE is nil, use `guix-user-profile'."
(or profile guix-user-profile)))
(defun guix-emacs-find-autoloads-in-directory (directory)
- "Return list of Emacs 'autoloads' files in DIRECTORY."
- (directory-files directory 'full-name "-autoloads\\.el\\'" 'no-sort))
+ "Return a list of Emacs 'autoloads' files in DIRECTORY.
+The files in the list do not have extensions (.el, .elc)."
+ (cl-remove-duplicates
+ (delq nil
+ (mapcar (lambda (file)
+ (when (string-match guix-emacs-autoloads-regexp file)
+ (match-string 1 file)))
+ (directory-files directory 'full-name nil 'no-sort)))
+ :test #'string=))
(defun guix-emacs-subdirs (directory)
"Return list of DIRECTORY subdirectories."
@@ -74,29 +86,33 @@ Return nil if there are no emacs packages installed in PROFILE."
nil)))
;;;###autoload
-(defun guix-emacs-load-autoloads (&optional all)
- "Load autoloads for Emacs packages installed in a user profile.
-Add autoloads directories to `load-path'.
-If ALL is nil, activate only those packages that were installed
-after the last activation, otherwise activate all Emacs packages
-installed in `guix-user-profile'."
- (interactive "P")
- (let* ((autoloads (guix-emacs-find-autoloads))
- (files (if all
- autoloads
- (cl-nset-difference autoloads guix-emacs-autoloads
- :test #'string=))))
- (dolist (file files)
- (cl-pushnew (file-name-directory file) load-path
+(defun guix-emacs-load-autoloads (&optional profile)
+ "Load autoloads for Emacs packages installed in PROFILE.
+If PROFILE is nil, use `guix-user-profile'.
+Add autoloads directories to `load-path'."
+ (interactive (list (guix-profile-prompt)))
+ (let* ((autoloads (guix-emacs-find-autoloads profile))
+ (new-autoloads (cl-nset-difference autoloads
+ guix-emacs-autoloads
+ :test #'string=)))
+ (dolist (file new-autoloads)
+ (cl-pushnew (directory-file-name (file-name-directory file))
+ load-path
:test #'string=)
(load file 'noerror))
- (setq guix-emacs-autoloads autoloads)))
+ (setq guix-emacs-autoloads
+ (append new-autoloads guix-emacs-autoloads))))
(defun guix-emacs-load-autoloads-maybe ()
"Load autoloads for Emacs packages if needed.
See `guix-emacs-activate-after-operation' for details."
(and guix-emacs-activate-after-operation
- (guix-emacs-load-autoloads)))
+ ;; FIXME Since a user can work with a non-current profile (using
+ ;; C-u before `guix-search-by-name' and other commands), emacs
+ ;; packages can be installed to another profile, and the
+ ;; following code will not work (i.e., the autoloads for this
+ ;; profile will not be loaded).
+ (guix-emacs-load-autoloads guix-current-profile)))
(provide 'guix-emacs)
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
index 260c7680f5..1c7e79b954 100644
--- a/emacs/guix-info.el
+++ b/emacs/guix-info.el
@@ -38,6 +38,12 @@
:group 'guix-info
:group 'guix-faces)
+(defface guix-info-heading
+ '((((type tty pc) (class color)) :weight bold)
+ (t :height 1.6 :weight bold :inherit variable-pitch))
+ "Face for headings."
+ :group 'guix-info-faces)
+
(defface guix-info-param-title
'((t :inherit font-lock-type-face))
"Face used for titles of parameters."
@@ -374,7 +380,7 @@ If POS is nil, use the current point position."
(interactive)
(let ((button (button-at (or pos (point)))))
(when button
- (kill-new (button-label button)))))
+ (guix-copy-as-kill (button-label button)))))
(defun guix-info-insert-action-button (label action &optional message
&rest properties)
@@ -416,8 +422,7 @@ See `insert-text-button' for the meaning of PROPERTIES."
:required (id installed non-unique))
(defface guix-package-info-heading
- '((((type tty pc) (class color)) :weight bold)
- (t :height 1.6 :weight bold :inherit variable-pitch))
+ '((t :inherit guix-info-heading))
"Face for package name and version headings."
:group 'guix-package-info-faces)
diff --git a/emacs/guix-init.el b/emacs/guix-init.el
index 4b3d9c281c..1da607034f 100644
--- a/emacs/guix-init.el
+++ b/emacs/guix-init.el
@@ -12,8 +12,9 @@ avoid loading autoloads of Emacs packages installed in
(add-to-list 'load-path (guix-emacs-directory))
(when guix-package-enable-at-startup
- (guix-emacs-load-autoloads 'all))
+ (guix-emacs-load-autoloads))
(add-hook 'scheme-mode-hook 'guix-devel-activate-mode-maybe)
+(add-hook 'shell-mode-hook 'guix-build-log-minor-mode-activate-maybe)
(provide 'guix-init)
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
index 87d214bb4d..560ae6a86f 100644
--- a/emacs/guix-list.el
+++ b/emacs/guix-list.el
@@ -45,6 +45,11 @@
"Face used for file paths."
:group 'guix-list-faces)
+(defface guix-list-time
+ '((t :inherit guix-info-time))
+ "Face used for time stamps."
+ :group 'guix-list-faces)
+
(defcustom guix-list-describe-warning-count 10
"The maximum number of entries for describing without a warning.
If a user wants to describe more than this number of marked
@@ -201,7 +206,8 @@ VAL may be nil."
(defun guix-list-get-time (seconds &optional _)
"Return formatted time string from SECONDS."
- (guix-get-time-string seconds))
+ (guix-get-string (guix-get-time-string seconds)
+ 'guix-list-time))
(defun guix-list-get-file-path (path &optional _)
"Return PATH button specification for `tabulated-list-entries'."
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index e29a0a0acc..7175b103da 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -905,7 +905,7 @@ OUTPUTS is a list of package outputs (may be an empty list)."
"~a packages in profile~%"
count)
count)
- (display-search-paths entries profile))))))))))
+ (display-search-paths entries (list profile)))))))))))
(define (delete-generations* profile generations)
"Delete GENERATIONS from PROFILE.
@@ -991,6 +991,11 @@ Return #t if the shell command was executed successfully."
"Return a list of names of available graph node types."
(map node-type-name %node-types))
+(define (refresh-updater-names)
+ "Return a list of names of available refresh updater types."
+ (map (@ (guix upstream) upstream-updater-name)
+ (@ (guix scripts refresh) %updaters)))
+
(define (lint-checker-names)
"Return a list of names of available lint checkers."
(map (lambda (checker)
diff --git a/emacs/guix-pcomplete.el b/emacs/guix-pcomplete.el
index 4743be59bd..85b267a78d 100644
--- a/emacs/guix-pcomplete.el
+++ b/emacs/guix-pcomplete.el
@@ -128,6 +128,13 @@ subcommands, actions, etc. for this guix COMMAND."
guix-help-parse-regexp-group
"graph" "--list-types"))
+(guix-memoized-defun guix-pcomplete-refresh-updaters ()
+ "Return a list of all available refresh updater types."
+ (guix-pcomplete-run-guix-and-search
+ guix-help-parse-list-regexp
+ guix-help-parse-regexp-group
+ "refresh" "--list-updaters"))
+
;;; Completing
@@ -209,8 +216,8 @@ group - the argument.")
"Complete argument for guix COMMAND."
(cond
((member command
- '("archive" "build" "graph" "edit" "environment"
- "lint" "refresh" "size"))
+ '("archive" "build" "challenge" "edit" "environment"
+ "graph" "lint" "refresh" "size"))
(while t
(pcomplete-here (guix-pcomplete-all-packages))))
(t (pcomplete-here* (pcomplete-entries)))))
@@ -287,9 +294,13 @@ INPUT is the current partially completed string."
(option? "-u" "--user"))
(complete* (pcmpl-unix-user-names)))
- ((and (command? "refresh")
- (option? "-s" "--select"))
- (complete* guix-help-refresh-subsets))
+ ((command? "refresh")
+ (cond
+ ((option? "-s" "--select")
+ (complete* guix-help-refresh-subsets))
+ ((option? "-t" "--type")
+ (guix-pcomplete-complete-comma-args
+ (guix-pcomplete-refresh-updaters)))))
((and (command? "size")
(option? "-m" "--map-file"))
diff --git a/emacs/guix-read.el b/emacs/guix-read.el
index 5a7201c3aa..e60af9c2f7 100644
--- a/emacs/guix-read.el
+++ b/emacs/guix-read.el
@@ -137,6 +137,12 @@ keywords are available:
:single-prompt "Refresh subset: ")
(guix-define-readers
+ :completions-getter guix-refresh-updater-names
+ :multiple-reader guix-read-refresh-updater-names
+ :multiple-prompt "Refresh updater,s: "
+ :multiple-separator ",")
+
+(guix-define-readers
:completions-var guix-help-key-policies
:single-reader guix-read-key-policy
:single-prompt "Key policy: ")
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
index d1f088b6a8..5f3f3ecc10 100644
--- a/emacs/guix-utils.el
+++ b/emacs/guix-utils.el
@@ -226,6 +226,17 @@ single argument."
(while (re-search-forward ,regexp nil t)
,@body)))
+(defun guix-modify (object modifiers)
+ "Apply MODIFIERS to OBJECT.
+OBJECT is passed as an argument to the first function from
+MODIFIERS list, the returned result is passed to the second
+function from the list and so on. Return result of the last
+modifier call."
+ (if (null modifiers)
+ object
+ (guix-modify (funcall (car modifiers) object)
+ (cdr modifiers))))
+
;;; Alist accessors