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

B.3 yank-pop

yank と current-kill を理解したことで、yank-pop 関数にどう取り組めばよいかが分かったはずです。スペース節約のためドキュメントは省略しますが、内容は以下の通りです。

(defun yank-pop (&optional arg)
  "..."
  (interactive "*p")
  (if (not (eq last-command 'yank))
      (error "Previous command was not a yank"))
  (setq this-command 'yank)
  (unless arg (setq arg 1))
  (let ((inhibit-read-only t)
        (before (< (point) (mark t))))
    (if before
        (funcall (or yank-undo-function 'delete-region) (point) (mark t))
      (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
    (setq yank-undo-function nil)
    (set-marker (mark-marker) (point) (current-buffer))
    (insert-for-yank (current-kill arg))
    ;; Set the window start back where it was in the yank command,
    ;; if possible.
    (set-window-start (selected-window) yank-window-start t)
    (if before
        ;; This is like exchange-point-and-mark,
        ;;     but doesn't activate the mark.
        ;; It is cleaner to avoid activation, even though the command
        ;; loop would deactivate the mark because we inserted text.
        (goto-char (prog1 (mark t)
                     (set-marker (mark-marker)
                                 (point)
                                 (current-buffer))))))
  nil)

この関数は小さな ‘p’ でインタラクティブに動作するため、プレフィックス引数が処理され、関数に渡されます。このコマンドは、事前にヤンクを行った後でなければ使用できず、それ以外の場合はエラーメッセージが送信されます。このチェックでは、yank によって設定され、別の箇所で説明されている変数 last-command が使用されます。(copy-region-as-kill を参照してください。)

let 節は、point が mark より前か後かに応じて変数 before に true または false を設定し、その後 point と mark の間の領域を削除します。これは直前の yank によって挿入されたばかりの領域であり、置換対象となるのはこのテキストです。

funcall は第1引数を関数として呼び出し、残りの引数をその関数に渡します。第1引数は、or 式が返す値です。残りの2つの引数は、直前の yank コマンドで設定された point と mark の位置です。

他にもあるが、そこが一番難しいところだ。