Emacs - 使用执行替换计数器

时间:2018-05-18 17:29:20

标签: replace emacs

我试图在elisp中编写一个命令来自动重新编号给定文件中的单元测试。为了帮助我轻松找到失败的测试,我通常使用以下语法(使用GoogleTest):

TEST(testCaseName,T0XX_Test_Description)

我已经能够使用带有重新搜索转发/替换匹配的while循环编写工作命令:

(defun renumber-tests-auto(&optional num)
 "Automatically renumber the tests from the current location in
 the active buffer. Optional argument sets the current test
 number (instead of 1).  This function automatically updates
 all test numbers from the current location until the end of
 the buffer without querying the user for each test."

  (interactive "NStarting test number: ")
  (save-excursion
  (setq num (or num 1 ))
  (while (re-search-forward ", +T0[0-9]+" nil t )
    (replace-match
      (concat ", T" (format "%03d" num )))
    (setq num (+ 1 num))
    )
  )
)

但是,我也非常希望拥有此功能的交互式版本,使用perform-replace以交互方式查询每个测试的用户。当然,我可以在我的代码中手动处理查询行为,但是,鉴于此功能已经存在,我真的不想重新实现它。此外,我想确保此命令与其他内置查询替换函数具有相同的接口。

我最近的失败尝试如下:

(defun renumber-tests(&optional num)
  (interactive "NStarting test number: ")
  (save-excursion
    (setq num (or num 1 ))
    (perform-replace ", +T0[0-9]+"
                 (concat ", T" (format "%03d" (+ 1 num )
                                   ))
                 t t nil)
  )
)

但是,每次运行时都不会更新num的值(我也尝试过(setq num(+ 1 num))并得到相同的结果。

我非常感谢那些在elisp中经验丰富的人提供的一些帮助 - 如果有任何方法可以让它按照我的意图运作。

1 个答案:

答案 0 :(得分:1)

您正在使用perform-replace作为替换文字致电string。您必须提供替换功能才能进行动态替换。从文档引用:

  

REPLACEMENTS是字符串,字符串列表或缺点单元格   包含一个函数及其第一个参数。该函数被调用   生成每个替换像这样:(funcall(汽车更换)   (cdr替换)replace-count)它必须返回一个字符串。

这样你也可以摆脱变异:

(defun renumber-tests(&optional num)
  (interactive "NStarting test number: ")
  (save-excursion
    (perform-replace ", +T0[0-9]+"
             (list (lambda (replacement replace-count)
                 (concat ", T" (format "%03d" (+ replace-count (or num 1))))))
             t t nil)))