Ich habe die gleiche Frage für VIM gesehen und wollte selbst wissen, wie man das für Emacs macht. In ReSharper verwende ich STRG-D für diese Aktion. Was ist die geringste Anzahl von Befehlen, um dies in Emacs auszuführen?
Ich habe die gleiche Frage für VIM gesehen und wollte selbst wissen, wie man das für Emacs macht. In ReSharper verwende ich STRG-D für diese Aktion. Was ist die geringste Anzahl von Befehlen, um dies in Emacs auszuführen?
Antworten:
ich benutze
C-a C-SPACE C-n M-w C-y
was zusammenbricht zu
C-a
: Bewegen Sie den Cursor zum ZeilenanfangC-SPACE
: eine Auswahl beginnen ("Marke setzen")C-n
: Bewegen Sie den Cursor in die nächste ZeileM-w
: Region kopierenC-y
: Einfügen ("reißen")Das vorgenannte
C-a C-k C-k C-y C-y
beträgt dasselbe (TMTOWTDI)
C-a
: Bewegen Sie den Cursor zum ZeilenanfangC-k
: Schneiden Sie die Linie ("töten")C-k
: Schneiden Sie die NewlineC-y
: paste ("yank") (wir sind wieder auf dem ersten Platz)C-y
: wieder einfügen (jetzt haben wir zwei Kopien der Zeile)Diese sind beide im Vergleich zu C-d
Ihrem Editor peinlich ausführlich , aber in Emacs gibt es immer eine Anpassung. C-d
ist delete-char
standardmäßig gebunden , wie wäre es also C-c C-d
? Fügen Sie einfach Folgendes zu Ihrem hinzu .emacs
:
(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 kaputt geht, wenn eine der Tastenkombinationen geändert wird.)
Achtung: Einige Emacs-Modi fordern möglicherweise C-c C-d
etwas anderes zurück.
C-S-backspace C-y C-y
?
Zusätzlich zu den vorherigen Antworten können Sie auch Ihre eigene Funktion zum Duplizieren einer Zeile definieren. Wenn Sie beispielsweise Folgendes in Ihre .emacs-Datei einfügen, wird Cd 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)
Symbol's function definition is void: move-beginning-of-line
Del
von dieser Funktion lösen kann?
Del
um zum Normalzustand zurückzukehren und gleichzeitig das Neue beizubehalten C-d
: (global-set-key (kbd "<delete>") 'delete-char)
Muss nach der C-d
Definition hinzugefügt werden .
Platzieren Sie den Cursor auf der Linie, wenn nicht am Anfang ein CTRL- A, dann:
CTRL- -K
CTRL- -K
CTRL- -Y
CTRL- -Y
Meine Version einer Funktion zum Duplizieren einer Zeile, die beim Rückgängigmachen gut funktioniert und die Cursorposition nicht beeinträchtigt. 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))
Anschließend können Sie STRG-D definieren, um diese Funktion aufzurufen:
(global-set-key (kbd "C-d") 'duplicate-line)
crux-duplicate-current-line-or-region
funktioniert bei mir besser, weil es mit Ihrer Funktion auch die Zeilenduplizierung und die letzte Operation rückgängig macht.
Statt kill-line
( C-k
) , wie in C-a
C-k
C-k
C-y
C-y
Verwendung den kill-whole-line
Befehl:
C-S-Backspace
C-y
C-y
Zu den Vorteilen gegenüber C-k
gehört, dass es keine Rolle spielt, wo sich der Punkt auf der Linie befindet (im Gegensatz C-k
dazu, dass man sich am Anfang der Linie befindet) und dass auch die neue Linie getötet wird (wieder C-k
funktioniert etwas nicht).
Hier ist noch eine weitere Funktion, um dies zu tun. Meine Version berührt den Kill-Ring nicht und der Cursor landet in der neuen Zeile, in der er sich auf dem Original befand. Der Bereich wird dupliziert, wenn er aktiv ist (Übergangsmarkierungsmodus), oder die Linie wird standardmäßig anderweitig dupliziert. Es werden auch mehrere Kopien erstellt, wenn ein Präfixargument angegeben wird, und die ursprüngliche Zeile auskommentiert, wenn ein negatives Präfixargument angegeben wird (dies ist nützlich, um eine andere Version eines Befehls / einer Anweisung zu testen, während die alte beibehalten wird).
(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 gebunden an C-c d
:
(global-set-key [?\C-c ?d] 'duplicate-line-or-region)
Dies sollte niemals durch einen Modus oder etwas anderes neu zugewiesen werden, da C-c
gefolgt von einem einzelnen (nicht geänderten) Buchstaben für Benutzerbindungen reserviert ist.
C-c d
erhalte ich den Fehler command-execute: Wrong type argument: commandp, duplicate-line-or-region
. Irgendeine Idee, was los ist? Ich benutze Emacs 25.1.1 unter Windows
Nathans Hinzufügung zu Ihrer .emacs-Datei ist der richtige Weg, könnte aber durch Ersetzen leicht vereinfacht werden
(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)
installiere duplicate-thing von melpa:
Mx Paket-Install RET Duplikat-Ding
und fügen Sie diese Schlüsselbindung zur Init-Datei hinzu :
(Global-Set-Key (kbd "Mc") 'Duplikat-Ding)
Ich erinnere mich nicht genau, wie das Duplizieren von Zeilen anderswo funktioniert, aber als ehemaliger SciTE-Benutzer mochte ich eines an SciTE-way: Es berührt nicht die Cursorposition! Alle oben genannten Rezepte waren nicht gut genug für mich, hier ist 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 während des Vorgangs nichts tatsächlich getötet wird und Markierungen und die aktuelle Auswahl intakt bleiben.
Übrigens, warum ruckelt ihr so gern mit dem Cursor herum, wenn es dieses nette und saubere Kill-Whole-Line-Ding (CS-Backspace) gibt?
weil ich es nicht weiß, beginne ich diese Golfrunde mit einem Slowball:
Strg-k, y, y
etwas, das Sie vielleicht in Ihren .emacs haben möchten, ist
(setq kill-whole-line t)
Dies tötet im Grunde die gesamte Zeile plus die neue Zeile, wenn Sie die Kill-Zeile aufrufen (dh über Ck). Dann können Sie ohne zusätzlichen Code einfach Ca Ck Cy Cy ausführen, um die Zeile zu duplizieren. Es bricht zusammen 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 möglicherweise eine dedizierte Schlüsselbindung eine bessere Idee. Der Vorteil der Verwendung von Ca Ck Cy Cy besteht jedoch darin, dass Sie die Zeile an anderer Stelle duplizieren können, anstatt direkt unter der aktuellen Zeile.
Ich habe copy-from-above-command
an einen Schlüssel gebunden und benutze diesen. Es ist mit XEmacs ausgestattet, aber ich weiß nichts über GNU Emacs.
"Kopieren von oben" ist eine interaktive kompilierte Lisp-Funktion
- geladen von" /usr/share/xemacs/21.4.15/lisp/misc.elc "(Copy-from-Above-Command & optionales ARG)Dokumentation: Kopieren Sie Zeichen aus der vorherigen nicht leeren Zeile , beginnend direkt über dem Punkt. Kopieren Sie ARG-Zeichen, jedoch nicht über das Ende dieser Zeile hinaus. Wenn kein Argument angegeben wird, kopieren Sie den gesamten Rest der Zeile. Die kopierten Zeichen werden vor dem Punkt in den Puffer eingefügt.
GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped]
.
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 noch die Kombination eingeben und erhalten diese Zeile. Dies funktioniert auch für die Region. Dann müssen Sie nur noch zwei Kombinationen eingeben.
Hier sehen Sie die Schnittstelle:
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)))))
Legen Sie das oben in .emacs
. Dann, um eine Zeile zu kopieren , M-w
. So löschen Sie eine Zeile , C-w
. So duplizieren Sie eine Zeile , C-a M-w C-y C-y C-y ...
.
„Ich habe meine eigene Version von geschrieben duplicate-line
, weil ich den Todesring 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)
Ich mochte die FraGGod-Version, abgesehen von zwei Dingen: (1) Sie prüft nicht, ob der Puffer bereits schreibgeschützt ist (interactive "*")
, und (2) sie schlägt in der letzten Zeile des Puffers fehl, wenn diese letzte Zeile leer ist (wie Sie kann die Zeile in diesem Fall nicht beenden), sodass Ihr Puffer schreibgeschützt bleibt.
Ich habe die folgenden Ä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)))))
Mit den neuesten Emacs können Sie Mw an einer beliebigen Stelle in der Zeile verwenden, um es zu kopieren. So wird es:
M-w C-a RET C-y
M-w
ist an gebunden easy-kill
. Überprüfen Sie, was Sie bekommen, wenn Sie tunC-h c M-w
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)
ctrl- k, ctrl- k, (Position zum neuen Standort) ctrl-y
Fügen Sie ein ctrl- hinzu, awenn Sie nicht am Zeilenanfang beginnen. Und das zweite ctrl- kist, den Zeilenumbruch zu greifen. Es kann entfernt werden, wenn Sie nur den Text möchten.
Wenn Sie interaktiv ohne aktive Region aufgerufen werden, kopieren Sie stattdessen (Mw) 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 interaktiv ohne aktive Region aufgerufen, wird stattdessen eine einzelne Zeile getötet (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)))))
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)
Ich schreibe eine für meine Präferenz.
(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 stellte jedoch fest, dass dies ein Problem darstellen würde, wenn die aktuelle Zeile Multi-Byte-Zeichen enthält (z. B. CJK-Zeichen). Wenn dieses Problem auftritt, versuchen Sie Folgendes:
(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)
Diese Funktionalität sollte mit der Implementierung von JetBrains übereinstimmen, da sowohl nach Linie als auch nach Region dupliziert wird und dann der Punkt und / oder die aktive Region wie erwartet belassen werden:
Nur ein Wrapper um 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)))
Was das nennt,
(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 dies an meta + shift + d gebunden
(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
Wie in anderen Antworten erwähnt, ist es besser, Tastenanschläge an Lisp-Code zu binden, als sie an andere Tastenanschläge zu binden. Mit der Antwort von @ mw dupliziert der Code die Zeile und verschiebt die Markierung an das Ende der neuen Zeile. Durch diese Änderung bleibt die Markierungsposition in derselben Spalte in der neuen Zeile:
fun duplicate-line ()
(interactive)
(let ((col (current-column)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
(move-to-column col)))
Wenn Sie Spacemacs verwenden, können Sie einfach Folgendes verwenden duplicate-line-or-region
:
SPC x l d
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 bleibt in der letzten Zeile. Alternativ können Sie ein Präfix angeben, um die nächsten Zeilen gleichzeitig 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 verwende beide häufig 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)
;; 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ügen Sie das obige Elisp zu Ihrer init.el hinzu, und Sie erhalten jetzt die Funktion zum Ausschneiden / Kopieren ganzer Zeilen. Anschließend können Sie mit F3 F4 eine Zeile duplizieren.
Der einfachste Weg ist die Methode von Chris Conway.
C-a C-SPACE C-n M-w C-y
Dies ist die von EMACS vorgeschriebene Standardmethode. Meiner Meinung nach ist es besser, den Standard zu verwenden. Ich bin immer vorsichtig bei der Anpassung der eigenen Schlüsselbindung in EMACS. EMACS ist bereits leistungsfähig genug. Ich denke, wir sollten unser Bestes geben, um uns an die eigenen Tastenkombinationen anzupassen.
Es ist zwar etwas langwierig, aber wenn Sie daran gewöhnt sind, können Sie es schnell machen und werden feststellen, dass dies Spaß macht!
Hier ist eine Funktion zum Duplizieren der aktuellen Zeile. Mit Präfixargumenten wird die Zeile mehrmals dupliziert. ZB C-3 C-S-o
wird die aktuelle Zeile dreimal dupliziert. Ä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)