it-swarm-eu.dev

Wie kopiere ich eine ganze Zeile in Emacs?

Ich sah dieselbe Frage für VIM und es war etwas, das ich selbst wissen wollte, wie man Emacs macht. In ReSharper verwende ich für diese Aktion STRG-D. Was ist die geringste Anzahl von Befehlen, um dies in Emacs auszuführen?

136
Ray Vega

Ich benutze 

C-a C-SPACE C-n M-w C-y

was bricht zu

  • C-a: Bewegt den Cursor zum Zeilenanfang
  • C-SPACE: eine Auswahl beginnen ("Markierung setzen")
  • C-n: Bewegt den Cursor in die nächste Zeile
  • M-w: kopierbereich
  • C-y: einfügen ("yank")

Das vorgenannte

C-a C-k C-k C-y C-y

beläuft sich auf dasselbe (TMTOWTDI)

  • C-a: Bewegt den Cursor zum Zeilenanfang
  • C-k: schneide ("kill") die Zeile
  • C-k: schneide den Zeilenumbruch ab
  • C-y: paste ("yank") (wir sind wieder auf Platz eins)
  • C-y: wieder einfügen (jetzt haben wir zwei Exemplare der Zeile)

Dies ist im Vergleich zu C-d in Ihrem Editor peinlich ausführlich, aber in Emacs gibt es immer eine Anpassung. C-d ist standardmäßig an delete-char gebunden. Wie sieht es mit C-c C-d aus? Fügen Sie einfach folgenden Code zu Ihrem .emacs hinzu:

(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")

(@ Nathans elisp-Version ist wahrscheinlich vorzuziehen, da sie nicht beschädigt wird, wenn eine der Tastenkombinationen geändert wird.)

Achtung: Einige Emacs-Modi können C-c C-d zurückfordern, um etwas anderes zu tun.

135
Chris Conway

Neben den vorherigen Antworten können Sie auch eine eigene Funktion definieren, um eine Zeile zu duplizieren. Wenn Sie beispielsweise Folgendes in Ihre .emacs-Datei einfügen, wird C-d die aktuelle Zeile duplizieren.

(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)
92
Nate

Cursor auf Linie setzen, wenn nicht am Anfang a CTRL-A, dann:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

60
epatel

Meine Version einer Funktion zum Duplizieren einer Zeile, die Nice mit Undo funktioniert und sich nicht mit der Cursorposition beschäftigt Es war das Ergebnis einer Diskussion in gnu.emacs.sources vom 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))

Dann können Sie CTRL-D definieren, um diese Funktion aufzurufen:

(global-set-key (kbd "C-d") 'duplicate-line)
51
pesche

Anstelle von kill-line (C-k) wie in C-aC-kC-kC-yC-y verwenden Sie den Befehl kill-whole-line :

C-S-Backspace
C-y
C-y

Die Vorteile gegenüber C-k umfassen, dass es nicht wichtig ist, wo sich der Punkt auf der Linie befindet (im Gegensatz zu C-k, das am Anfang der Zeile stehen muss) und dass auch die Newline beseitigt wird (wiederum C-k nicht).

42
Ray Vega

Hier ist noch eine weitere Funktion dazu. Meine Version berührt den Kill-Ring nicht und der Cursor befindet sich in der neuen Zeile, in der er sich auf dem Original befand. Die Region wird dupliziert, wenn sie aktiv ist (Modus für Transientenmarkierungen). Andernfalls wird standardmäßig die Zeile dupliziert. Wenn ein Präfix arg angegeben wird, werden auch mehrere Kopien erstellt und die negative Zeile des negativen Präfix arg auskommentiert.

(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)))))

Ich habe es an C-c d gebunden:

(global-set-key [?\C-c ?d] 'duplicate-line-or-region)

Dies sollte niemals durch einen Modus oder irgendetwas neu zugewiesen werden, da C-c, gefolgt von einem einzelnen (unveränderten) Buchstaben, für Benutzerbindungen reserviert ist.

24
qmega

Nathans Ergänzung zu Ihrer .emacs-Datei ist der Weg, der jedoch durch Ersetzen leicht vereinfacht werden kann 

  (open-line 1)
  (next-line 1)

mit

  (newline)

nachgeben

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (newline)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
16
pw.

duplikat-Ding von melpa installieren:

M-x Paketinstallations-RET-Duplikat

und fügen Sie diese Tastenkombination zu init-Datei hinzu:

(global-set-key (kbd "M-c") 'Duplikat')

5
user2626414

Ich kann mich nicht genau erinnern, wie die Linienduplizierung an anderen Stellen funktioniert, aber als ehemaliger SciTE-Benutzer hat mir SciTE-Weg vor allem eines gefallen: Es berührt die Cursorposition nicht! für mich hier meine Hippie-Version:

(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))))

