如何在Emacs中将一个缓冲区的多行复制到另一个缓冲区?

6

我有两个缓冲区。我想将第一个缓冲区中的第2、5、9和10行复制到第二个缓冲区中(只是追加到第二个缓冲区中)。除了一次复制和粘贴一行之外,是否有更优雅的方法来完成?


1
这是一个任意的例子,还是你想要用那些行号重复多次的特定情况? - phils
4个回答

5
你可以使用命令append-next-kill,绑定到C-M-w,将更多的文本添加到kill环中的最新条目。在一个M-w命令之前使用它,就像这样:

  • 标记并复制第2行:C-SPCC-nM-w
  • 移动到第5行
  • 标记并追加复制它:C-SPCC-nC-M-wM-w
  • 移动到第9行...

...等等。

当你用C-y粘贴文本时,你会得到你选择并追加到kill环条目中的所有行。


4
对于现成的功能,我会推荐使用multiple-cursors.el。当您需要选择和修改多个位置中的符号/正则表达式时,它非常有效。
您可以在以下链接中找到它: https://github.com/magnars/multiple-cursors.el 但是,它也可以通过通用添加光标函数来处理特定行/点: mc/add-cursor-on-click 不过这意味着您必须将其绑定到鼠标事件上(建议在“技巧”部分中): (global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click) 这意味着您必须伸手去拿鼠标,但创建新的函数mc/add-cursor-at-line看起来非常容易:
(defun mc/add-cursor-at-line (&optional linenum)
  (interactive "nLine number: ")
  (save-excursion 
    (goto-char (point-min))
    (forward-line (1- linenum))
    (mc/create-fake-cursor-at-point))
  (mc/maybe-multiple-cursors-mode))

然后,一旦你在所有行上设置了多个光标:

复制所有光标: C-SPC C-e M-w RET

切换缓冲区并...

矩形粘贴: C-x r y


不错。我没有注意到多个光标使用了 killed-rectangle。那个库真的需要一种好的方式来在单光标模式下“标记”一堆待编辑的光标,然后切换到多光标模式进行编辑。你可以通过设置标记并重复调用 mc/pop-mark 来实现这个功能,但这比它本应该的更加笨拙。 - phils
@assem,你可以使用(interactive "n行号: ")在你的函数中节省几行代码。 - juanleon
@juanleon,非常好,谢谢。我已经按照你的建议更新了示例。 - assem
@phils,我也想看到那个功能;是否可以在所有感兴趣的点上插入文本属性,然后激活时累积该属性的点列表,并使用“mc/add-cursor-at-point”函数对列表进行mapcar/loop?无论采用何种解决方案,将其纳入MC中都是值得的=) - assem
assem: 我之前在它的问题队列中讨论过了(https://github.com/magnars/multiple-cursors.el/issues/44),但基于鼠标的方法似乎是唯一从中得出的标准交互方法。 - phils

3

一个简单的解决方案是记录一个宏,将一行从一个缓冲区复制到另一个缓冲区 (f3 C-SCP C-n M-w C-x o C-y C-x o f4),然后在想要复制的每一行上执行该宏 (f4)。

如果这是您经常遇到的情况,您可以保存该宏并将其绑定到一个键。


那就是我想要的答案。而且,我刚学会了如何使用微控制器。 - Xing Shi

0
根据具体的使用情况,我可能会将整个区域从第一行到最后一行一起复制,然后在新缓冲区中删除我不需要的那些行。
  • 1. 移动到第一行的开头以便复制
  • 2. C-space 设置标记以开始标记一个区域
  • 3. 移动到最后一行的结尾以便复制
  • 4. M-w 复制区域
  • 5. C-x b 缓冲区名称 RET 转到第二个缓冲区
  • 6. 移动到第二个缓冲区的插入位置
  • 7. C-y 插入(粘贴)区域
  • 8. C-x C-x 转到已粘贴区域的开头
  • 9. C-n 重复直到到达第一个不需要的行
  • 10. C-k C-k 删除不需要的行
  • 11. 重复步骤 9 直到完成
如果在新缓冲区中有更长的不想要的行,需要删除,则步骤9到11应替换为如下内容:
  • 9. 移动到较长的一段不想要的行的开头
  • 10. C-space 设置标记以开始标记一个区域
  • 11. 移动到较长的一段不想要的行的结尾
  • 12. C-w 剪切选定区域
  • 13. 重复9-12直至完成

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