me
/
guix
Archived
1
0
Fork 0

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.
master
Alex Kost 2015-11-18 22:28:13 +03:00
parent 376af769f9
commit 4ba476f949
4 changed files with 131 additions and 109 deletions

View File

@ -382,21 +382,13 @@ following keywords are available:
(buf-name-var (intern (concat prefix "-buffer-name"))) (buf-name-var (intern (concat prefix "-buffer-name")))
(revert-var (intern (concat prefix "-revert-no-confirm"))) (revert-var (intern (concat prefix "-revert-no-confirm")))
(history-var (intern (concat prefix "-history-size"))) (history-var (intern (concat prefix "-history-size")))
(params-var (intern (concat prefix "-required-params"))) (params-var (intern (concat prefix "-required-params"))))
(buf-name-val (format "*Guix %s %s*" Entry-type-str Buf-type-str)) (guix-keyword-args-let args
(revert-val nil) ((params-val :required '(id))
(history-val 20) (history-val :history-size 20)
(params-val '(id))) (revert-val :revert)
(buf-name-val :buffer-name
;; Process the keyword args. (format "*Guix %s %s*" Entry-type-str Buf-type-str)))
(while (keywordp (car args))
(pcase (pop args)
(`:required (setq params-val (pop args)))
(`:history-size (setq history-val (pop args)))
(`:revert (setq revert-val (pop args)))
(`:buffer-name (setq buf-name-val (pop args)))
(_ (pop args))))
`(progn `(progn
(defgroup ,group nil (defgroup ,group nil
,(concat Buf-type-str " buffer with " entry-str ".") ,(concat Buf-type-str " buffer with " entry-str ".")
@ -438,7 +430,7 @@ following keywords are available:
"\\{" mode-map-str "}") "\\{" mode-map-str "}")
(setq-local revert-buffer-function 'guix-revert-buffer) (setq-local revert-buffer-function 'guix-revert-buffer)
(setq-local guix-history-size ,history-var) (setq-local guix-history-size ,history-var)
(and (fboundp ',mode-init-fun) (,mode-init-fun)))))) (and (fboundp ',mode-init-fun) (,mode-init-fun)))))))
(put 'guix-define-buffer-type 'lisp-indent-function 'defun) (put 'guix-define-buffer-type 'lisp-indent-function 'defun)

View File

@ -416,19 +416,11 @@ This macro defines the following functions:
(prefix (concat "guix-" entry-type-str "-list")) (prefix (concat "guix-" entry-type-str "-list"))
(mode-str (concat prefix "-mode")) (mode-str (concat prefix "-mode"))
(init-fun (intern (concat prefix "-mode-initialize"))) (init-fun (intern (concat prefix "-mode-initialize")))
(marks-var (intern (concat prefix "-mark-alist"))) (marks-var (intern (concat prefix "-mark-alist"))))
(marks-val nil) (guix-keyword-args-let args
(sort-key nil) ((sort-key :sort-key)
(invert-sort nil)) (invert-sort :invert-sort)
(marks-val :marks))
;; Process the keyword args.
(while (keywordp (car args))
(pcase (pop args)
(`:sort-key (setq sort-key (pop args)))
(`:invert-sort (setq invert-sort (pop args)))
(`:marks (setq marks-val (pop args)))
(_ (pop args))))
`(progn `(progn
(defvar ,marks-var ',marks-val (defvar ,marks-var ',marks-val
,(concat "Alist of additional marks for `" mode-str "'.\n" ,(concat "Alist of additional marks for `" mode-str "'.\n"
@ -454,7 +446,7 @@ This macro defines the following functions:
(guix-list-tabulated-format ',entry-type)) (guix-list-tabulated-format ',entry-type))
(setq-local guix-list-mark-alist (setq-local guix-list-mark-alist
(append guix-list-mark-alist ,marks-var)) (append guix-list-mark-alist ,marks-var))
(tabulated-list-init-header))))) (tabulated-list-init-header))))))
(put 'guix-list-define-entry-type 'lisp-indent-function 'defun) (put 'guix-list-define-entry-type 'lisp-indent-function 'defun)

View File

@ -66,26 +66,14 @@ keywords are available:
`<multiple-reader-name>-string' function returning a string `<multiple-reader-name>-string' function returning a string
of multiple values separated the specified separator will be of multiple values separated the specified separator will be
defined." defined."
(let (completions-var (guix-keyword-args-let args
completions-getter ((completions-var :completions-var)
single-reader (completions-getter :completions-getter)
single-prompt (single-reader :single-reader)
multiple-reader (single-prompt :single-prompt)
multiple-prompt (multiple-reader :multiple-reader)
multiple-separator) (multiple-prompt :multiple-prompt)
(multiple-separator :multiple-separator))
;; Process the keyword args.
(while (keywordp (car args))
(pcase (pop args)
(`:completions-var (setq completions-var (pop args)))
(`:completions-getter (setq completions-getter (pop args)))
(`:single-reader (setq single-reader (pop args)))
(`:single-prompt (setq single-prompt (pop args)))
(`:multiple-reader (setq multiple-reader (pop args)))
(`:multiple-prompt (setq multiple-prompt (pop args)))
(`:multiple-separator (setq multiple-separator (pop args)))
(_ (pop args))))
(let ((completions (let ((completions
(cond ((and completions-var completions-getter) (cond ((and completions-var completions-getter)
`(or ,completions-var `(or ,completions-var

View File

@ -257,6 +257,55 @@ modifier call."
(guix-modify (funcall (car modifiers) object) (guix-modify (funcall (car modifiers) object)
(cdr modifiers)))) (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 ;;; Alist accessors
@ -326,7 +375,8 @@ See `defun' for the meaning of arguments."
(defvar guix-utils-font-lock-keywords (defvar guix-utils-font-lock-keywords
(eval-when-compile (eval-when-compile
`((,(rx "(" (group "guix-with-indent") `((,(rx "(" (group (or "guix-keyword-args-let"
"guix-with-indent"))
symbol-end) symbol-end)
. 1) . 1)
(,(rx "(" (,(rx "("