GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/eintr/kill_002dappend-function.html ・ emacs-doc.conao3.com

kill-append 関数

kill-append 関数は次のようになります。

(defun kill-append (string before-p &optional yank-handler)
  "Append STRING to the end of the latest kill in the kill ring.
If BEFORE-P is non-nil, prepend STRING to the kill.
... "
  (let* ((cur (car kill-ring)))
    (kill-new (if before-p (concat string cur) (concat cur string))
              (or (= (length cur) 0)
                  (equal yank-handler
                         (get-text-property 0 'yank-handler cur)))
              yank-handler)))

kill-append 関数はかなりシンプルです。この関数は kill-new 関数を利用しており、これについては後ほど詳しく説明します。

(また、この関数には yank-handler というオプション引数が用意されており、これを指定すると、太字や斜体などテキストに追加されたプロパティをどのように処理すべきかを関数に伝えることができます。)

キルリングの最初の要素の値をcurに設定するlet*関数があります。(なぜ代わりにletを使わないのかは分かりません。式内で設定される値は1つだけです。おそらく、特に問題は生じないバグなのでしょうか?)

kill-new の2つの引数のうちの1つである条件式を考えてみましょう。この条件式は concat を用いて、新しいテキストをキルリングの CAR に連結します。テキストを先頭に付加するか末尾に付加するかは、if 式の結果によって決まります:

(if before-p                            ; if-part
    (concat string cur)                 ; then-part
  (concat cur string))                  ; else-part

削除対象の領域が、直前のコマンドで削除された領域よりも前にある場合は、前回の削除時に保存された内容の前に付加されるべきであり、逆に、削除対象のテキストが直前に削除された内容の後に続く場合は、前回のテキストの後に付加されるべきです。if 式は、新たに保存されたテキストを前回保存されたテキストの前に置くか後に置くかを決定するために、述語 before-p に依存します。

記号 before-p は、kill-append の引数の一つの名前です。kill-append 関数が評価される際、それは実引数を評価して得られた値にバインドされます。この場合、その値は式 (< end beg) となります。この式は、このコマンドで削除されたテキストが、直前のコマンドで削除されたテキストの前にあるか後にあるかを直接的に判定するものではありません。この式が行うのは、変数 end の値が変数 beg の値よりも小さいかどうかを判定することです。もし小さい場合、ユーザーはバッファの先頭に向かっている可能性が高いことを意味します。また、述語式 (< end beg) の評価結果は true となり、テキストは直前のテキストの前に付加されます。一方、変数 end の値が変数 beg の値よりも大きい場合、テキストは直前のテキストの後に付加されます。

新しく保存されたテキストが先頭に付加される場合、新しいテキストを含む文字列が元のテキストの前に連結されます:

(concat string cur)

ただし、テキストが追記される場合は、既存のテキストの後に連結されます:

(concat cur string))

この仕組みを理解するために、まずはconcat関数について確認しましょう。concat関数は、2つのテキスト文字列を連結または結合します。その結果は1つの文字列となります。例えば:

(concat "abc" "def")
     ⇒ "abcdef"

(concat "new "
        (car '("first element" "second element")))
     ⇒ "new first element"

(concat (car
        '("first element" "second element")) " modified")
     ⇒ "first element modified"

We can now make sense of kill-append: it modifies the contents of the kill ring. The kill ring is a list, each element of which is saved text. The kill-append function uses the kill-new function which in turn uses the setcar function.