current-kill 函数代码 ¶yank 与 yank-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-append、copy-region-as-kill、kill-ring-save、kill-line 与 kill-region。
下面是 kill-new 中的相关代码,其解释参见 The kill-new function。
(setq kill-ring-yank-pointer kill-ring)