如何在Windows上使用Emacs保留剪贴板内容?

16

我遇到过这样的情况:

我从其他程序中复制了一些文本,然后在Emacs中编辑,并在粘贴/插入文本之前进行了一些操作。 我按C-y粘贴,哇......出现了一个我不想要的文本。 然后我意识到,在移动文本时,我使用了像kill-line和backward-kill-word这样的命令,并且那些删除的行和单词现在占用了kill-ring。 但是,键入M-y并不能将原始复制的文本带回来,因此我需要返回到我的原始程序中再次复制文本。 如果原始程序已关闭,则更糟糕,我将完全失去复制的文本。

Kill-line等是非常基本的命令(几乎像按删除键一样),虽然我不介意使用这些命令使kill-ring有点凌乱,但我期望我的原始文本能够保留在kill-ring中,以便我最终可以通过多次键入M-y找到它。 如何让Emacs在覆盖剪贴板内容之前自动将当前剪贴板内容保存到kill-ring中?

5个回答

12

这段代码应该可以自动将来自Emacs外部的选择(Selection)放入剪贴板(kill-ring),每当你在Emacs中进行Kill操作时。它已经在Linux上测试过,但不应限于Linux。

(defadvice kill-new (before kill-new-push-xselection-on-kill-ring activate)
  "Before putting new kill onto the kill-ring, add the clipboard/external selection to the kill ring"
  (let ((have-paste (and interprogram-paste-function
                         (funcall interprogram-paste-function))))
    (when have-paste (push have-paste kill-ring))))

如果你经常这样做,那么看一下browse-kill-ring这个包可能会很有用,它可以让你轻松查看剪贴板历史记录(而不是反复地使用M-y命令)。


今天我用了这个脚本。我从浏览器中复制了一些文本,然后进入emacs将其粘贴到一个新文件中。不知不觉中,当我打开新文件时,我使用了一些删除命令来操作文件路径名。如果没有这个脚本,剪贴板的内容就会消失。但是这次它按预期工作了! - Cheeso

3
请注意,最新的Emacs CVS版本有一个名为save-interprogram-paste-before-kill的变量,它可以实现这个功能。参见etc/NEWS文件中的说明:
** 当save-interprogram-paste-before-kill非nil时,当删除某些内容时,Emacs不会破坏之前的程序间粘贴内容,而是将其保存在kill-ring中。

2
我认为问题在于当你从emacs外部复制时,没有保存到kill ring中。
你需要使用函数clipboard-yank插入区域,然后以某种方式选择它并保存到kill ring中,就像函数kill-ring-save一样。
或者更好的是编写一个函数clipboard-save-to-kill-ring-and-yank,将剪贴板保存到kill ring中,然后插入它。
编辑:通过代码跟踪一下,这样做可以实现你想要的功能;你可以将其连接到一个按键上。它会将Windows剪贴板内容保存到kill ring中。
(defun clipboard-to-kill-ring()
  "save the external clipboard contents to the kill ring"
  (interactive)
    (let ((clip (funcall interprogram-paste-function)))
      (when clip
        (kill-new clip)))

(defadvice yank (before maybe-copy-windows-clipboard (arg))
    (clipboard-to-kill-ring))

(ad-activate 'yank)

这很好,但我需要一些自动化的东西(以防我忘记!),这样每当我杀死某些东西时,如果剪贴板上的内容尚未存在于kill-ring中,则会将其保留到kill-ring中。 - polyglot
我认为我的编辑起作用了。before advice 会自动将 Windows 剪贴板保存到 kill ring 中。 - justinhj
我认为你的代码在以下场景中无法正常工作: 在非emacs窗口(比如“XYZ”)中选择文本 现在在emacs中删除一些文本(比如“ABC”) C-y M-y M-y ...由于第一次删除时选择已经丢失,所以第一次yank不能将其添加到kill ring中,因此找不到XYZ。 - Trey Jackson

0

我猜你可以修改各种 kill 命令,使其不将文本放入剪贴板,然后将 clipboard-yank 绑定到另一个键上,不知道这是否可行。


0

我有点绕过这个问题,只需要在从其他窗口应用程序复制或剪切后弹出emacs时,将文本取走然后再重新删除它。

更好的方法是入侵emacs,这样当您删除某些内容时,它会将现有剪贴板与kill ring中的最顶端条目进行比较,如果不同,则在执行您明确请求的删除之前,将剪贴板内容推送到kill ring中。


你不需要使用我的解决方案来检查 kill ring 中的内容,因为当你获取剪贴板时,它会清空,所以后续调用只会得到 nil,并且不会将其添加到 kill ring 中。 - justinhj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接