如何在Emacs中复制整行?

175

我看到了关于VIM的相同问题,这也是我自己在Emacs中想要知道如何实现的。在ReSharper中,我使用CTRL-D来执行此操作。在Emacs中执行此操作的最少命令数是多少?


2
当然,这是emacs,所以TMTOWTDI - 有22种!(还在不断增加中)http://c2.com/cgi/wiki?ThereIsMoreThanOneWayToDoIt - Tom
34个回答

3

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

按下ctrl键和k键,松开后再依次按下y键两次。


2
这里有一个用于复制当前行的函数。使用前缀参数,它可以多次复制该行。例如:C-3 C-S-o会将当前行复制三次。不会改变kill ring。
(defun duplicate-lines (arg)
  (interactive "P")
  (let* ((arg (if arg arg 1))
         (beg (save-excursion (beginning-of-line) (point)))
         (end (save-excursion (end-of-line) (point)))
         (line (buffer-substring-no-properties beg end)))
    (save-excursion
      (end-of-line)
      (open-line arg)
      (setq num 0)
      (while (< num arg)
        (setq num (1+ num))
        (forward-line 1)
        (insert line))
      )))

(global-set-key (kbd "C-S-o") 'duplicate-lines)

2
我无法相信所有这些复杂的解决方案。这只需要两个按键:

<C-S-backspace> 运行命令 kill-whole-line
C-/ 运行命令 undo

所以使用 <C-S-backspace> C-/ 可以“复制”整行(删除和撤销)。

当然,您可以将其与数字和负参数结合使用,向前或向后删除多行。

不幸的是,就像我的情况一样:“请注意,许多文本终端将阻止您键入键序列C-S-backspace。” https://www.gnu.org/software/emacs/manual/html_node/emacs/Killing-by-Lines.html - Michael Terry

2
如果您正在使用Spacemacs,您可以简单地使用duplicate-line-or-region,它绑定在:
SPC x l d 

2

ctrl-k, ctrl-k, (将光标移动到新位置) ctrl-y

如果你不是从行首开始,请加上ctrl-a。第二个ctrl-k是为了选中换行符,如果只想复制文本可以省略。


这一定是这里最简单的方法。谢谢! - bartlomiej.n

2

@[Kevin Conner]: 就我所知,你的翻译已经很接近了。唯一需要考虑的是打开kill-whole-line以在C-k中包括换行符。


@Allen:在 @[Kevin Conner] 中移除 [] - jfs

2
在Melpa上有一个名为“move-dup”的软件包,可以帮助您完成此操作。
免责声明:我是该软件包的作者。

1
我为自己的喜好写了一个。
(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 "C-c d l") '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 "C-c d l") 'duplicate-line)

1
如其他答案所述,将按键绑定到Lisp代码比将其绑定到其他按键更好。在@mw的回答中,代码会复制该行并将标记移动到新行的末尾。这种修改使标记位置保持在新行的同一列:
fun duplicate-line ()
  (interactive)
  (let ((col (current-column)))
    (move-beginning-of-line 1)
    (kill-line)
    (yank)
    (newline)
    (yank)
    (move-to-column col)))

0

使用前缀参数,并且具有(我希望)直观的行为:

(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 "C-S-d") 'duplicate-line)


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