如何在Emacs中选择非连续区域?


31

假设我已经在当前缓冲区中选择了一些文本。是否可以选择另一段文字,同时保留先前的选择(依此类推)?

添加:此功能的动机如下:假设我有一些看起来像这样的文本:

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

我想删除一些段落(例如2、4和6),然后将它们插入第1段之前。



2
有一个multiselect软件包:skamphausen.de/cgi-bin/ska/multiselect看起来有点像快速破解。
Tobias 2015年

根据您选择的大小以及原因,multiple-cursors可能会为您提供解决方案。
Jordon Biondo 2015年

@wasamasa我按照您提供的链接中给出的说明进行操作。第一次选择后,我选择第二个区域并保持Meta键。它被选中了,但是有两个问题:(1)第二个选择似乎不是真正的选择,因为复制或删除不起作用。(2)用这种方法不可能选择第三选择。
命名

1
Emacs Wiki中有一个很好的部分介绍了次要选择。例如,各种增强功能使它在键盘上更加有用。
Drew

Answers:


43

您可以使用append-next-killC-M-w默认情况下绑定到)来累积要在上面插入的文本paragraph 1

  1. paragraph 2照常杀人。

  2. 标记paragraph 4并按下,C-M-w然后杀死它。对您想在其上移动的所有段落重复此步骤paragraph 1

完成后,您可以在之前拉动累积的文本paragraph 1


5
即使有了基本的东西,总会有一些新东西要学习!这非常有用,因为当我需要这样做时,我通常会通过移动杀伤环来浪费很多按键。希望我能再投票赞成…
有意义的用户名

9

您可以将寄存器与标记环一起使用。用推动当前标记,用C-<SPC> C-<SPC>以后恢复它们C-u C-<SPC>,或将它们保存在一个寄存器中,例如b通过C-x r <SPC> b,然后用恢复到后面C-x r j b

现在标记另一个区域。 C-u C-x r s a将复制标记的区域以注册a并删除文本。然后标记下一个区域,C-u C-x r + a并将另一个选择添加到该寄存器a并将其删除。

然后,您可以使用插入内容C-x r i a

请参阅Emacs手册的“在寄存器中保存文本”部分。


5

Emacs-24.4中新的矩形区域支持实际上引入了此功能所需的基础结构(很大一部分)[毕竟,矩形区域不连续的区域]。

因此,现在应该可以实现一个“ split-region”程序包,该程序包仅提供您要的功能。

诚然,许多Emacs命令仍未适应使用新的基础结构(例如,如upcase-region或undo-in-region,query-replace之类的命令),因此在矩形上尚不能正常工作(因此它们也无法在“分割区域”上正常工作),但是这些bug有望随着时间的流逝而得到修复。


4

安装browser-kill-ring.el

复制并杀死所有感兴趣的区域。

指出重新插入的位置。

M-x browse-kill-ring RET 将打开一个缓冲区并将光标放在其中。

键入n以旅行的块。

RET 将在原始/其他缓冲区中的点插入块。


3

如果可以通过正则表达式匹配来区分要操作的行,则可以使用出现模式在新窗口中查看它们。然后,您可以使用出现编辑模式进行编辑,原始缓冲区反映出您在Occur缓冲区中所做的更改。

例如,与multi-cursors-mode结合使用时,它的效果非常好:因为您选择显示在Occur缓冲区中的行连续显示,而不管它们在原始缓冲区中有多远,因此您可以标记所有行或子集,然后一次激活mc/edit-lines和编辑它们。(是的,我知道多光标本身可以使用来完成所有操作mc/mark-all-like-this,但是拥有选项很好。)

如果您只看到要处理的行,那么任何其他编辑操作都将更容易完成,例如设置复杂的regex搜索和替换,或者需要依次在缓冲区的每一行上运行的宏,也可以这样


3

这回答了您的一般问题,但不是特别地回答了您提到的用例(四处移动代码)。

Emacs现在具有所谓的非连续区域,这是您要询问的选择类型。Vanilla Emacs不提供任何特殊方法来创建不连续的区域,除非它是矩形。但是图书馆区域确实如此。

库区域可让您在缓冲区中定义多个区域。一个区域的列表是不连续的区域。您也可以将其视为多个区域,具体取决于您希望如何使用它。您可以随时定义多个区域列表,每个区域列表都分配给不同的区域变量,并且可以在它们之间切换。

如果您还使用Bookmark +库,则可以永久保存区域列表,并在以后的Emacs会话中将其还原。Bookmark +还允许您将任意标签分配给书签。这意味着您可以标记区域列表。

给定区域列表中的区域通常位于同一缓冲区中,但不必如此。在这种情况下,区域列表比非连续区域更笼统。还更笼统的是,每个区域除了区域限制之外还可以包含其他信息,并且可以具有标识符。

有几种创建区域的方法。最简单的方法之一是使用C-x n a:它从活动区域定义一个区域,并将其添加到当前区域集中。(C-x n nnarrow-to-region)除缩小范围外,还这样做。)

您可以对一组区域(列表)执行以下操作:

  • 对它们进行排序。
  • 团结(凝聚)相邻或重叠的区域(包括对其进行排序)。
  • 与它们相交。
  • 将缓冲区缩小到列表中的区域。在缩小之间循环。请参阅多重变窄
  • 在列表中选择一个区域作为活动区域。在区域之间循环。
  • 搜索它们(它们会先自动组合在一起)。为此,您需要库Isearch +
  • 查询替换它们。
  • 突出显示并取消突出显示它们。(为此,您需要库Highlight或library facemenu+.el

另请参见Narrow Indirect,它使您可以创建间接缓冲区,这些间接缓冲区是给定缓冲区的克隆,并且缩小到其不同部分。


2

另一种选择:转置段落

为了完整起见,您可以使用标记的区域(顺序)实现对段落的重新排序,并且M-0 M-x transpose-paragraph(零参数tra-par交换了点和标记所在的段落,即区域的开始和结束)!

顺便说一下,这适用于所有transpose-.*命令(-words,-sexp,-sentences等),并且在许多情况下非常方便。


2

另一种方法是使用objed包(我是作者)。您可以标记任何文本对象,并且m该点会自动移动到当前类型的下一个对象。通过导航到任何对象取消标记,然后再次按m。这是一个示例屏幕录像(显示标记线,但也适用于其他对象,如段落,defuns ...):

在此处输入图片说明


当我尝试从Melpa安装此软件包时,出现错误package-install-from-archive: http://melpa.milkbox.net/packages/objed-20181201.1346.tar: Not found
命名

@Name听起来好像需要更新您的软件包列表。尝试M-x package-refresh-contents然后M-x package-install
clemera

@Name现在可以使用吗?如果您还有其他问题,请告诉我。
clemera

我能够安装该软件包。似乎运行良好,我尚未测试其所有功能。谢谢。
命名
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.