我正在创建一系列与各种elisp函数相关的缩写。这些函数插入一些文本并定义一个名为ae-abbrev-next
的交互式函数,该函数映射到tab键。
例如,我创建了一个缩写/int
来调用函数ah-abbrev-insert-integral
;该函数定义如下:
(defun ah-abbrev-insert-integral ()
(ah-abbrev-insert-structure "\\int_{" "}^{" "}" "\\mathrm{d}" ""))
应该发生的事情是,当缩写扩展时,
\int_{
插入缓冲区。然后函数ae-abbrev-next
被映射到tab
键,以便在命中tab
时,插入传递给ah-abbrev-insert-structure
的下一个字符串:
\int_{0 <TAB> }^{
每次输入<TAB>
时,都会调用重新定义的ae-abbrev-next
。
我已经创建了一些函数,宏和变量,它们共同实现了我想要的效果:
我创建了一个缩写,我已将其映射到以下函数
(defun ah-abbrev-insert-integral ()
(ah-abbrev-insert-structure "\\int_{" "}^{" "}" "\\mathrm{d}" ""))
以下是使其工作所需的其余代码:
(defmacro ah-abbrev-insert-structure
(
ae-string-a
ae-string-b
&optional
ae-string-c
ae-string-d
ae-string-e
)
;; round (1)
;; insert front matter
`(progn
(insert ,ae-string-a)
(ah-abbrev-set-mark-for-next)
(defun z-abbrev-next ()
;; insert 2nd level material
(ah-abbrev-search-for-next)
(insert ,ae-string-b)
;; test whether 3rd level material
(if (eq ,ae-string-c nil) (defun z-abbrev-next () (message "UNDEFINED"))
(ah-abbrev-set-mark-for-next)
(defun z-abbrev-next ()
(ah-abbrev-search-for-next)
(insert ,ae-string-c)
;; test whether 4th level material
(if (eq ,ae-string-d nil) (defun z-abbrev-next () (message "UNDEFINED"))
(ah-abbrev-set-mark-for-next)
(defun z-abbrev-next ()
(ah-abbrev-search-for-next)
(insert ,ae-string-d)
;; test whether 5th level material
(if (eq ,ae-string-e nil) (defun z-abbrev-next () (message "UNDEFINED"))
(ah-abbrev-set-mark-for-next)
(defun z-abbrev-next ()
(ah-abbrev-search-for-next)
(insert ,ae-string-e)
;; no more options to test for
(defun z-abbrev-next () (message "UNDEFINED"))
))
))
))
)))
(defun ah-abbrev-set-mark-for-next ()
(let ((ae-pos (point-marker)))
(insert (concat "\n" ah-var-next-string))
(goto-char ae-pos)))
(defun ah-abbrev-search-for-next ()
(search-forward ah-var-next-string nil t)
(replace-match "")
(delete-char -1))
(defvar ah-var-next-string "%%/<next>/")
(defun ae-abbrev-next ()
(interactive)
(z-abbrev-next))
(defun z-abbrev-next () (message "UNDEFINED"))
以上所有作品都非常合适
但我真的想创建一个ah-abbrev-insert-structure
版本,递归调用自身如下。
这是我尝试进行递归调用:
(defun ah-abbrev-insert-structure ( ae-string-a &rest ae-string-b )
(insert ae-string-a)
(ah-abbrev-set-mark-for-next)
(if (eq ae-string-b nil)
(defun z-abbrev-next () (message "UNDEFINED"))
(defun z-abbrev-next ()
(ah-abbrev-search-for-next)
(ah-abbrev-insert-structure ae-string-b))
))
当我稍后调用它时ae-string-b
显然不知道问题z-abbrev-next
。我收到以下错误消息。
ae-abbrev-next: Symbol's value as variable is void: ae-string-b
我尝试将ah-abbrev-insert-structure
重写为宏,但是
(defun ah-abbrev-insert-structure ( ae-string-a &rest ae-string-b )
`(progn
(insert ,ae-string-a)
(ah-abbrev-set-mark-for-next)
(if (eq ,ae-string-b nil)
(defun z-abbrev-next () (message "UNDEFINED"))
(defun z-abbrev-next ()
(ah-abbrev-search-for-next)
(ah-abbrev-insert-structure ,ae-string-b))
)))
但是elisp
真的很讨厌这个。
如何递归调用函数并重新定义它?