我如何在Emacs中复制整行?

我看到了VIM的这个相同的问题,而且我自己也想知道如何为Emacs做些什么。 在ReSharper中,我使用CTRL-D进行这个操作。 在Emacs中执行此操作的命令数量最less是多less?

我用

Ca C-SPACE Cn Mw Cy 

分解到

  • Ca :将光标移动到行首
  • C-SPACE :开始select(“设置标记”)
  • Cn :将光标移动到下一行
  • Mw :复制区域
  • Cy :粘贴(“yank”)

之前所提

 Ca Ck Ck Cy Cy 

相当于同一件事(TMTOWTDI)

  • Ca :将光标移动到行首
  • Ck :切断(“杀死”)线路
  • Ck :切换换行符
  • Cy :粘贴(“yank”)(我们回到原点)
  • Cy :再次粘贴(现在我们有两行)

与编辑器中的Cd相比,这些都是令人尴尬的详细信息,但是在Emacs中总是有一个定制。 Cd默认情况下会delete-char ,那么Cc Cd怎么样? 只需将以下内容添加到.emacs

 (global-set-key "\Cc\Cd" "\Ca\C- \Cn\Mw\Cy") 

(@ Nathan的elisp版本可能是可取的,因为如果任何键绑定被改变,它不会中断。)

注意:一些Emacs模式可能会回收Cc Cd来做其他事情。