Beachten Sie, dass im Prozess nichts tatsächlich getötet wird, Markierungen und aktuelle Auswahl intakt bleiben.

Übrigens, warum liebt man es, den Cursor herumzuziehen, wenn es dieses Nice'n'clean-Kill-Full-Line-Ding (C-S-Backspace) gibt?

5
mk-fg

Ich habe copy-from-above-command an einen Schlüssel gebunden und verwende diesen. Es wird mit XEmacs geliefert, aber ich weiß nicht über GNU Emacs.

`copy-from-above-command 'ist eine interaktive kompilierte LISP-Funktion
- geladen von "/usr/share/xemacs/21.4.15/LISP/misc.elc" (copy-from-above-command & optional ARG)

Dokumentation: Zeichen aus .__ kopieren. vorherige nicht leere Zeile , beginnt gerade über dem Punkt. Kopieren Sie ARG-Zeichen, aber nicht über das Ende dieser Zeile hinaus. Wenn nein Argument gegeben, kopieren Sie den gesamten Rest der Linie. Die kopierten Zeichen sind vor dem Punkt in den Puffer eingefügt.

4
Darron

weil ich nicht weiß, werde ich diese Runde mit einem Slowball beginnen:

ctrl-k, y, y

4
Kevin Conner

Bei aktuellen Emacs können Sie M-w überall in der Zeile verwenden, um es zu kopieren. So wird es:

M-w C-a RET C-y
3
Louis Kottmann
C-a C-k C-k C-y C-y
3
sverrejoh

etwas, das Sie in Ihren .emacs haben möchten, ist 

(setq kill-whole-line t)

Das bedeutet im Grunde die gesamte Zeile plus die Newline, wenn Sie die Kill-Line aufrufen (d. H. Über C-k). Dann können Sie ohne zusätzlichen Code einfach C-aC-kC-yC-y ausführen, um die Zeile zu duplizieren. Es bricht zu 

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.

Wenn Sie dies jedoch häufig verwenden, ist eine dedizierte Tastenbindung möglicherweise eine bessere Idee. Der Vorteil der Verwendung von C-C-K-C-Y-C-y besteht jedoch darin, dass Sie die Zeile an anderer Stelle duplizieren können, anstatt direkt unter der aktuellen Zeile.

3
polyglot

Die Standardeinstellungen sind dafür schrecklich. Sie können Emacs jedoch so erweitern, dass es wie SlickEdit und TextMate funktioniert, dh die aktuelle Zeile kopieren/ausschneiden, wenn kein Text ausgewählt ist:

(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)))))

Platzieren Sie das obige in .emacs. Um dann eine Zeile zu kopieren, M-w. Um eine Zeile zu löschen, C-w. Um eine Zeile zu duplizieren, C-a M-w C-y C-y C-y ....

3
Marius Andersen

Ich habe sowieso sehr komplexe Lösungen gesehen ...

(defun duplicate-line ()
  "Duplicate current line"
  (interactive)
  (kill-whole-line)
  (yank)
  (yank))
(global-set-key (kbd "C-x M-d") 'duplicate-line)
3
user6581334

'Ich habe meine eigene Version von duplicate-line geschrieben, weil ich den Mordring nicht vermasseln will.

  (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)
3
Joyer

Es gibt ein Paket namens Avy Es hat den Befehl avy-copy-line. Wenn Sie diesen Befehl verwenden, erhält jede Zeile in Ihrem Fenster eine Buchstabenkombination. Dann müssen Sie nur die Kombination eingeben und erhalten diese Zeile. Dies funktioniert auch für die Region. Dann müssen Sie nur zwei Kombinationen eingeben.

Hier sehen Sie die Schnittstelle: 

http://i68.tinypic.com/24fk5eu.png

3
teksturi

@ [Kevin Conner]: Ziemlich nah, soweit ich weiß. Die einzige andere Sache, die Sie berücksichtigen sollten, ist, kill-whole-line zu aktivieren, um den Zeilenumbruch in das C-k aufzunehmen.

2
Allen

FraGGods Version hat mir gefallen, abgesehen von zwei Dingen: (1) Mit (interactive "*") wird nicht geprüft, ob der Puffer bereits schreibgeschützt ist Sie können die Zeile in diesem Fall nicht töten), sodass der Puffer schreibgeschützt bleibt.

Ich habe folgende Änderungen vorgenommen, um das zu beheben:

(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)))))
2
phils

Wenn Sie interaktiv ohne aktive Region aufgerufen werden, kopieren Sie stattdessen eine einzelne Zeile:

(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)))))

Wenn Sie interaktiv ohne aktiven Bereich aufgerufen werden, KILL (C-w) stattdessen eine einzelne Zeile.

(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)))))

Auch in einem verwandten Hinweis:

(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)
2
yPhil

Ich schreibe einen für meine Vorlieben.

(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)

Ich fand jedoch, dass dies ein Problem haben würde, wenn die aktuelle Zeile Mehrbytezeichen enthält (z. B. CJK-Zeichen). Wenn dieses Problem auftritt, versuchen Sie es stattdessen:

(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
kuanyui

ctrl-kctrl-k, (Position zu neuem Standort) ctrl-y

Füge hinzu ein ctrl-a wenn Sie nicht am Anfang der Zeile beginnen. Und der 2. ctrl-k ist das Newline-Zeichen zu greifen. Es kann entfernt werden, wenn Sie nur den Text möchten.

1
CJP

Diese Funktionalität sollte mit der JetBrains-Implementierung übereinstimmen, indem sowohl die Linie als auch die Region dupliziert und dann der Punkt und/oder die aktive Region wie erwartet verlassen werden:

Nur ein Wrapper für das interaktive Formular:

(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)))

Welches nennt das,

(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))

Oder dieses

(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))

Und dann habe ich das an meta + shift + d gebunden

(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
1
AesopHimself

M-c, Shift+Insertx2 (oder was auch immer Ihre Einfügeverknüpfung ist) wird es tun.

0
Andrew Naguib
;; 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.

füge den elisp oben zu dir init.el hinzu, und du bekommst die Funktion zum Ausschneiden/Kopieren der gesamten Zeile, dann kannst du F3 F4 verwenden, um eine Zeile zu duplizieren.

0
WisdomFusion

Dies fühlt sich natürlicher an in Bezug auf die ausgewählte Antwort von Chris Conway.

(global-set-key "\ C-c\C-d" "\ C-a\C-\C-n\M-w\C-y\C-p\C-e")

Auf diese Weise können Sie eine Zeile mehrmals duplizieren, indem Sie einfach die\C-c\C-d-Tastenkombinationen wiederholen.

0
Shim Kporku

Hier ist eine Funktion zum Duplizieren der aktuellen Zeile. Mit Präfix-Argumenten wird die Zeile mehrmals dupliziert. Zum Beispiel wird C-3 C-S-o die aktuelle Zeile dreimal duplizieren. Ändert den Kill-Ring nicht. 

(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)
0
Dodgie

Wie in anderen Antworten erwähnt, ist das Binden von Tastatureingaben an LISP-Code eine bessere Idee als das Binden an andere Tastenkombinationen. Mit der Antwort von @ mw dupliziert der Code die Zeile und verschiebt die Markierung an das Ende der neuen Zeile. Diese Änderung behält die Markierungsposition in derselben Spalte in der neuen Zeile bei:

fun duplicate-line ()
  (interactive)
  (let ((col (current-column)))
    (move-beginning-of-line 1)
    (kill-line)
    (yank)
    (newline)
    (yank)
    (move-to-column col)))
0
krsoni

Ich kann nicht alle diese komplizierten Lösungen glauben. Dies sind zwei Tastenanschläge:

<C-S-backspace> führt den Befehl kill-whole-line aus

C-/ führt den Befehl rückgängig

Also <C-S-backspace> C-/, um eine ganze Zeile zu "kopieren" (töten und rückgängig machen).

Sie können dies natürlich mit numerischen und negativen Argumenten kombinieren, um mehrere Zeilen entweder vorwärts oder rückwärts zu löschen.

0
Andy

Der einfachste Weg ist die Methode von Chris Conway. 

C-a C-SPACE C-n M-w C-y

Dies ist die von EMACS vorgegebene Standardmethode. Meiner Meinung nach ist es besser, den Standard zu verwenden. Ich bin immer darauf bedacht, die eigene Schlüsselbindung in EMACS anzupassen. EMACS ist bereits stark genug. Ich denke, wir sollten unser Bestes geben, um uns an die eigenen Tastenkombinationen anzupassen. 

Es ist zwar etwas langwierig, aber wenn Sie es gewohnt sind, können Sie es schnell tun und werden feststellen, dass dies Spaß macht!

0
linbianxiaocao

Mit Präfixargumenten und was ist (ich hoffe) intuitives Verhalten:

(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))))))

Der Cursor verbleibt in der letzten Zeile. Alternativ können Sie auch ein Präfix angeben, um die nächsten Zeilen auf einmal zu duplizieren:

(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))

Ich benutze oft beide und verwende eine Wrapper-Funktion, um das Verhalten des Präfix-Arguments zu ändern.

Und eine Schlüsselbindung: (global-set-key (kbd "C-S-d") 'duplicate-line)

0
Karthik