这是一个让事情顺利进行的最小片段:
(define-prefix-command 'foo)
(define-key foo "a" 'bar)
(define-key foo "b" 'baz)
(global-set-key (kbd "C-M-r") 'foo)
Run Code Online (Sandbox Code Playgroud)
现在,foo
当我按下时,我可以"调用" 键盘图C-M-r.但我想知道如何从代码中做到这一点,例如:
(funcall (lambda-from-keymap 'foo))
Run Code Online (Sandbox Code Playgroud)
这个电话后,我期待的焦点是在小缓冲区,等着,等着 a,或者b还是C-h要输入.这样的事情可能吗?
您可以使用read-key-sequence
和lookup-key
来实现:
(defun call-keymap (map &optional prompt)
"Read a key sequence and call the command it's bound to in MAP."
;; Note: MAP must be a symbol so we can trick `describe-bindings' into giving
;; us a nice help text.
(let* ((overriding-local-map `(keymap (,map . ,map)))
(help-form `(describe-bindings ,(vector map)))
(key (read-key-sequence prompt))
(cmd (lookup-key map key t)))
(if (functionp cmd) (call-interactively cmd)
(user-error "%s is undefined" key))))
Run Code Online (Sandbox Code Playgroud)
如果你点击C-h read-key-sequence
仍然等待你完成序列。我认为你可以通过循环来模拟 Emacs 的正常行为read-key
,尽管它有点复杂。
像这样使用它:
(defun bar () (interactive) (message "you called bar"))
(defun baz () (interactive) (message "you called baz"))
(define-prefix-command 'foo)
(define-key foo "a" 'bar)
(define-key foo "b" 'baz)
(global-set-key (kbd "C-M-r") 'foo)
(defun call-foo ()
(interactive)
;; Note: pass the symbol form of the keymap so we can give nice help
(call-keymap 'foo "enter a foo command: "))
(global-set-key (kbd "C-c f") 'call-foo)
Run Code Online (Sandbox Code Playgroud)
你需要有foo
互动。我这样做是使用:
(global-set-key (kbd "C-M-r") (lambda () (interactive) ( foo)))
Run Code Online (Sandbox Code Playgroud)
这应该可以解决你的问题。