在Emacs中,一次编辑多行


71

我相信textmate的模式是,如果您开始输入文字,则会在您选择的所有行中输入相同的内容。emacs中有与此类似的东西吗?我猜矩形有一种可以帮助我的方式,但是我不确定如何...



如果您重新阅读该帮助说明,将会发现,由于它最初是发布的,因此已被多行光标
2012年

是的,@ phils,multiple-cursors.el很棒。
whunmr 2012年

Answers:


98

就这么简单:Cx rt

一些示例在这里:http : //ergoemacs.org/emacs/emacs_string-rectangle_ascii-art.html


7
这很棒,但对完全不熟悉emacs的人不是很有用,请您帮我破译一下吗?

3
@cone您应该阅读内置的emacs教程。它解释了如何阅读象形文字;)。要在emacs中升级本教程,请在按住ctrl键的同时打“ h”。然后,按“ t”(“教学”)
。– allyourcode

1
我已经C-x映射到剪切(cua模式),所以这不是一个好主意。
mefiX

26
也许这是您映射C-x剪切的想法,这不是很好:)
BartoszKP 2014年

注意:此命令用指定的字符串替换选定的矩形,即选择行的开头以使替换生效。
2014年

54

您绝对需要尝试安装多个游标:

https://github.com/magnars/multiple-cursors.el

就在果酱和梅尔帕上,所以:

MX包安装多光标

1
这是一个很好的解决方案。很好用。要通过单击添加多个选择(包括我在内的人员丧生的标准),请添加(global-unset-key (kbd "M-<down-mouse-1>")) (global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)到您的配置中。
smonff

22

解决方案之一是使用CUA模式。使用激活CUA模式M-x cua-mode,开始选择矩形:首先按下,C-Enter然后使用标准移动命令移动光标以进行选择,现在随时按Enter键将使光标在矩形的各个角之间循环,从而使您可以在选择之前或之后添加文本。


谢谢,boskom。我正在使用21.3.1版,因此似乎未安装此模式。我可能不会安装它,因为发现我喜欢Cx r t。
allyourcode

1
谢谢!我只是认为cua模式适用于不想学习emacs复制和粘贴绑定的人:P这太棒了!
rflood89

2
如果使用cua-selection-mode代替cua-mode,则不会得到不需要的剪切/复制/粘贴绑定。但是,您获得一些您可能不想要的其他功能(最值得注意的是,编辑命令替换了该区域)。
phils 2012年


20

对于那些想在更复杂的情况下执行此操作并且不想安装新模块的人,请继续阅读。(尽管我个人使用并喜欢MarkMultiple,但在Emacs中无需安装MarkMultiple即可实现)

最近,我不得不将SQL查询输出到文件,然后将其格式化为MYSQL INSERT查询。这就是Emacs使我的生活变得轻松的方式。

文件看起来像:

1   I am a random text
2   I am not
3   G, you've gone mad
4   Click on this link
5   Transfer in progress (we've started the transfer process)
6   But transfer happend yesterday
7   No you are
8   Oh please! this is getting too much!
9   I love emacs
10  I cant be bothered with this any more
11  its time to raise the bar
12  show me how to expand my territory

我想使其看起来像:

(1,   ,'I am a random text'),
(2,   ,'I am not'),
(3,   ,'G, youve gone mad'),
(4,   ,'Click on this link'),
(5,   ,'Transfer in progress (weve started the transfer process)'),
(6,   ,'But transfer happend yesterday'),
(7,   ,'No you are'),
(8,   ,'Oh please! this is getting too much!'),
(9,   ,'I love emacs'),
(10,  ,'I cant be bothered with this any more'),
(11,  ,'its time to raise the bar'),
(12,  ,'show me how to expand my territory'),
  1. 将光标放在第一行
  2. 按下C-x (开始录制宏[此刻正在录制您所有的按键输入,因此请仔细按照说明进行操作]
  3. C-a转到行的开头
  4. 键入“(”,然后M-f向前移动一个单词,然后键入“,”
  5. C-n转到下一行,然后C-x )结束宏
  6. C-u 11 C-x e 重复宏n(在这种情况下为11)次

尤里卡!到现在为止,如果您没有失败,您将获得如下所示的内容:

(1,   I am a random text
(2,   I am not
(3,   G, youve gone mad
(4,   Click on this link
(5,   Transfer in progress (weve started the transfer process)
(6,   But transfer happend yesterday
(7,   No you are
(8,   Oh please! this is getting too much!
(9,   I love emacs
(10,  I cant be bothered with this any more
(11,  its time to raise the bar
(12,  show me how to expand my territory

在这一点上,我将让您自己解决其余的问题。但是,在我走之前,我想提一提,有很多方法可以实现这种目的。这只是这些方式之一,它恰好是我最喜欢的方式。

希望对您有所帮助;)



3

矩形用于简单的东西,例如删除相邻行中相同数量的空格。

否则,键盘宏是必经之路。


2

上面显示的答案用于在列中插入文本。TextMate的“编辑选择中的每一行”在每行中插入相同的文本,而不管每行的长度如何。我现在正在学习Lisp,因此作为练习,我编写了一个函数来做到这一点:

(defun append-to-lines (text-to-be-inserted)
  ;;Appends text to each line in region
  (interactive "sEnter text to append: ")
  (save-excursion
    (let (point-ln mark-ln initial-ln final-ln count)
      (barf-if-buffer-read-only)
      (setq point-ln (line-number-at-pos))
      (exchange-point-and-mark)
      (setq mark-ln (line-number-at-pos))
      (if (< point-ln mark-ln)
          (progn (setq initial-ln point-ln final-ln mark-ln)
                 (exchange-point-and-mark))
        (setq initial-ln mark-ln final-ln point-ln))
      (setq count initial-ln)
      (while (<= count final-ln)
        (progn (move-end-of-line 1)
               (insert text-to-be-inserted)
               (next-line)
               (setq count (1+ count))))
      (message "From line %d to line %d." initial-ln final-ln ))))

您首先进行选择,其中包含要影响的所有行,然后使用Mx附加行来运行该函数。


我还没有测试过,但是很好。我对“将相同的文本添加到相同的列”方法更感兴趣,但是我相信这也会派上用场。
allyourcode
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.