如何在Emacs中复制整行?

Ray*_*ega 149 emacs text command editing editor

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

Chr*_*way 142

我用

C-a C-SPACE C-n M-w C-y
Run Code Online (Sandbox Code Playgroud)

分解为

  • C-a:将光标移动到行首
  • C-SPACE:开始选择("设置标记")
  • C-n:将光标移动到下一行
  • M-w:复制区域
  • C-y:粘贴("猛")

之前所提

C-a C-k C-k C-y C-y
Run Code Online (Sandbox Code Playgroud)

相同的东西(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")
Run Code Online (Sandbox Code Playgroud)

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

注意:一些Emacs模式可能会重新C-c C-d开始做其他事情.

  • 这真的很令人尴尬. (169认同)
  • 那么`CS-backspace Cy Cy`怎么样? (18认同)
  • 当我真的感谢vim中的简单dd/yy或0y $ (11认同)
  • 嗨!请注意,如果你有'(setq kill-whole-line t)',你只需要一个'Ck'(解决方案2),因为它已经将新行与行的内容一起杀死了.我首选使用'C-k'.干杯,丹尼尔 (4认同)
  • @Bala"M"是"Meta"(通常是Esc或Alt,它取决于你的键盘布局)."Mw"同时是"Meta"和"w"(在我的键盘上,"Alt-w"). (4认同)

Nat*_*ate 94

除了之前的答案,您还可以定义自己的函数来复制一行.例如,将以下内容放在.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 "C-d") 'duplicate-line)
Run Code Online (Sandbox Code Playgroud)

  • 这个问题是"Del"键也绑定到重复行... (5认同)

epa*_*tel 62

将光标放在行上,如果不是在开头做一个CTRL- A,则:

CTRL- K

CTRL- K

CTRL- Y

CTRL- Y

  • 使用CS-Backspace(kill-whole-line)代替Ck.您不必拧动光标位置或杀死换行符. (17认同)
  • 没有,它不会重复 (4认同)

pes*_*che 51

我的函数版本复制一行,对撤销工作很好,不会弄乱光标位置.这是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))
Run Code Online (Sandbox Code Playgroud)

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

(global-set-key (kbd "C-d") 'duplicate-line)
Run Code Online (Sandbox Code Playgroud)

  • @pesche `crux-duplicate-current-line-or-region` 对我来说效果更好,因为使用你的函数它也可以撤销行重复和最后一次操作。 (2认同)

Ray*_*ega 44

而不是 使用命令中的kill-line(C-k):C-a C-k C-k C-y C-ykill-whole-line

C-S-Backspace
C-y
C-y
Run Code Online (Sandbox Code Playgroud)

优点C-k包括无论哪个点在线上都无关紧要(不像C-k需要在线的起点)并且它也会杀死换行符(再次有些东西C-k没有做).

  • 荣幸@RayVega!我尝试了这个解决方案,它就像一个冠军(在我的GNU Emacs 23.3.1中,无论如何).这个解决方案对某些人不起作用吗?这是您(自己)问题的最佳答案. (2认同)

qme*_*ega 25

这是另一个执行此操作的功能.我的版本没有碰到杀戮戒指,光标最终出现在原来的新线上.如果区域处于活动状态(瞬态标记模式),它将复制该区域,否则默认为复制该区域.如果给出前缀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)))))
Run Code Online (Sandbox Code Playgroud)

我有它必须C-c d:

(global-set-key [?\C-c ?d] 'duplicate-line-or-region)
Run Code Online (Sandbox Code Playgroud)

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


pw.*_*pw. 16

Nathan添加到您的.emacs文件是可行的方法,但可以通过替换来略微简化

  (open-line 1)
  (next-line 1)
Run Code Online (Sandbox Code Playgroud)

  (newline)
Run Code Online (Sandbox Code Playgroud)

生产

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (newline)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
Run Code Online (Sandbox Code Playgroud)


Dar*_*ron 5

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 字符,但不要超过该行的末尾。如果没有给出参数,则复制该行的其余部分。复制的字符在点之前插入缓冲区。

  • @qmega你需要做(需要'misc)。 (2认同)

mk-*_*-fg 5

我不太清楚线复制是如何在其他任何地方工作的,但作为一名前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))))
Run Code Online (Sandbox Code Playgroud)

请注意,在进程中实际上没有任何内容被杀死,标记和当前选择保持不变

顺便说一下,为什么你们这么喜欢摇摇晃晃的光圈呢?有这个漂亮的''清洁杀戮 - 全线(CS-backspace)?


小智 5

从melpa安装重复的东西:

Mx package-install RET duplicate-thing

并将此键绑定添加到init文件:

(global-set-key(kbd"Mc")'重复的东西)