如何在Emacs中复制整行?
我对VIM看到了同样的问题,这是我自己想知道如何为Emacs做的事情。在ReSharper中,我使用CTRL-D进行此操作。在Emacs中执行此操作的最少命令数是多少?
解决方案
我经常使用的:
Ctl-Space (set the mark) move to end of line Ctl-K kill line Ctl-Y * 2 (yank the line back)
也许有更好的方法:P
因为我不知道,我将从慢球开始这一轮高尔夫:
ctrl-k,y,y
ctrl
-k
,ctrl
-k
(到新位置的位置)ctrl
-y
如果我们不是从行首开始,请添加ctrl
-a
。第二个ctrl -k是要获取换行符。如果只需要文本,可以将其删除。
将光标放在行上,如果不是开始时执行CTRL
-A
,则:
CTRL
-K
CTRL
-K
CTRL
-Y
CTRL
-Y
@ [Kevin Conner]:据我所知,非常接近。唯一需要考虑的另一件事是打开" kill-whole-line"以在C-k中包括换行符。
C-a C-k C-k C-y C-y
我用
C-a C-SPACE C-n M-w C-y
分解为
- C-a:将光标移至行首
- C-SPACE:开始选择("设置标记")
- C-n:将光标移至下一行
M-w
:复制区域C-y
:粘贴("扬")
之前所提
C-a C-k C-k C-y C-y
等于同一件事(TMTOWTDI)
- C-a:将光标移至行首
C-k
:剪断("杀")线C-k
:换行C-y
:粘贴("扬")(我们回到第一个方框)C-y
:再次粘贴(现在我们有该行的两个副本)
与编辑器中的C-d
相比,它们都令人尴尬地冗长,但是在Emacs中始终有一个自定义项。 C-d
默认绑定到delete-char
,那么C-c C-d
呢?只需将以下内容添加到.emacs
中:
(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")
(@Nathan的elisp版本可能是更可取的,因为如果更改任何键绑定,它都不会中断。)
当心:某些Emacs模式可能会回收C-c C-d
来做其他事情。
除了前面的答案,我们还可以定义自己的函数来复制一行。例如,将以下内容放入.emacs文件将使C-d复制当前行。
(defun duplicate-line() (interactive) (move-beginning-of-line 1) (kill-line) (yank) (open-line 1) (next-line 1) (yank) ) (global-set-key (kbd "C-d") 'duplicate-line)
我将"从上面复制命令"绑定到一个键并使用它。它随XEmacs一起提供,但我不了解GNU Emacs。
`copy-from-above-command' is an interactive compiled Lisp function -- loaded from "/usr/share/xemacs/21.4.15/lisp/misc.elc" (copy-from-above-command &optional ARG) Documentation: Copy characters from previous nonblank line, starting just above point. Copy ARG characters, but not past the end of that line. If no argument given, copy the entire rest of the line. The characters copied are inserted in the buffer before point.
内森(Nathan)在.emacs文件中的添加方式是可行的,但是可以通过替换来稍微简化它
(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 "C-d") 'duplicate-line)
我们可能想要在.emacs中包含的内容是
(setq kill-whole-line t)
基本上,每当我们调用kill-line(即通过C-k)时,都会杀死整行以及换行符。然后,无需额外的代码,我们只需执行C-a C-k C-y C-y即可复制该行。它分解为
C-a go to beginning of line C-k kill-line (i.e. cut the line into clipboard) C-y yank (i.e. paste); the first time you get the killed line back; second time gives the duplicated line.
但是,如果我们经常使用它,那么专用的键绑定也许是一个更好的主意,但是仅使用C-a C-k C-y C-y的优点是我们可以在其他地方复制该行,而不仅仅是在当前行下方。
默认设置对此非常可怕。但是,我们可以扩展Emacs使其像SlickEdit和TextMate一样工作,也就是说,当没有选择任何文本时,复制/剪切当前行:
(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
中。然后,复制一条线," M-w"。要删除一行,C-w
。要复制一行,请输入" C-a M-w C-y C-y C-y ..."。
我不太记得行复制在其他任何地方的工作方式,但是作为前SciTE用户,我喜欢SciTE-way的一件事:它不会碰到光标位置!
因此,以上所有方法对我来说都不足够,这是我的嬉皮版本:
(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))))
请注意,实际上没有任何东西在进程中被杀死,不会留下任何痕迹和当前选择。
顺便说一句,为什么你们会喜欢在这种不错的"干净的全线杀人事件"(C-S-backspace)周围晃动光标?
我的函数版本可以复制一条行,该行可以与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 "C-d") 'duplicate-line)
'我写了自己的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)
代替C-a``C-k
C-kC-y
C-y中的
kill-line(
C-k),使用
kill-whole-line`命令:
C-S-Backspace C-y C-y
与C-k
相比的优点在于,在线上的点无关紧要(不同于C-k
要求在行的开始处),并且它也杀死换行符(同样,C-k
也不行)。
我喜欢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)))))
具有前缀参数,什么是(我希望)直观的行为:
(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))
我发现自己经常使用两者,使用包装函数来切换prefix参数的行为。
和一个绑定:
`(global-set-key(kbd" C-S-d")'重复行)