我如何在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)
将光标放在线上,如果不是在开始时按CTRL – A ,则:
CTRL – K
CTRL – K
CTRL – Y
CTRL – Y
我的一个函数版本复制了一个可以很好地处理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-line
( Ck
):
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来复制一行。
ctrl – k , ctrl – k ,(位置到新位置) ctrl – y
添加一个ctrl – a,如果你不是从行首开始。 而第二个CTRL – K是抓住换行符。 如果你只是想要的文字,它可以被删除。
最简单的方法是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两个组合。
在这里你可以看到界面:
通常使用的很好:
Ctl-空间(设置标记) 移动到行尾 Ctl-K杀死线 Ctl-Y * 2(将线路拉回)
可能有更好的办法,但:P