branch: externals/leaf commit 6f78d673695ceacc3b12cf127ac7b684d85705f4 Author: Caowei <igoo...@gmail.com> Commit: Caowei <igoo...@gmail.com>
Now :bind can accept lambda form binding. #322 --- leaf-tests.el | 8 +++++++- leaf.el | 53 +++++++++++++++++++++-------------------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/leaf-tests.el b/leaf-tests.el index 97b4654742..4a2603357a 100644 --- a/leaf-tests.el +++ b/leaf-tests.el @@ -1161,7 +1161,13 @@ Example: :bind (([(control ?x) (control ?f)] . find-file))) (prog1 'files (unless (fboundp 'find-file) (autoload #'find-file "files" nil t)) - (leaf-keys (([(control ?x) (control ?f)] . find-file))))))) + (leaf-keys (([(control ?x) (control ?f)] . find-file))))) + + ;; you can bind the lambda. + ((leaf color-moccur + :bind ("M-s O" . (lambda () "color-moccur" (interactive) (color-moccur)))) + (prog1 'color-moccur + (leaf-keys (("M-s O" . (lambda () "color-moccur" (interactive) (color-moccur))))))))) (cort-deftest-with-macroexpand leaf/bind* '( diff --git a/leaf.el b/leaf.el index 19a5f3246b..83f289bfb3 100644 --- a/leaf.el +++ b/leaf.el @@ -834,23 +834,26 @@ KEY-NAME may be a vector, in which case it is passed straight to `define-key'. Or it may be a string to be interpreted as spelled-out keystrokes. See documentation of `edmacro-mode' for details. -COMMAND must be an interactive function or lambda form. +COMMAND must be an interactive function. lambda form, menu-item, +or the form that returned one of them also be accepted. +If lambda's docstring in non-nil, shall bind the lambda to the symbol +using docstring; if not, shall bind the lambda to the symbol +generated by `gensym'. KEYMAP, if present, should be a keymap and not a quoted symbol. For example: (leaf-key \"M-h\" #'some-interactive-function my-mode-map) -If PREDICATE is non-nil, it is a form evaluated to determine when a -key should be bound. It must return non-nil in such cases. Emacs can -evaluate this form at any time that it does redisplay or operates on -menu data structures, so you should write it so it can safely be -called at any time. - You can also use [remap COMMAND] as KEY. For example: (leaf-key [remap backward-sentence] 'sh-beginning-of-command)" (let* ((key* (eval key)) - (command* (eval command)) + (psucmd (eval command)) + (symbol (if (eq (car-safe psucmd) 'lambda) + (if (documentation psucmd) + (make-symbol (documentation psucmd)) + (gensym "cmd-")))) + (command* (if symbol (progn (fset symbol psucmd) symbol) psucmd)) (keymap* (eval keymap)) (mmap (or keymap* 'global-map)) (vecp (vectorp key*)) @@ -869,7 +872,7 @@ Bind COMMAND at KEY." (defmacro leaf-keys (bind &optional dryrun-name bind-keymap bind-keymap-pkg) "Bind multiple BIND for KEYMAP defined in PKG. -BIND is (KEY . COMMAND) or (KEY . nil) to unbind KEY. +BIND is (KEY . COMMAND), (KEY . (lambda ...)). (KEY . nil) to unbind KEY. If BIND-KEYMAP is non-nil generate `leaf-key-bind-keymap' instead of `leaf-key'. If BIND-KEYMAP-PKG is passed, require it before binding. @@ -890,8 +893,7 @@ NOTE: BIND can also accept list of these." (condition-case _err (and (listp x) (or (stringp (eval (car x))) - (vectorp (eval (car x)))) - (atom (cdr x))) + (vectorp (eval (car x))))) (error nil)))) recurfn forms bds fns) (setq recurfn @@ -900,23 +902,12 @@ NOTE: BIND can also accept list of these." ((funcall pairp bind) (push (if bind-keymap `(leaf-key-bind-keymap ,(car bind) ,(cdr bind) nil ,bind-keymap-pkg) - `(leaf-key ,(car bind) #',(cdr bind))) + (if (atom (cdr bind)) + `(leaf-key ,(car bind) #',(cdr bind)) + `(leaf-key ,(car bind) ,(cdr bind)))) forms) (push bind bds) (push (cdr bind) fns)) - ((and (listp (car bind)) - (funcall pairp (car bind))) - (mapcar (lambda (elm) - (if (funcall pairp elm) - (progn - (push (if bind-keymap - `(leaf-key-bind-keymap ,(car elm) ,(cdr elm) nil ,bind-keymap-pkg) - `(leaf-key ,(car elm) #',(cdr elm))) - forms) - (push elm bds) - (push (cdr elm) fns)) - (funcall recurfn elm))) - bind)) ((or (keywordp (car bind)) (symbolp (car bind))) (let* ((map (leaf-sym-from-keyword (car bind))) @@ -929,19 +920,17 @@ NOTE: BIND can also accept list of these." (push (cdr elm) fns) (if bind-keymap `(leaf-key-bind-keymap ,(car elm) ,(cdr elm) ',map ,bind-keymap-pkg) - `(leaf-key ,(car elm) #',(cdr elm) ',map))) + (if (atom (cdr elm)) + `(leaf-key ,(car elm) #',(cdr elm) ',map) + `(leaf-key ,(car elm) ,(cdr elm) ',map)))) elmbinds)))) - (push (if pkg - `(,map :package ,pkg ,@elmbinds) - `(,map :package ,dryrun-name ,@elmbinds)) - bds) + (push `(,map :package ,(or `,pkg `,dryrun-name) ,@elmbinds) bds) (when pkg (dolist (elmpkg (if (atom pkg) `(,pkg) pkg)) (unless bind-keymap (setq form `(eval-after-load ',elmpkg ',form))))) (push form forms))) - (t - (mapcar (lambda (elm) (funcall recurfn elm)) bind))))) + (t (mapcar recurfn bind))))) (funcall recurfn bind) (if dryrun-name `'(,(nreverse bds) ,(nreverse fns))