diff options
Diffstat (limited to 'emacs')
-rw-r--r-- | emacs/guix-backend.el | 2 | ||||
-rw-r--r-- | emacs/guix-base.el | 18 | ||||
-rw-r--r-- | emacs/guix-build-log.el | 58 | ||||
-rw-r--r-- | emacs/guix-command.el | 159 | ||||
-rw-r--r-- | emacs/guix-devel.el | 2 | ||||
-rw-r--r-- | emacs/guix-emacs.el | 52 | ||||
-rw-r--r-- | emacs/guix-info.el | 11 | ||||
-rw-r--r-- | emacs/guix-init.el | 3 | ||||
-rw-r--r-- | emacs/guix-list.el | 8 | ||||
-rw-r--r-- | emacs/guix-main.scm | 7 | ||||
-rw-r--r-- | emacs/guix-pcomplete.el | 21 | ||||
-rw-r--r-- | emacs/guix-read.el | 6 | ||||
-rw-r--r-- | emacs/guix-utils.el | 11 |
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 |