多光标基础


55

我最近了解了 multiple-cursors,它看起来像一个非常有用的软件包。我浏览了原始存储库中的文档,但是命令对我来说仍然有些晦涩。

然后,我在Emacs Rocks!中观看了视频,虽然视频很棒,但它主要关注的multiple-cursors是能够做的事情,而不是如何去做。

是否有任何演练,教程或示例可以说明其最基本的功能?


4
multiple-cursors只需阅读README文件,我就能非常快速地启动并运行。我的建议是学习mc/mark-next-like-this。试试看,并熟悉它的作用。每当您遇到一个以“我想知道多个光标是否可以...”开头的问题时,请从这里回到自述文件。所有这些都表示,我认为这是比Emacs Rocks更基本的介绍!视频将对初学者有所帮助。
nispio 2014年

完全同意!绝对不清楚如何使用它。我只是遮罩了行,然后绑定了KBD来进行mc / edit-lines(不通过Github上的Mx进行绑定),然后看到多个光标,但是它们在输入任何文本后才消失
Dima Fomin

Answers:


19

除了@bastibe描述的用途外,我还使用多个游标从一组行的开头/结尾添加或删除文本:

  1. 将点移动到感兴趣区域的起点或终点
  2. 电话set-rectangular-region-anchor(绑定到您喜欢的任何键H-space,如果您有超级键,我想Magnars的建议是)
  3. 按行(C-nC-p)向前或向后移动点,直到要编辑的每一行都有光标为止
  4. 根据需要插入或删除文本,可以选择移动到行(C-e)的末尾进行更改。

您可以使用forward-wordforward sentence等来来回移动沿着线,它允许你在每一行编辑第四个单词,即使在每一行文字是不相同的。

举例来说,我一直在做这种工作:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    这会将pp5目录的内容插入缓冲区。我将点!放在清单的开头:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • H-spaceC-nx 4 将光标添加到每一行
  • 复制每行 C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • 将第一部分修整为M-dx 3 C-d C-fx3 M-dx3 <-的变量名

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • 然后将实际文件名包装在函数中以进行加载:read.file(C-dC-e”)RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

瞧,您已经将文件列表转换为代码以读取该列表。实际上比实际更难描述!


3
如果您经常执行相同的操作,则可以将其包装在键盘宏中。键盘宏multiple-cursors可以组成一个真正强大的组合。
nispio 2014年

@nispio同意!有时我会重复相同的过程,宏将很有用。但是,通常情况下,工作流程中间会有一些细微的差异,需要进行细微的更改才能“破坏”宏。
泰勒2014年

1
您通常可以使用正则表达式准确地描述您希望光标跳转到的位置。在这种情况下,使用phi-search导航要比使用诸如M-f (x3)
nispio

@nispio当然,这取决于情况。借助结构一致的名称,您可以轻松地逐字移动。我没有在多个游标中使用搜索功能,因为内置的emacs搜索命令对mc很脆弱。我不知道phi-search,看起来很棒!
泰勒2014年

22

我基本上有两个频繁的用例multiple-cursors

  • 替换一些字符串。标记一个字符串实例,然后使用mc/mark-next-like-thismc/mark-previous-like-this标记它的更多实例。然后,我立即点击C-w删除每个实例,并改写一个新字符串。我经常使用它来重命名代码中的变量。
  • 同时编辑多个位置。像以前一样标记一个字符串的多个实例,但是立即使用取消选择(但不删除光标)C-g,或者将mark和point放在不同行的同一列中,并使用mc/edit-lines来获得每行一个光标。现在,您可以使用对这些光标中的每一个进行操作的常规编辑命令。

第一个用例对于尤其有用expand-region。我已经er/expand-region绑定C-j,并mc/mark-next-like-thismc/mark-previous-like-thisC->C-<。这样,我可以轻松地选择单词点已打开,并立即标记该单词的下一个/上一个出现的位置。

第二个用例对我来说替代了大多数使用宏的方法。与其记录宏,然后在多个位置应用宏,不如将光标放在每个位置上,然后一次在所有位置进行操作。


谢谢@bastibe。您或multiple-cursors 建议使用的任何特殊绑定,例如mark-next-like-thismark-previous-like-this
2014年

如帖子中所述,@ user815423426,我使用C->and C-<for mark-next-like-thismark-previous-like-this
bastibe

为什么不使用Standart M-%进行搜索和替换
Dima Fomin

6

我想添加一些我有时使用的附加功能multiple-cursors

我发现以下有用:

我去炭火

有时,您发现自己需要移至下一个#或下一个,或某些特定的定界符。当您需要为每个光标移动不同数量的单词时,这特别方便。它提供了功能iy-go-to-chariy-go-to-char-backward,您可以很好地绑定和使用它们。

扩大区域

出于类似原因,这真的很有用iy-当每个光标下的行略有不同时,您可能希望选择该点或类似内容下的带引号的字符串。

定制的东西

这些只是我的配置中不多见的东西,但是我发现很有用。可能不是我写的。

提示输入
我是从Magnars获得此输入的,以响应在每个光标下放置不同字符串的请求。代码很简单,但是将其绑定到某个对象并用于多个游标是在每个位置插入稍有不同的东西的便捷方法。

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

此时的增量数
可能来自SO或emacswiki。不知道哪个。单独使用,以及与mc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

评估和替换
这是超级强大的功能,并且启用了一些非常有用的位'n'件。它评估光标后面的任何sexp,并插入评估结果。
结合使用multiple-cursors-numbers,例如插入2的幂或0 1 2 0 1 2 0 1 2贯穿每条线或某物的一系列幂。(我对这两个步骤都做了有益的处理),或将其s.el与默认值一起写出那些乏味的Java配置。您写出每个CONFIG_VALUE_VARIABLE,然后CONFIG_VALUE_VARIABLE = "configValueVariable"通过运行将其转换为s-camel-case

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))

即时聊天非常有帮助。正是我想要的。
海因里希·哈特曼

1
  1. 转到要选择的内容的末尾*。
  2. C-S-bM-S-b向后选择,直到选择了一部分。您也可以使用左移箭头。
  3. 然后按C->(如果键>位于键盘键的上方,请按Shift ),直到选择了多个项目。

*向后选择很重要,否则第一个选择会将光标放置在错误的位置。

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.