summary refs log tree commit diff
path: root/emacs/guix-utils.el
diff options
context:
space:
mode:
authorAlex Kost <alezost@gmail.com>2015-11-18 22:28:13 +0300
committerAlex Kost <alezost@gmail.com>2016-01-02 17:25:35 +0300
commit4ba476f94992247cd54541ac09b0a516660f20e5 (patch)
treefc7fbed8d2aef413850f469fe96710d775942404 /emacs/guix-utils.el
parent376af769f9cad7f521611c230d192ac639159fda (diff)
downloadguix-4ba476f94992247cd54541ac09b0a516660f20e5.tar.gz
emacs: Add 'guix-keyword-args-let'.
* emacs/guix-utils.el (guix-keyword-args-let): New macro.
  (guix-utils-font-lock-keywords): Add it.
* emacs/guix-base.el (guix-define-buffer-type): Use it.
* emacs/guix-list.el (guix-list-define-entry-type): Use it.
* emacs/guix-read.el (guix-define-readers): Use it.
Diffstat (limited to 'emacs/guix-utils.el')
-rw-r--r--emacs/guix-utils.el52
1 files changed, 51 insertions, 1 deletions
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
index e24b58fb17..3748350b87 100644
--- a/emacs/guix-utils.el
+++ b/emacs/guix-utils.el
@@ -257,6 +257,55 @@ modifier call."
     (guix-modify (funcall (car modifiers) object)
                  (cdr modifiers))))
 
+(defmacro guix-keyword-args-let (args varlist &rest body)
+  "Parse ARGS, bind variables from VARLIST and eval BODY.
+
+Find keyword values in ARGS, bind them to variables according to
+VARLIST, then evaluate BODY.
+
+ARGS is a keyword/value property list.
+
+Each element of VARLIST has a form:
+
+  (SYMBOL KEYWORD [DEFAULT-VALUE])
+
+SYMBOL is a varible name.  KEYWORD is a symbol that will be
+searched in ARGS for an according value.  If the value of KEYWORD
+does not exist, bind SYMBOL to DEFAULT-VALUE or nil.
+
+The rest arguments (that present in ARGS but not in VARLIST) will
+be bound to `%foreign-args' variable.
+
+Example:
+
+  (guix-keyword-args-let '(:two 8 :great ! :guix is)
+      ((one :one 1)
+       (two :two 2)
+       (foo :smth))
+    (list one two foo %foreign-args))
+
+  => (1 8 nil (:guix is :great !))"
+  (declare (indent 2))
+  (let ((args-var (make-symbol "args")))
+    `(let (,@(mapcar (lambda (spec)
+                       (pcase-let ((`(,name ,_ ,val) spec))
+                         (list name val)))
+                     varlist)
+           (,args-var ,args)
+           %foreign-args)
+       (while ,args-var
+         (pcase ,args-var
+           (`(,key ,val . ,rest-args)
+            (cl-case key
+              ,@(mapcar (lambda (spec)
+                          (pcase-let ((`(,name ,key ,_) spec))
+                            `(,key (setq ,name val))))
+                        varlist)
+              (t (setq %foreign-args
+                       (cl-list* key val %foreign-args))))
+            (setq ,args-var rest-args))))
+       ,@body)))
+
 
 ;;; Alist accessors
 
@@ -326,7 +375,8 @@ See `defun' for the meaning of arguments."
 
 (defvar guix-utils-font-lock-keywords
   (eval-when-compile
-    `((,(rx "(" (group "guix-with-indent")
+    `((,(rx "(" (group (or "guix-keyword-args-let"
+                           "guix-with-indent"))
             symbol-end)
        . 1)
       (,(rx "("