From c10521e97679c35a40926084e049445cc5053254 Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Wed, 12 Aug 2015 15:28:55 +0300 Subject: emacs: Add and use 'guix-while-search'. * emacs/guix-utils.el (guix-while-search): New macro. * emacs/guix-pcomplete.el (guix-pcomplete-run-guix-and-search): Use it. * emacs/guix-prettify.el (guix-prettify-decompose-buffer): Likewise. --- emacs/guix-utils.el | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index dc0c58a114..8a0673a3a0 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -160,6 +160,14 @@ accessed with KEYS." (find-file file) (message "File '%s' does not exist." file))) +(defmacro guix-while-search (regexp &rest body) + "Evaluate BODY after each search for REGEXP in the current buffer." + (declare (indent 1) (debug t)) + `(save-excursion + (goto-char (point-min)) + (while (re-search-forward ,regexp nil t) + ,@body))) + ;;; Diff -- cgit v1.2.3 From 1ce96dd9271445133b920cff81bbb44085a5fe7c Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Wed, 12 Aug 2015 15:44:22 +0300 Subject: emacs: Add and use 'guix-concat-strings'. * emacs/guix-utils.el (guix-concat-strings): New function. * emacs/guix-pcomplete.el (guix-pcomplete-short-options): Use it. * emacs/guix-base.el (guix-get-package-strings): Likewise. --- emacs/guix-base.el | 2 +- emacs/guix-pcomplete.el | 2 +- emacs/guix-utils.el | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-base.el b/emacs/guix-base.el index 2212dd746f..76974e12ab 100644 --- a/emacs/guix-base.el +++ b/emacs/guix-base.el @@ -913,7 +913,7 @@ ENTRIES is a list of package entries to get info about packages." (concat (guix-get-full-name entry) (when outputs (concat ":" - (mapconcat #'identity outputs ","))) + (guix-concat-strings outputs ","))) (when location (concat "\t(" location ")"))))))) specs))) diff --git a/emacs/guix-pcomplete.el b/emacs/guix-pcomplete.el index 0049c94d38..2b9249554b 100644 --- a/emacs/guix-pcomplete.el +++ b/emacs/guix-pcomplete.el @@ -147,7 +147,7 @@ subcommands, actions, etc. for this guix COMMAND." "Return a string with available short options for guix COMMAND." guix-pcomplete-parse-short-option-regexp (lambda (list) - (mapconcat #'identity list ""))) + (guix-concat-strings list ""))) (guix-memoized-defun guix-pcomplete-all-packages () "Return a list of all available Guix packages." diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index 8a0673a3a0..df6636c139 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -128,6 +128,22 @@ split it into several short lines." (fill-region (point-min) (point-max))) (buffer-string))) +(defun guix-concat-strings (strings separator &optional location) + "Return new string by concatenating STRINGS with SEPARATOR. +If LOCATION is a symbol `head', add another SEPARATOR to the +beginning of the returned string; if `tail' - add SEPARATOR to +the end of the string; if nil, do not add SEPARATOR; otherwise +add both to the end and to the beginning." + (let ((str (mapconcat #'identity strings separator))) + (cond ((null location) + str) + ((eq location 'head) + (concat separator str)) + ((eq location 'tail) + (concat str separator)) + (t + (concat separator str separator))))) + (defun guix-completing-read-multiple (prompt table &optional predicate require-match initial-input hist def inherit-input-method) -- cgit v1.2.3 From 009d6388e6ba83d903c9e3756daa71251ca1b8e6 Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 16 Aug 2015 11:09:39 +0300 Subject: emacs: Add utils to make symbol and string for guix command. * emacs/guix-utils.el (guix-shell-quote-argument, guix-command-symbol, guix-command-string): New functions. --- emacs/guix-utils.el | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index df6636c139..68cad8878d 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -144,6 +144,25 @@ add both to the end and to the beginning." (t (concat separator str separator))))) +(defun guix-shell-quote-argument (argument) + "Quote shell command ARGUMENT. +This function is similar to `shell-quote-argument', but less strict." + (if (equal argument "") + "''" + (replace-regexp-in-string + "\n" "'\n'" + (replace-regexp-in-string + (rx (not (any alnum "-=,./\n"))) "\\\\\\&" argument)))) + +(defun guix-command-symbol (&optional args) + "Return symbol by concatenating 'guix' and ARGS (strings)." + (intern (guix-concat-strings (cons "guix" args) "-"))) + +(defun guix-command-string (&optional args) + "Return 'guix ARGS ...' string with quoted shell arguments." + (let ((args (mapcar #'guix-shell-quote-argument args))) + (guix-concat-strings (cons "guix" args) " "))) + (defun guix-completing-read-multiple (prompt table &optional predicate require-match initial-input hist def inherit-input-method) -- cgit v1.2.3 From ad0f31f6a514d29b2f734069d5c3b2a7a6cd2a82 Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 16 Aug 2015 11:11:37 +0300 Subject: emacs: Add utils to copy guix command. * emacs/guix-utils.el (guix-copy-as-kill, guix-copy-command-as-kill): New functions. --- emacs/guix-utils.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index 68cad8878d..3157f6359b 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -163,6 +163,18 @@ This function is similar to `shell-quote-argument', but less strict." (let ((args (mapcar #'guix-shell-quote-argument args))) (guix-concat-strings (cons "guix" args) " "))) +(defun guix-copy-as-kill (string &optional no-message?) + "Put STRING into `kill-ring'. +If NO-MESSAGE? is non-nil, do not display a message about it." + (kill-new string) + (unless no-message? + (message "'%s' has been added to kill ring." string))) + +(defun guix-copy-command-as-kill (args &optional no-message?) + "Put 'guix ARGS ...' string into `kill-ring'. +See also `guix-copy-as-kill'." + (guix-copy-as-kill (guix-command-string args) no-message?)) + (defun guix-completing-read-multiple (prompt table &optional predicate require-match initial-input hist def inherit-input-method) -- cgit v1.2.3 From e767752c79975d30341f71d7f9de88edeb192d59 Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Wed, 12 Aug 2015 15:37:20 +0300 Subject: emacs: Add 'guix-any'. * emacs/guix-utils.el (guix-any): New function. --- emacs/guix-utils.el | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index 3157f6359b..fb1ca60654 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -215,6 +215,14 @@ accessed with KEYS." (while (re-search-forward ,regexp nil t) ,@body))) +(defun guix-any (pred lst) + "Test whether any element from LST satisfies PRED. +If so, return the return value from the successful PRED call. +Return nil otherwise." + (when lst + (or (funcall pred (car lst)) + (guix-any pred (cdr lst))))) + ;;; Diff -- cgit v1.2.3 From 6543601fa05b629b387d1da0b5fc5fe81ecaf24c Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 16 Aug 2015 06:46:52 +0300 Subject: emacs: Add 'guix-memoized-defalias' macro. * emacs/guix-utils.el (guix-memoized-defalias): New macro. (guix-memoized-font-lock-keywords): New variable. --- emacs/guix-utils.el | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index fb1ca60654..0b8a760af8 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -262,6 +262,27 @@ See `defun' for the meaning of arguments." (mapconcat #'symbol-name arglist " ") docstring))) +(defmacro guix-memoized-defalias (symbol definition &optional docstring) + "Set SYMBOL's function definition to memoized version of DEFINITION." + (declare (doc-string 3) (indent 1)) + `(defalias ',symbol + (guix-memoize #',definition) + ,(or docstring + (format "Memoized version of `%S'." definition)))) + +(defvar guix-memoized-font-lock-keywords + (eval-when-compile + `((,(rx "(" + (group "guix-memoized-" (or "defun" "defalias")) + symbol-end + (zero-or-more blank) + (zero-or-one + (group (one-or-more (or (syntax word) (syntax symbol)))))) + (1 font-lock-keyword-face) + (2 font-lock-function-name-face nil t))))) + +(font-lock-add-keywords 'emacs-lisp-mode guix-memoized-font-lock-keywords) + (provide 'guix-utils) ;;; guix-utils.el ends here -- cgit v1.2.3 From 51dac383392a723aa77b0496cf12c593b013cb2b Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 16 Aug 2015 07:11:57 +0300 Subject: emacs: Add and use alist accessors. * emacs/guix-utils.el (guix-define-alist-accessor): New macro. (guix-assq-value, guix-assoc-value): New functions. (guix-get-key-val): Remove. * emacs/guix-base.el: Replace 'guix-get-key-val' with 'guix-assq-value' everywhere. * emacs/guix-info.el: Likewise. * emacs/guix-list.el: Likewise. * emacs/guix-messages.el: Likewise. --- emacs/guix-base.el | 22 +++++++++++----------- emacs/guix-info.el | 48 ++++++++++++++++++++++++------------------------ emacs/guix-list.el | 50 +++++++++++++++++++++++++------------------------- emacs/guix-messages.el | 8 ++++---- emacs/guix-utils.el | 27 +++++++++++++++++++-------- 5 files changed, 83 insertions(+), 72 deletions(-) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-base.el b/emacs/guix-base.el index 9cec510406..4c7782dd53 100644 --- a/emacs/guix-base.el +++ b/emacs/guix-base.el @@ -89,8 +89,8 @@ Each element of the list has a form: (defun guix-get-param-title (entry-type param) "Return title of an ENTRY-TYPE entry parameter PARAM." - (or (guix-get-key-val guix-param-titles - entry-type param) + (or (guix-assq-value guix-param-titles + entry-type param) (prog1 (symbol-name param) (message "Couldn't find title for '%S %S'." entry-type param)))) @@ -102,15 +102,15 @@ Each element of the list has a form: (defun guix-get-full-name (entry &optional output) "Return name specification of the package ENTRY and OUTPUT." - (guix-get-name-spec (guix-get-key-val entry 'name) - (guix-get-key-val entry 'version) + (guix-get-name-spec (guix-assq-value entry 'name) + (guix-assq-value entry 'version) output)) (defun guix-entry-to-specification (entry) "Return name specification by the package or output ENTRY." - (guix-get-name-spec (guix-get-key-val entry 'name) - (guix-get-key-val entry 'version) - (guix-get-key-val entry 'output))) + (guix-get-name-spec (guix-assq-value entry 'name) + (guix-assq-value entry 'version) + (guix-assq-value entry 'output))) (defun guix-entries-to-specifications (entries) "Return name specifications by the package or output ENTRIES." @@ -120,13 +120,13 @@ Each element of the list has a form: (defun guix-get-installed-outputs (entry) "Return list of installed outputs for the package ENTRY." (mapcar (lambda (installed-entry) - (guix-get-key-val installed-entry 'output)) - (guix-get-key-val entry 'installed))) + (guix-assq-value installed-entry 'output)) + (guix-assq-value entry 'installed))) (defun guix-get-entry-by-id (id entries) "Return entry from ENTRIES by entry ID." (cl-find-if (lambda (entry) - (equal id (guix-get-key-val entry 'id))) + (equal id (guix-assq-value entry 'id))) entries)) (defun guix-get-package-id-and-output-by-output-id (oid) @@ -934,7 +934,7 @@ ENTRIES is a list of package entries to get info about packages." (outputs (cdr spec)) (entry (guix-get-entry-by-id id entries))) (when entry - (let ((location (guix-get-key-val entry 'location))) + (let ((location (guix-assq-value entry 'location))) (concat (guix-get-full-name entry) (when outputs (concat ":" diff --git a/emacs/guix-info.el b/emacs/guix-info.el index f17ce01ab6..4bdd62a6a5 100644 --- a/emacs/guix-info.el +++ b/emacs/guix-info.el @@ -178,13 +178,13 @@ The order of displayed parameters is the same as in this list.") (defun guix-info-get-insert-methods (entry-type param) "Return list of insert methods for parameter PARAM of ENTRY-TYPE. See `guix-info-insert-methods' for details." - (guix-get-key-val guix-info-insert-methods - entry-type param)) + (guix-assq-value guix-info-insert-methods + entry-type param)) (defun guix-info-get-displayed-params (entry-type) "Return parameters of ENTRY-TYPE that should be displayed." - (guix-get-key-val guix-info-displayed-params - entry-type)) + (guix-assq-value guix-info-displayed-params + entry-type)) (defun guix-info-get-indent (&optional level) "Return `guix-info-indent' \"multiplied\" by LEVEL spaces. @@ -232,7 +232,7 @@ Use `guix-info-insert-ENTRY-TYPE-function' or "Insert title and value of a PARAM at point. ENTRY is alist with parameters and their values. ENTRY-TYPE is a type of ENTRY." - (let ((val (guix-get-key-val entry param))) + (let ((val (guix-assq-value entry param))) (unless (and guix-info-ignore-empty-vals (null val)) (let* ((title (guix-get-param-title entry-type param)) (insert-methods (guix-info-get-insert-methods entry-type param)) @@ -492,12 +492,12 @@ filling them to fit the window." (defun guix-package-info-insert-heading (entry) "Insert the heading for package ENTRY. Show package name, version, and `guix-package-info-heading-params'." - (guix-format-insert (concat (guix-get-key-val entry 'name) " " - (guix-get-key-val entry 'version)) + (guix-format-insert (concat (guix-assq-value entry 'name) " " + (guix-assq-value entry 'version)) 'guix-package-info-heading) (insert "\n\n") (mapc (lambda (param) - (let ((val (guix-get-key-val entry param)) + (let ((val (guix-assq-value entry param)) (face (guix-get-symbol (symbol-name param) 'info 'package))) (when val @@ -587,10 +587,10 @@ If nil, insert installed info in a default way.") (defun guix-package-info-insert-outputs (outputs entry) "Insert OUTPUTS from package ENTRY at point." - (and (guix-get-key-val entry 'obsolete) + (and (guix-assq-value entry 'obsolete) (guix-package-info-insert-obsolete-text)) - (and (guix-get-key-val entry 'non-unique) - (guix-get-key-val entry 'installed) + (and (guix-assq-value entry 'non-unique) + (guix-assq-value entry 'installed) (guix-package-info-insert-non-unique-text (guix-get-full-name entry))) (insert "\n") @@ -617,11 +617,11 @@ If nil, insert installed info in a default way.") Make some fancy text with buttons and additional stuff if the current OUTPUT is installed (if there is such output in `installed' parameter of a package ENTRY)." - (let* ((installed (guix-get-key-val entry 'installed)) - (obsolete (guix-get-key-val entry 'obsolete)) + (let* ((installed (guix-assq-value entry 'installed)) + (obsolete (guix-assq-value entry 'obsolete)) (installed-entry (cl-find-if (lambda (entry) - (string= (guix-get-key-val entry 'output) + (string= (guix-assq-value entry 'output) output)) installed)) (action-type (if installed-entry 'delete 'install))) @@ -655,8 +655,8 @@ ENTRY is an alist with package info." (current-buffer))) (concat type-str " '" full-name "'") 'action-type type - 'id (or (guix-get-key-val entry 'package-id) - (guix-get-key-val entry 'id)) + 'id (or (guix-assq-value entry 'package-id) + (guix-assq-value entry 'id)) 'output output))) (defun guix-package-info-insert-output-path (path &optional _) @@ -720,7 +720,7 @@ PACKAGE-ID is an ID of the package which source to show." (entries (cl-substitute-if new-entry (lambda (entry) - (equal (guix-get-key-val entry 'id) + (equal (guix-assq-value entry 'id) entry-id)) guix-entries :count 1))) @@ -746,9 +746,9 @@ SOURCE is a list of URLs." (guix-info-insert-indent) (if (null source) (guix-format-insert nil) - (let* ((source-file (guix-get-key-val entry 'source-file)) - (entry-id (guix-get-key-val entry 'id)) - (package-id (or (guix-get-key-val entry 'package-id) + (let* ((source-file (guix-assq-value entry 'source-file)) + (entry-id (guix-assq-value entry 'id)) + (package-id (or (guix-assq-value entry 'package-id) entry-id))) (if (null source-file) (guix-info-insert-action-button @@ -798,13 +798,13 @@ If nil, insert output in a default way.") "Insert output VERSION and obsolete text if needed at point." (guix-info-insert-val-default version 'guix-package-info-version) - (and (guix-get-key-val entry 'obsolete) + (and (guix-assq-value entry 'obsolete) (guix-package-info-insert-obsolete-text))) (defun guix-output-info-insert-output (output entry) "Insert OUTPUT and action buttons at point." - (let* ((installed (guix-get-key-val entry 'installed)) - (obsolete (guix-get-key-val entry 'obsolete)) + (let* ((installed (guix-assq-value entry 'installed)) + (obsolete (guix-assq-value entry 'obsolete)) (action-type (if installed 'delete 'install))) (guix-info-insert-val-default output @@ -874,7 +874,7 @@ If nil, insert generation in a default way.") (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)))) + 'number (guix-assq-value entry 'number)))) (provide 'guix-info) diff --git a/emacs/guix-list.el b/emacs/guix-list.el index e84d60a0aa..abb02326af 100644 --- a/emacs/guix-list.el +++ b/emacs/guix-list.el @@ -1,6 +1,6 @@ ;;; guix-list.el --- List buffers for displaying entries -*- lexical-binding: t -*- -;; Copyright © 2014 Alex Kost +;; Copyright © 2014, 2015 Alex Kost ;; This file is part of GNU Guix. @@ -110,13 +110,13 @@ parameters and their values).") (defun guix-list-get-param-title (entry-type param) "Return title of an ENTRY-TYPE entry parameter PARAM." - (or (guix-get-key-val guix-list-column-titles - entry-type param) + (or (guix-assq-value guix-list-column-titles + entry-type param) (guix-get-param-title entry-type param))) (defun guix-list-get-column-format (entry-type) "Return column format for ENTRY-TYPE." - (guix-get-key-val guix-list-column-format entry-type)) + (guix-assq-value guix-list-column-format entry-type)) (defun guix-list-get-displayed-params (entry-type) "Return list of parameters of ENTRY-TYPE that should be displayed." @@ -170,7 +170,7 @@ ENTRIES should have a form of `guix-entries'." Values are taken from ENTRIES which should have the form of `guix-entries'." (mapcar (lambda (entry) - (list (guix-get-key-val entry 'id) + (list (guix-assq-value entry 'id) (guix-list-get-tabulated-entry entry entry-type))) entries)) @@ -180,9 +180,9 @@ Parameters are taken from ENTRY of ENTRY-TYPE." (guix-list-make-tabulated-vector entry-type (lambda (param _) - (let ((val (guix-get-key-val entry param)) - (fun (guix-get-key-val guix-list-column-value-methods - entry-type param))) + (let ((val (guix-assq-value entry param)) + (fun (guix-assq-value guix-list-column-value-methods + entry-type param))) (if fun (funcall fun val entry) (guix-get-string val)))))) @@ -221,7 +221,7 @@ VAL may be nil." (guix-package-list-mode (guix-list-current-id)) (guix-output-list-mode - (guix-get-key-val (guix-list-current-entry) 'package-id)))) + (guix-assq-value (guix-list-current-entry) 'package-id)))) (defun guix-list-for-each-line (fun &rest args) "Call FUN with ARGS for each entry line." @@ -262,7 +262,7 @@ ARGS is a list of additional values.") (defsubst guix-list-get-mark (name) "Return mark character by its NAME." - (or (guix-get-key-val guix-list-mark-alist name) + (or (guix-assq-value guix-list-mark-alist name) (error "Mark '%S' not found" name))) (defsubst guix-list-get-mark-string (name) @@ -355,8 +355,8 @@ With ARG, unmark all lines." "Put marks according to `guix-list-mark-alist'." (guix-list-for-each-line (lambda () - (let ((mark-name (car (guix-get-key-val guix-list-marked - (guix-list-current-id))))) + (let ((mark-name (car (guix-assq-value guix-list-marked + (guix-list-current-id))))) (tabulated-list-put-tag (guix-list-get-mark-string (or mark-name 'empty))))))) @@ -524,16 +524,16 @@ likely)." Colorize it with `guix-package-list-installed' or `guix-package-list-obsolete' if needed." (guix-get-string name - (cond ((guix-get-key-val entry 'obsolete) + (cond ((guix-assq-value entry 'obsolete) 'guix-package-list-obsolete) - ((guix-get-key-val entry 'installed) + ((guix-assq-value entry 'installed) 'guix-package-list-installed)))) (defun guix-package-list-get-installed-outputs (installed &optional _) "Return string with outputs from INSTALLED entries." (guix-get-string (mapcar (lambda (entry) - (guix-get-key-val entry 'output)) + (guix-assq-value entry 'output)) installed))) (defun guix-package-list-marking-check () @@ -562,7 +562,7 @@ be separated with \",\")." (interactive "P") (guix-package-list-marking-check) (let* ((entry (guix-list-current-entry)) - (all (guix-get-key-val entry 'outputs)) + (all (guix-assq-value entry 'outputs)) (installed (guix-get-installed-outputs entry)) (available (cl-set-difference all installed :test #'string=))) (or available @@ -597,7 +597,7 @@ be separated with \",\")." (installed (guix-get-installed-outputs entry))) (or installed (user-error "This package is not installed")) - (when (or (guix-get-key-val entry 'obsolete) + (when (or (guix-assq-value entry 'obsolete) (y-or-n-p "This package is not obsolete. Try to upgrade it anyway? ")) (guix-package-list-mark-outputs 'upgrade installed @@ -611,14 +611,14 @@ accept an entry as argument." (guix-package-list-marking-check) (let ((obsolete (cl-remove-if-not (lambda (entry) - (guix-get-key-val entry 'obsolete)) + (guix-assq-value entry 'obsolete)) guix-entries))) (guix-list-for-each-line (lambda () (let* ((id (guix-list-current-id)) (entry (cl-find-if (lambda (entry) - (equal id (guix-get-key-val entry 'id))) + (equal id (guix-assq-value entry 'id))) obsolete))) (when entry (funcall fun entry))))))) @@ -682,7 +682,7 @@ The specification is suitable for `guix-process-package-actions'." (interactive) (guix-package-list-marking-check) (let* ((entry (guix-list-current-entry)) - (installed (guix-get-key-val entry 'installed))) + (installed (guix-assq-value entry 'installed))) (if installed (user-error "This output is already installed") (guix-list--mark 'install t)))) @@ -692,7 +692,7 @@ The specification is suitable for `guix-process-package-actions'." (interactive) (guix-package-list-marking-check) (let* ((entry (guix-list-current-entry)) - (installed (guix-get-key-val entry 'installed))) + (installed (guix-assq-value entry 'installed))) (if installed (guix-list--mark 'delete t) (user-error "This output is not installed")))) @@ -702,10 +702,10 @@ The specification is suitable for `guix-process-package-actions'." (interactive) (guix-package-list-marking-check) (let* ((entry (guix-list-current-entry)) - (installed (guix-get-key-val entry 'installed))) + (installed (guix-assq-value entry 'installed))) (or installed (user-error "This output is not installed")) - (when (or (guix-get-key-val entry 'obsolete) + (when (or (guix-assq-value entry 'obsolete) (y-or-n-p "This output is not obsolete. Try to upgrade it anyway? ")) (guix-list--mark 'upgrade t)))) @@ -777,8 +777,8 @@ VAL is a boolean value." "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))) + (current (guix-assq-value entry 'current)) + (number (guix-assq-value entry 'number))) (if current (user-error "This generation is already the current one") (guix-switch-to-generation guix-profile number (current-buffer))))) diff --git a/emacs/guix-messages.el b/emacs/guix-messages.el index bd985a0670..2bf99de6fa 100644 --- a/emacs/guix-messages.el +++ b/emacs/guix-messages.el @@ -1,6 +1,6 @@ ;;; guix-messages.el --- Minibuffer messages -;; Copyright © 2014 Alex Kost +;; Copyright © 2014, 2015 Alex Kost ;; This file is part of GNU Guix. @@ -186,14 +186,14 @@ (defun guix-result-message (profile entries entry-type search-type search-vals) "Display an appropriate message after displaying ENTRIES." - (let* ((type-spec (guix-get-key-val guix-messages - entry-type search-type)) + (let* ((type-spec (guix-assq-value guix-messages + entry-type search-type)) (fun-or-count-spec (car type-spec))) (if (functionp fun-or-count-spec) (funcall fun-or-count-spec profile entries search-vals) (let* ((count (length entries)) (count-key (if (> count 1) 'many count)) - (msg-spec (guix-get-key-val type-spec count-key)) + (msg-spec (guix-assq-value type-spec count-key)) (msg (car msg-spec)) (args (cdr msg-spec))) (mapc (lambda (subst) diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index 0b8a760af8..78ea3545c6 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -193,14 +193,6 @@ Return time value." (require 'org) (org-read-date nil t nil prompt)) -(defun guix-get-key-val (alist &rest keys) - "Return value from ALIST by KEYS. -ALIST is alist of alists of alists ... which can be consecutively -accessed with KEYS." - (let ((val alist)) - (dolist (key keys val) - (setq val (cdr (assq key val)))))) - (defun guix-find-file (file) "Find FILE if it exists." (if (file-exists-p file) @@ -223,6 +215,25 @@ Return nil otherwise." (or (funcall pred (car lst)) (guix-any pred (cdr lst))))) + +;;; Alist accessors + +(defmacro guix-define-alist-accessor (name assoc-fun) + "Define NAME function to access alist values using ASSOC-FUN." + `(defun ,name (alist &rest keys) + ,(format "Return value from ALIST by KEYS using `%s'. +ALIST is alist of alists of alists ... which can be consecutively +accessed with KEYS." + assoc-fun) + (if (or (null alist) (null keys)) + alist + (apply #',name + (cdr (,assoc-fun (car keys) alist)) + (cdr keys))))) + +(guix-define-alist-accessor guix-assq-value assq) +(guix-define-alist-accessor guix-assoc-value assoc) + ;;; Diff -- cgit v1.2.3 From 32c0b6d78ce815350acf2f6879579d5b628c437f Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 30 Aug 2015 18:51:09 +0300 Subject: emacs: Allow users to choose a 'find-file' function. * emacs/guix-utils.el (guix-find-file-function): New variable. (guix-find-file): Use it. --- emacs/guix-utils.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'emacs/guix-utils.el') diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el index 78ea3545c6..c1ce954f8f 100644 --- a/emacs/guix-utils.el +++ b/emacs/guix-utils.el @@ -193,10 +193,19 @@ Return time value." (require 'org) (org-read-date nil t nil prompt)) +(defcustom guix-find-file-function #'find-file + "Function used to find a file. +The function is called by `guix-find-file' with a file name as a +single argument." + :type '(choice (function-item find-file) + (function-item org-open-file) + (function :tag "Other function")) + :group 'guix) + (defun guix-find-file (file) "Find FILE if it exists." (if (file-exists-p file) - (find-file file) + (funcall guix-find-file-function file) (message "File '%s' does not exist." file))) (defmacro guix-while-search (regexp &rest body) -- cgit v1.2.3