除了以前的答案,您还可以定义自己的函数来复制一条线。 例如,将以下内容放在.emacs文件中将使Cd复制当前行。

 (defun duplicate-line() (interactive) (move-beginning-of-line 1) (kill-line) (yank) (open-line 1) (next-line 1) (yank) ) (global-set-key (kbd "Cd") 'duplicate-line) 

将光标放在线上,如果不是在开始时按CTRLA ,则:

CTRLK

CTRLK

CTRLY

CTRLY

我的一个函数版本复制了一个可以很好地处理undo的行,并且不会混淆光标的位置。 这是1997年11月在gnu.emacs.sources上讨论的结果。

 (defun duplicate-line (arg) "Duplicate current line, leaving point in lower line." (interactive "*p") ;; save the point for undo (setq buffer-undo-list (cons (point) buffer-undo-list)) ;; local variables for start and end of line (let ((bol (save-excursion (beginning-of-line) (point))) eol) (save-excursion ;; don't use forward-line for this, because you would have ;; to check whether you are at the end of the buffer (end-of-line) (setq eol (point)) ;; store the line and disable the recording of undo information (let ((line (buffer-substring bol eol)) (buffer-undo-list t) (count arg)) ;; insert the line arg times (while (> count 0) (newline) ;; because there is no newline in 'line' (insert line) (setq count (1- count))) ) ;; create the undo information (setq buffer-undo-list (cons (cons eol (point)) buffer-undo-list))) ) ; end-of-let ;; put the point in the lowest line and return (next-line arg)) 

然后你可以定义CTRL-D来调用这个函数:

 (global-set-key (kbd "Cd") 'duplicate-line) 

Ca Ck Ck Cy Cy使用kill-whole-line命令代替kill-lineCk ):

 CS-Backspace Cy Cy 

Ck ,它的优点包括:线上的哪一点并不重要(不像Ck需要在线开始时),并且也杀死了换行符(再次是Ck不做的)。

这是另外一个function。 我的版本没有触及杀戒,光标在原来的新行上结束。 如果它处于激活状态(瞬态标记模式),则会复制该区域,否则将默认复制该行。 如果给定一个前缀arg,它也会产生多个副本,如果给定一个负前缀arg,这个注释掉原始行(这对于testing不同版本的命令/语句同时保留旧的)是有用的。

 (defun duplicate-line-or-region (&optional n) "Duplicate current line, or region if active. With argument N, make N copies. With negative N, comment out original line and use the absolute value." (interactive "*p") (let ((use-region (use-region-p))) (save-excursion (let ((text (if use-region ;Get region if active, otherwise line (buffer-substring (region-beginning) (region-end)) (prog1 (thing-at-point 'line) (end-of-line) (if (< 0 (forward-line 1)) ;Go to beginning of next line, or make a new one (newline)))))) (dotimes (i (abs (or n 1))) ;Insert N times, or once if not specified (insert text)))) (if use-region nil ;Only if we're working with a line (not a region) (let ((pos (- (point) (line-beginning-position)))) ;Save column (if (> 0 n) ;Comment out original with negative arg (comment-region (line-beginning-position) (line-end-position))) (forward-line 1) (forward-char pos))))) 

我有约束Cc d

 (global-set-key [?\Cc ?d] 'duplicate-line-or-region) 

这不应该由一个模式或任何东西重新分配,因为Cc后跟一个(未修改的)字母保留给用户绑定。

Nathan对.emacs文件的补充是要走的路,但是可以通过replace来简化

  (open-line 1) (next-line 1) 

  (newline) 

生产

 (defun duplicate-line() (interactive) (move-beginning-of-line 1) (kill-line) (yank) (newline) (yank) ) (global-set-key (kbd "Cd") 'duplicate-line) 

因为我不知道,我会用一个慢球开始这一轮高尔夫:

ctrl-k,y,y

我不太清楚线路复制在其他地方是如何工作的,但是作为一个以前的SciTE用户,我喜欢SciTE方式的一个方面:它不接触光标位置! 所以上面所有的对我来说都不够好,这是我的嬉皮士版本:

 (defun duplicate-line () "Clone line at cursor, leaving the latter intact." (interactive) (save-excursion (let ((kill-read-only-ok t) deactivate-mark) (toggle-read-only 1) (kill-whole-line) (toggle-read-only 0) (yank)))) 

请注意,在处理过程中没有任何事情会被杀死,留下标记和当前的select。

顺便说一句,为什么你们这么喜欢在这个不错的“干净的杀戮”(CS-backspace)的时候轻松地移动光标?

从melpa安装重复的东西

并添加这个键绑定:

(全球设置密钥(kbd“Mc”)'重复的东西)

 Ca Ck Ck Cy Cy 

你可能想在你的.emacs中有一些东西

 (setq kill-whole-line t) 

当你调用kill-line(即通过Ck)时,它基本上杀死整个行加上换行符。 然后没有额外的代码,你可以做Ca Ck Cy Cy复制行。 它分解为

 Ca go to beginning of line Ck kill-line (ie cut the line into clipboard) Cy yank (ie paste); the first time you get the killed line back; second time gives the duplicated line. 

但是如果你经常使用这个键,那么也许一个专用的键绑定可能是一个更好的主意,但是使用CaCk Cy Cy的好处是你可以在其他地方复制该行,而不是在当前行的下面。

这个默认是可怕的。 但是,您可以扩展Emacs以像SlickEdit和TextMate一样工作,即在未select文本时复制/剪切当前行:

 (transient-mark-mode t) (defadvice kill-ring-save (before slick-copy activate compile) "When called interactively with no active region, copy a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (message "Copied line") (list (line-beginning-position) (line-beginning-position 2))))) (defadvice kill-region (before slick-cut activate compile) "When called interactively with no active region, kill a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (list (line-beginning-position) (line-beginning-position 2))))) 

将上述放在.emacs 。 然后,复制一行, Mw 。 删除一行, Cw 。 复制一条线, Ca Mw Cy Cy Cy ...

“我写了我自己的版本的duplicate-line ,因为我不想搞砸了。

  (defun jr-duplicate-line () "EASY" (interactive) (save-excursion (let ((line-text (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (move-end-of-line 1) (newline) (insert line-text)))) (global-set-key "\C-cd" 'jr-duplicate-line) 

我有绑定到一个键copy-from-above-command并使用它。 它提供了XEmacs,但我不知道GNU Emacs。

“从上面复制”是一个交互式编译的Lisp函数
– 从“/usr/share/xemacs/21.4.15/lisp/misc.elc”(上面的命令和可选的ARG复制)

文档: 上面的非空行复制字符 ,从上面开始。 复制ARG字符,但不能超过该行的结尾。 如果没有给出的参数,复制整个行的其余部分。 点之前复制的字符被插入到缓冲区中。

使用最近的emacs,您可以使用该行中的任意位置的M来复制它。 所以它变成:

 Mw Ca RET Cy 

凯文·康纳(Kevin Conner):据我所知,就近在咫尺。 唯一需要考虑的是打开kill-whole-line来包含ck中的换行符。

我喜欢FraGGod的版本,除了两件事情:(1)它不检查缓冲区是否已经只读(interactive "*") ,(2)如果最后一行失败行是空的(因为在这种情况下你不能杀死这行),只保留你的缓冲区。

我做了以下更改来解决这个问题:

 (defun duplicate-line () "Clone line at cursor, leaving the latter intact." (interactive "*") (save-excursion ;; The last line of the buffer cannot be killed ;; if it is empty. Instead, simply add a new line. (if (and (eobp) (bolp)) (newline) ;; Otherwise kill the whole line, and yank it back. (let ((kill-read-only-ok t) deactivate-mark) (toggle-read-only 1) (kill-whole-line) (toggle-read-only 0) (yank))))) 

当与没有活动区域交互调用时,COPY(Mw)代替一行:

 (defadvice kill-ring-save (before slick-copy activate compile) "When called interactively with no active region, COPY a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (message "Copied line") (list (line-beginning-position) (line-beginning-position 2))))) 

当没有活动区域交互调用时,KILL(Cw)代替一行。

 (defadvice kill-region (before slick-cut activate compile) "When called interactively with no active region, KILL a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (message "Killed line") (list (line-beginning-position) (line-beginning-position 2))))) 

另外,在一个相关的说明:

 (defun move-line-up () "Move up the current line." (interactive) (transpose-lines 1) (forward-line -2) (indent-according-to-mode)) (defun move-line-down () "Move down the current line." (interactive) (forward-line 1) (transpose-lines 1) (forward-line -1) (indent-according-to-mode)) (global-set-key [(meta shift up)] 'move-line-up) (global-set-key [(meta shift up)] 'move-line-up) 

无论如何,我看到了非常复杂的解决scheme

 (defun duplicate-line () "Duplicate current line" (interactive) (kill-whole-line) (yank) (yank)) (global-set-key (kbd "Cx Md") 'duplicate-line) 

我为我的喜好写一个。

 (defun duplicate-line () "Duplicate current line." (interactive) (let ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol))) (cur-col (current-column))) (end-of-line) (insert "\n" text) (beginning-of-line) (right-char cur-col))) (global-set-key (kbd "Cc dl") 'duplicate-line) 

但是,我发现当前行包含多字节字符(例如CJK字符)时会出现一些问题。 如果遇到此问题,请尝试以下操作:

 (defun duplicate-line () "Duplicate current line." (interactive) (let* ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol))) (cur-col (length (buffer-substring-no-properties (point-at-bol) (point))))) (end-of-line) (insert "\n" text) (beginning-of-line) (right-char cur-col))) (global-set-key (kbd "Cc dl") 'duplicate-line) 

用前缀参数,什么是(我希望)直观的行为:

 (defun duplicate-line (&optional arg) "Duplicate it. With prefix ARG, duplicate ARG times." (interactive "p") (next-line (save-excursion (let ((beg (line-beginning-position)) (end (line-end-position))) (copy-region-as-kill beg end) (dotimes (num arg arg) (end-of-line) (newline) (yank)))))) 

光标将保留在最后一行。 或者,您可能需要指定一个前缀,以便一次复制下面几行:

 (defun duplicate-line (&optional arg) "Duplicate it. With prefix ARG, duplicate ARG times." (interactive "p") (save-excursion (let ((beg (line-beginning-position)) (end (progn (forward-line (1- arg)) (line-end-position)))) (copy-region-as-kill beg end) (end-of-line) (newline) (yank))) (next-line arg)) 

我发现自己经常使用包装函数来切换前缀参数的行为。

和一个键绑定:( (global-set-key (kbd "CSd") 'duplicate-line)

 ;; http://www.emacswiki.org/emacs/WholeLineOrRegion#toc2 ;; cut, copy, yank (defadvice kill-ring-save (around slick-copy activate) "When called interactively with no active region, copy a single line instead." (if (or (use-region-p) (not (called-interactively-p))) ad-do-it (kill-new (buffer-substring (line-beginning-position) (line-beginning-position 2)) nil '(yank-line)) (message "Copied line"))) (defadvice kill-region (around slick-copy activate) "When called interactively with no active region, kill a single line instead." (if (or (use-region-p) (not (called-interactively-p))) ad-do-it (kill-new (filter-buffer-substring (line-beginning-position) (line-beginning-position 2) t) nil '(yank-line)))) (defun yank-line (string) "Insert STRING above the current line." (beginning-of-line) (unless (= (elt string (1- (length string))) ?\n) (save-excursion (insert "\n"))) (insert string)) (global-set-key (kbd "<f2>") 'kill-region) ; cut. (global-set-key (kbd "<f3>") 'kill-ring-save) ; copy. (global-set-key (kbd "<f4>") 'yank) ; paste. 

添加上面的elisp到你的init.el,现在你可以切割/复制整行function,然后你可以用F3 F4来复制一行。

ctrlkctrlk ,(位置到新位置) ctrly

添加一个ctrla,如果你不是从行首开始。 而第二个CTRLK是抓住换行符。 如果你只是想要的文字,它可以被删除。

最简单的方法是Chris Conway的方法。

 Ca C-SPACE Cn Mw Cy 

这是EMACS规定的默认方式。 在我看来,最好使用这个标准。 我一直在EMACS中定制自己的键盘绑定。 EMACS已经足够强大了,我认为我们应该尽力适应自己的键绑定。

虽然它有点冗长,但是当你习惯了的时候,你可以做得很快,并且会觉得这很有趣!

这个function应该与JetBrains的实现相匹配,以便按行或区域进行复制,然后按照预期的方式离开点和/或活动区域:

只是围绕交互式表单的一个包装:

 (defun wrx/duplicate-line-or-region (beg end) "Implements functionality of JetBrains' `Command-d' shortcut for `duplicate-line'. BEG & END correspond point & mark, smaller first `use-region-p' explained: http://emacs.stackexchange.com/questions/12334/elisp-for-applying-command-to-only-the-selected-region#answer-12335" (interactive "r") (if (use-region-p) (wrx/duplicate-region-in-buffer beg end) (wrx/duplicate-line-in-buffer))) 

哪个叫这个,

 (defun wrx/duplicate-region-in-buffer (beg end) "copy and duplicate context of current active region |------------------------+----------------------------| | before | after | |------------------------+----------------------------| | first <MARK>line here | first line here | | second item<POINT> now | second item<MARK>line here | | | second item<POINT> now | |------------------------+----------------------------| TODO: Acts funky when point < mark" (set-mark-command nil) (insert (buffer-substring beg end)) (setq deactivate-mark nil)) 

或这个

 (defun wrx/duplicate-line-in-buffer () "Duplicate current line, maintaining column position. |--------------------------+--------------------------| | before | after | |--------------------------+--------------------------| | lorem ipsum<POINT> dolor | lorem ipsum dolor | | | lorem ipsum<POINT> dolor | |--------------------------+--------------------------| TODO: Save history for `Cmd-Z' Context: http://stackoverflow.com/questions/88399/how-do-i-duplicate-a-whole-line-in-emacs#answer-551053" (setq columns-over (current-column)) (save-excursion (kill-whole-line) (yank) (yank)) (let (v) (dotimes (n columns-over v) (right-char) (setq v (cons nv)))) (next-line)) 

然后我有这个绑定到meta + shift + d

 (global-set-key (kbd "MD") 'wrx/duplicate-line-or-region) 

有一个叫Avy的软件包它有命令avy-copy-line。 当你使用这个命令时,你窗口中的每一行都是字母组合。 那么你只需要input组合,你就可以得到这一行。 这也适用于地区。 那么你只需要input两个组合。

在这里你可以看到界面:

160wpb4.png

通常使用的很好:

  Ctl-空间(设置标记)
移动到行尾
 Ctl-K杀死线
 Ctl-Y * 2(将线路拉回) 

可能有更好的办法,但:P