如何轻松更新Emacs Lisp表达式的评估结果注释

4

假设我有一段展示mapcar使用示例的代码

(mapcar #'1+ (list 10 20 30)) ; ⇒ (11 21 31)

(mapcar (lambda (it)
          (* 2 it))
        (list 0 1 2 3))
;; ⇒ (0 2 4 6)

(require cl-lib)
(cl-mapcar #'+
           '(1 2 3)
           '(10 20 30))
;; ⇒ (11 22 33)

我可能会将那段代码保存在某个地方,以便在教程中使用或者每当我忘记mapcar的用法时,可以快速阅读该代码。

现在假设我想要更新一些示例代码。例如,我可能会将第二个示例中的(list 0 1 2 3)更改为其他列表。在我更改示例后,相应的结果注释就已经过时了。需要更新结果注释。因此,我评估表单,复制结果,并用新结果替换注释中的旧结果。有没有一个软件包可以帮助我轻松地完成所有这些工作,减少繁琐的操作?这是不同于litable或ielm软件包解决的问题,因为这仅仅是关于更新现有示例代码的问题。

目前我使用的是:

(defun my-insert-eval-last-sexp ()
  (interactive)
  (let ((beg (point)))
    (let ((current-prefix-arg '(4)))
      (call-interactively 'eval-last-sexp))
    (goto-char beg)
    (if (looking-back ")")
        (insert " ; "))
    (insert "⇒ ")
    (move-end-of-line 1)))

这还不够,因为它只是添加了新的评论结果,而没有更新旧的评论。并且当表单计算出数字时会有奇怪的东西被插入,这是一个bug:

(+ 1 2)
;; ⇒ 3 (#o3, #x3)
2个回答

2

好的,我不确定我是否想鼓励这种事情 ;-), 但这会让您更接近您尝试做的事情,如果我理解正确的话:

 (defun my-insert-eval-last-sexp ()
   (interactive)
   (let ((this-command  'eval-print-last-sexp))
     (save-excursion (eval-last-sexp-1 t)))
   (when (looking-back ")") (insert " ; "))
   (insert "⇒ ")
   (move-end-of-line 1))
  1. 你不需要保存点并明确返回到它,可以使用save-excursion

  2. 你不需要绑定前缀参数并交互调用命令。只需直接调用该命令(或其辅助函数),并传递所需的参数。

  3. 你需要调整行为以防止它认为这是第二次出现该命令,这会导致它打印八进制等数字信息。 let 绑定可完成此操作(但是是一个丑陋的小技巧)。


2

您的函数实现的相应功能是在 org-mode 中实现的,即 org-babel。

请参见 Info、Org Mode、14 Working with source code。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接