【发布时间】:2019-11-30 10:33:39
【问题描述】:
我是一个新的 emacs 用户。并尝试编写一些 Elisp 来更好地学习这个软件。虽然我遇到了一些问题。
我想在progn 上使用apply 按顺序运行函数列表。但我得到如下错误。我很困惑,需要一些帮助来告诉我如何在 Elisp 中实现这一点,谢谢。
(progn
(+ 1 1)
(+ 2 2)
)
;; => 4
(apply #'progn ((+ 1 1) (+ 2 2)))
;; => Invalid function: (+ 1 1)
(apply #'progn ('(+ 1 1) '(+ 2 2)))
;; => Invalid function: '(+ 1 1)
(apply #'progn '((+ 1 1) (+ 2 2)))
;; => Invalid function: #<subr progn>
我像上面那样玩玩具,因为我从 vim 来到 emacs。所以我安装了邪恶和邪恶的号码。并想要返回 vim 编号 inc 和 dec 绑定 C-a、C-x。所以我写了一个宏来避免样板。
(defmacro set-evil-number-keymap (key-set func &rest modes)
`(apply 'progn
,(-map
(lambda (mode)
`(define-key ,(intern (concat "evil-" mode "-state-map")) (kbd ,key-set)
',(intern
(concat "evil-numbers/" func))))
,modes)))
(set-evil-number-keymap "C-a" "inc-at-pt" "normal" "insert")
(set-evil-number-keymap "C-x" "dec-at-pt" "normal" "insert")
我的期望如下。虽然它只是没有运行。
(progn
(define-key evil-normal-state-map (kbd "C-a") ’evil-numbers/inc-at-pt) (define-key evil-visual-state-map (kbd "C-a") ’evil-numbers/inc-at-pt))
(progn
(define-key evil-normal-state-map (kbd "C-x") ’evil-numbers/dec-at-pt) (define-key evil-visual-state-map (kbd "C-x") ’evil-numbers/dec-at-pt))
【问题讨论】:
-
现在有什么问题?为什么
(apply 'progn ...)不起作用? -
@xuchunyang 因为
progn是“特殊形式”,我认为它是一个函数,但事实并非如此。什么时候在(apply 'progn ...)上做macroexpand我会得到(apply 'progn (define-key evil-normal-state-map (kbd "C-a") ’evil-numbers/inc-at-pt) (define-key evil-visual-state-map (kbd "C-a") ’evil-numbers/inc-at-pt)) -
仍然不确定您的问题。您需要一个,因为这是一个 QA 站点,而不是论坛。由于您使用的是宏(实际上您不必这样做,易于阅读/编写的普通 defun 可以正常工作),您不需要
apply。apply的目的是,例如,你有一些数字存储在some-numbers中,想要求和,你使用(apply '+ some-numbers),但是使用宏,你可以只写(cons '+ some-numbers),不需要申请,你可以认为这个宏应该返回一个列表,也就是一个诸如(+ 1 2 3)之类的函数调用,然后它会被自动求值。 -
@xuchunyang 很抱歉让您感到困惑,问题可以澄清一下,为什么
apply不能在progn上?我认为progn只是一个函数。所有的“特殊形式”都应该只是一个函数,可以很容易地与其他形式复合。为什么elisp需要“特殊形式”的概念,使其与正常功能区分开来,防止apply在其上。
标签: emacs apply elisp elisp-macro