如何定义一个在传递参数时重复自身的函数

时间:2010-05-11 14:04:55

标签: emacs elisp

有没有一种简单的方法可以定义一个在传递参数时重复自身的函数?

例如,我已经定义了以下函数

(defun swap-sign ()
  (interactive)
  (search-forward-regexp "[+-]")
  (if (equal (match-string 0) "-")
      (replace-match "+")
    (replace-match "-"))
  )

我希望C-u swap-sign四次致电swap-sign

我试过

(defun swap-sign (&optional num)
  (interactive)
  (let ((counter 0)
 (num (if num (string-to-number num) 0)))
    (while (<= counter num)
      (search-forward-regexp "[+-]")
      (if (equal (match-string 0) "-")
   (replace-match "+")
 (replace-match "-"))           
      (setq counter (1+ counter)))))

但是C-u swap-sign仍然只运行swap-sign(或者更准确地说,是while循环的主体)一次。我猜这是因为if num不是测试num是否为空字符串的正确方法。

我是在正确的轨道上,还是有更好/更简单的方式来扩展swap-sign

2 个答案:

答案 0 :(得分:5)

(defun swap-sign (arg)
  (interactive "p")
  (dotimes (i arg)
    (search-forward-regexp "[+-]")
    (if (equal (match-string 0) "-")
        (replace-match "+")
      (replace-match "-"))))

有关详细信息,请参阅interactive特殊表单的文档: C-h f interactive RET

答案 1 :(得分:4)

您需要通过添加“p”作为交互式参数规范(M-x apropos interactive来获取文档)来告诉emacs期望并传递参数。在这里,我对代码进行了最小的更改以使其工作 - 但是,请注意,您不需要let / while来执行迭代,并且arg不需要是可选的。

(defun swap-sign (&optional num)
  (interactive "p")
  (let ((counter 1))
    (while (<= counter num)
      (search-forward-regexp "[+-]")
      (if (equal (match-string 0) "-")
      (replace-match "+")
    (replace-match "-"))           
      (setq counter (1+ counter)))))

请注意,您不需要从字符串转换参数 - 使用“p”告诉emacs为您执行此操作。