2

我正在阅读 Robert J. Chassell 的“ An Introduction to Programming in Emacs Lisp ”。我有一个问题。在节点“ fwd-para while ”(while循环的解释forward-paragraph)中,它说:

有趣的是,在我们离开段落之间的空间之前,循环计数不会减少,除非我们到达缓冲区的末尾或停止查看段落分隔符的本地值。

看不懂,谁能给我解释一下?谢谢。

while循环如下所示:

;; going forwards and not at the end of the buffer
(while (and (> arg 0) (not (eobp)))

  ;; between paragraphs
  ;; Move forward over separator lines...
  (while (and (not (eobp))
              (progn (move-to-left-margin) (not (eobp)))
              (looking-at parsep))
    (forward-line 1))
  ;;  This decrements the loop
  (unless (eobp) (setq arg (1- arg)))
  ;; ... and one more line.
  (forward-line 1)

  (if fill-prefix-regexp
      ;; There is a fill prefix; it overrides parstart;
      ;; we go forward line by line
      (while (and (not (eobp))
                  (progn (move-to-left-margin) (not (eobp)))
                  (not (looking-at parsep))
                  (looking-at fill-prefix-regexp))
        (forward-line 1))

    ;; There is no fill prefix;
    ;; we go forward character by character
    (while (and (re-search-forward sp-parstart nil 1)
                (progn (setq start (match-beginning 0))
                       (goto-char start)
                       (not (eobp)))
                (progn (move-to-left-margin)
                       (not (looking-at parsep)))
                (or (not (looking-at parstart))
                    (and use-hard-newlines
                         (not (get-text-property (1- start) 'hard)))))
      (forward-char 1))

    ;; and if there is no fill prefix and if we are not at the end,
    ;;     go to whatever was found in the regular expression search
    ;;     for sp-parstart
    (if (< (point) (point-max))
        (goto-char start))))

感谢您的编辑和回答。关于前段,我还有另外三个问题:

  1. 是什么意思(progn (move-to-left-margin) (not (eobp)))?如果(not (eobp))是真的,不应该(progn (move-to-left-margin) (not (eobp)))总是真的吗?

  2. 关于这一行:

    ;; ... and one more line.
    (forward-line 1)
    

    为什么要多转一行?

  3. 关于本段:

    这个while循环让我们向前搜索“sp-parstart”,它是可能的空白与段落开头或段落分隔符的本地值的组合。

    为什么the local value of the start of a paragraph or of a paragraph separator呢?就我而言,段落分隔符的条件已经whilewhile.

4

1 回答 1

2

那么有趣!如果您查看文档字符串,forward-paragraph您会看到它:

返回要移动的段落数。

这意味着如果您距离缓冲区末尾的一个段落,并且 evaluate (forward-paragraph 3),它将返回2,这意味着它前进了一个段落,但您请求的其余两个步骤无法执行。

为了返回未采取的步骤数,forward-paragraph返回(就在您引用的代码块之后) value arg。因此,只有在实际前进一段arg时才必须递减。forward-paragraph我相信你可以弄清楚其余的。

(如果您想知道返回值在哪里使用,这是fill-paragraph为了避免在缓冲区末尾填充不存在的段落。)

ETA:我看到你添加了三个新问题。我不会回答它们,而是告诉您如何尝试自己回答它们,方法是使用Emacs Lisp 调试器逐步检查代码forward-paragraph并查看它实际在做什么。

  1. forward-paragraph通过键入C-h C-f forward-paragraph RET然后单击*Help*缓冲区中的链接来查找源代码。

  2. 通过运行命令重新编译forward-paragraph以进行调试eval-defun,例如键入C-M-x.

  3. forward-paragraph通过键入打开调试M-x debug-on-entry RET forward-paragraph RET

  4. 转到合适的缓冲区并运行forward-paragraph,例如键入M-}.

  5. 现在您在调试器中,它向您显示调用堆栈和正在评估的当前表单。您可以键入d进入该表单并查看其子表单的评估,或c完全评估该表单并查看其结果,然后q退出调试器。(有关更多调试器命令,请参阅文档。)

  6. 逐步执行,forward-paragraph直到您了解它在做什么。

于 2012-11-28T23:15:37.527 回答