如何在elisp中递归调用和重新定义函数

时间:2014-05-03 08:20:06

标签: elisp

我正在创建一系列与各种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真的很讨厌这个。

如何递归调用函数并重新定义它?

0 个答案:

没有答案