current-kill 函数代码

yankyank-pop 均使用 current-kill 函数。下面是 current-kill 的代码:

(defun current-kill (n &optional do-not-move)
  "将粘贴指针旋转 N 位,然后返回对应剪切内容。
若 N 为 0 且 `interprogram-paste-function' 设为可返回字符串或字符串列表的函数,
且该函数返回非空值,则将该字符串(或列表)添加到剪切环头部,
并将该字符串(或列表首个字符串)作为最新剪切内容返回。
若 N 不为 0 且 `yank-pop-change-selection' 非空,
则使用 `interprogram-cut-function' 将新粘贴指针处的剪切内容
传递到窗口系统剪贴板。
若可选参数 DO-NOT-MOVE 非空,则不实际移动粘贴指针,
仅返回向前第 N 个剪切内容。"

  (let ((interprogram-paste (and (= n 0)
                                 interprogram-paste-function
                                 (funcall interprogram-paste-function))))
    (if interprogram-paste
        (progn
          ;; 将新文本添加到剪切环时禁用程序间剪切函数,
          ;; 避免 Emacs 以相同文本占用剪贴板。
          (let ((interprogram-cut-function nil))
            (if (listp interprogram-paste)
              (mapc 'kill-new (nreverse interprogram-paste))
              (kill-new interprogram-paste)))
          (car kill-ring))
      (or kill-ring (error "Kill ring is empty"))
      (let ((ARGth-kill-element
             (nthcdr (mod (- n (length kill-ring-yank-pointer))
                          (length kill-ring))
                     kill-ring)))
        (unless do-not-move
          (setq kill-ring-yank-pointer ARGth-kill-element)
          (when (and yank-pop-change-selection
                     (> n 0)
                     interprogram-cut-function)
            (funcall interprogram-cut-function (car ARGth-kill-element))))
        (car ARGth-kill-element)))))

同时记住,kill-new 函数会将 kill-ring-yank-pointer 指向剪切环的最新元素,这意味着所有调用它的函数都会间接设置该值:kill-appendcopy-region-as-killkill-ring-savekill-linekill-region

下面是 kill-new 中的相关代码,其解释参见 The kill-new function

(setq kill-ring-yank-pointer kill-ring)