我看到了this same question for VIM,我本人想知道如何为Emacs做些什么。在ReSharper中,我使用CTRL-D进行此操作。在Emacs中执行此操作的最少命令数是多少?
我用
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
:粘贴(“yank”)(我们回到正方形)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
来做其他事情。
因为我不知道,我会用慢球来开始这一轮高尔夫:
ctrl-k,y,y
'我写了自己的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。
`copy-from-above-command'是一个交互式编译的Lisp函数 - 从“/usr/share/xemacs/21.4.15/lisp/misc.elc”加载(copy-from-above-command&optional ARG)
文档:从上一个非空白行复制字符,从上面开始。复制ARG字符,但不能超过该行的结尾。如果没有给出参数,则复制整行的其余部分。复制的字符将在点之前插入缓冲区。
C-a C-k C-k C-y C-y
您可能希望在.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 ...
。
我喜欢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)))))
使用最近的emacs,您可以在行中的任何位置使用M-w来复制它。所以它变成:
M-w C-a RET C-y
无论如何,我看到非常复杂的解决方案......
(defun duplicate-line ()
"Duplicate current line"
(interactive)
(kill-whole-line)
(yank)
(yank))
(global-set-key (kbd "C-x M-d") 'duplicate-line)
有一个名为Avy的包它有命令avy-copy-line。当您使用该命令时,窗口中的每一行都会得到字母组合。然后你只需要输入组合就可以得到那条线。这也适用于地区。然后你只需要输入两个组合。
在这里你可以看到界面:
除了之前的答案,您还可以定义自己的函数来复制一行。例如,将以下内容放在.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)
@ [凯文康纳]:据我所知,非常接近。唯一需要考虑的是打开kill-whole-line
以包含C-k中的换行符。
当交互式调用没有活动区域时,COPY(M-w)代替一行:
(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(C-w)代替单行。
(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 down)] 'move-line-down)
ctrl-k,ctrl-k,(位置到新位置)ctrl-y
如果你没有从行的开头开始,请添加一个ctrl-a。第二个ctrl-k是抓取换行符。如果您只想要文本,可以将其删除。
我根据自己的喜好写了一个。
(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)
此功能应与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 n v))))
(next-line))
然后我将这绑定到meta + shift + d
(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
使用前缀参数,以及(我希望)直观行为是什么:
(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)
;; 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,然后立即剪切/复制整行功能,然后你可以F3 F4复制一行。
最简单的方法是Chris Conway的方法。
C-a C-SPACE C-n M-w C-y
这是EMACS规定的默认方式。在我看来,最好使用标准。我总是小心翼翼地在EMACS中定制一个自己的密钥绑定。 EMACS已经足够强大,我认为我们应该尽力适应自己的密钥绑定。
虽然它有点冗长,但是当你习惯它时,你可以做得很快,并会发现这很有趣!
这是复制当前行的功能。使用前缀参数,它将多次复制该行。例如,C-3 C-S-o
将复制当前行三次。不会改变杀戮戒指。
(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-string line))
)))
(global-set-key (kbd "C-S-o") 'duplicate-lines)
我无法相信所有这些复杂的解决方案。这是两次击键:
<C-S-backspace>
运行命令kill-whole-line
C-/
运行命令undo
所以<C-S-backspace> C-/
要“复制”整行(杀死和撤消)。
当然,您可以将其与数字和负数args相结合,以向前或向后杀死多条线。
将光标放在行上,如果不是在开头做一个CTRL-A,则:
CTRL-K
CTRL-K
CTRL-Y
CTRL-Y
就克里斯康威选定的答案而言,这感觉更自然。
(global-set-key“\ C-c \ C-d”“\ C-a \ C- \ C-n \ M-w \ C-y \ C-p \ C-e”)
这允许您通过简单地重复\ C-c \ C-d键击来多次复制一行。
我的函数版本复制一行,对撤销工作很好,不会弄乱光标位置。这是discussion in gnu.emacs.sources from November 1997的结果。
(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)
而不是kill-line
(C-k
)在C-a
C-k
C-k
C-y
C-y
使用kill-whole-line
命令:
C-S-Backspace
C-y
C-y
与C-k
相比的优势包括无论线上的哪个点都不重要(不像C-k
需要在线的起点)而且它也会杀死换行符(C-k
也不会这样做)。
这是另一个执行此操作的功能。我的版本没有碰到杀戮戒指,光标最终出现在原来的新线上。如果区域处于活动状态(瞬态标记模式),它将复制该区域,否则默认为复制该区域。如果给出前缀arg,它也会生成多个副本,如果给出一个负前缀arg,则注释掉原始行(这对于测试不同版本的命令/语句同时保留旧的命令/语句非常有用)。
(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)))))
我有它绑定到C-c d
:
(global-set-key [?\C-c ?d] 'duplicate-line-or-region)
这绝不应该由模式或任何东西重新分配,因为C-c
后跟一个(未修改的)字母保留给用户绑定。
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)
我不太清楚线复制是如何在其他任何地方工作的,但作为一名前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))))
请注意,在进程中实际上没有任何内容被杀死,标记和当前选择保持不变
顺便说一下,为什么你们这么喜欢摇摇欲坠的光标呢?有这个漂亮的'n'清洁杀死全线(C-S-backspace)?
从melpa安装重复的东西:
M-x package-install RET duplicate-thing
并将此键绑定添加到init file:
(global-set-key(kbd“M-c”)'重复的东西)