2

私はRobertJ.Chassellによる「EmacsLispでのプログラミング入門」を読んでいます。そして、私は質問があります。ノード「fwd-parawhile」(の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))))

編集して回答していただきありがとうございます。前段落についてさらに3つの質問があります。

  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)
    

    なぜもう1行転送するのですか?

  3. この段落について:

    このwhileループでは、可能な空白と段落の先頭または段落区切り文字のローカル値の組み合わせである「sp-parstart」を前方に検索します。

    なぜthe local value of the start of a paragraph or of a paragraph separatorですか?私に関する限り、段落区切り文字の条件は、の最初のwhileループですでに処理されていますwhile

4

1 に答える 1

2

そんなに面白くない!docstringを見ると、次のforward-paragraphことがわかります。

移動するために残っている段落の数を返します。

つまり、バッファの最後から1段落で、を評価する(forward-paragraph 3)と、が返されます。つまり、1段落進み2ましたが、要求した残りの2つの手順を実行できませんでした。

実行されなかったステップ数を返すために、forward-paragraph(引用したコードのブロックの直後に)値を返しますarg。したがって、実際に段落を進めるarg場合にのみデクリメントする必要があります。forward-paragraph私はあなたが残りを理解できると確信しています。

(戻り値がどこで使用されているのか疑問に思っている場合はfill-paragraph、バッファーの最後に存在しない段落を埋めないようにする必要があります。)

ETA:3つの新しい質問が追加されたようです。それらに答える代わりに、 Emacs Lispデバッガーを使用してコードをステップ実行し、forward-paragraph実際に何をしているのかを確認することで、自分で答えようとする方法を説明します。

  1. forward-paragraph入力してからバッファC-h C-f forward-paragraph RET内のリンクをクリックして、のソースコードを見つけます。*Help*

  2. コマンドを実行して、たとえば。と入力しforward-paragraphて、デバッグ用に再コンパイルします。eval-defunC-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 に答える