Ho visto questa stessa domanda per VIM ed è stato qualcosa che io stesso volevo sapere come fare per Emacs. In ReSharper uso CTRL-D per questa azione. Qual è il numero minimo di comandi per eseguire questo in Emacs?
Ho visto questa stessa domanda per VIM ed è stato qualcosa che io stesso volevo sapere come fare per Emacs. In ReSharper uso CTRL-D per questa azione. Qual è il numero minimo di comandi per eseguire questo in Emacs?
Risposte:
Io uso
C-a C-SPACE C-n M-w C-y
che si rompe a
C-a
: sposta il cursore all'inizio della rigaC-SPACE
: inizia una selezione ("imposta segno")C-n
: sposta il cursore sulla riga successivaM-w
: copia regioneC-y
: incolla ("yank")Il suddetto
C-a C-k C-k C-y C-y
equivale alla stessa cosa (TMTOWTDI)
C-a
: sposta il cursore all'inizio della rigaC-k
: taglia ("uccidi") la lineaC-k
: taglia la nuova rigaC-y
: paste ("yank") (siamo tornati al punto di partenza)C-y
: incolla di nuovo (ora abbiamo due copie della linea)Questi sono entrambi imbarazzantemente dettagliati rispetto al C-d
tuo editor, ma in Emacs c'è sempre una personalizzazione. C-d
è vincolato per delete-char
impostazione predefinita, quindi che ne dici C-c C-d
? Aggiungi quanto segue al tuo .emacs
:
(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")
(Probabilmente è preferibile la versione elisp di @ Nathan, perché non si romperà se una qualsiasi delle combinazioni di tasti viene modificata.)
Attenzione: alcune modalità Emacs potrebbero richiedere C-c C-d
di fare qualcos'altro.
C-S-backspace C-y C-y
?
Oltre alle risposte precedenti, puoi anche definire la tua funzione per duplicare una riga. Ad esempio, inserendo quanto segue nel tuo file .emacs, Cd duplicherà la riga corrente.
(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
da questa funzione?
Del
alla normalità mantenendo il nuovo C-d
: (global-set-key (kbd "<delete>") 'delete-char)
deve essere aggiunto dopo la C-d
definizione.
Posiziona il cursore sulla linea, se non all'inizio fai un CTRL- A, quindi:
CTRL-K
CTRL-K
CTRL-Y
CTRL-Y
La mia versione di una funzione per duplicare una linea che funziona bene con annulla e non si scherza con la posizione del cursore. È stato il risultato di una discussione in gnu.emacs.sources del novembre 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))
Quindi è possibile definire CTRL-D per chiamare questa funzione:
(global-set-key (kbd "C-d") 'duplicate-line)
crux-duplicate-current-line-or-region
funziona meglio per me, perché con la tua funzione annulla la duplicazione della linea e anche l'ultima operazione.
Invece di kill-line
( C-k
) come in C-a
C-k
C-k
C-y
C-y
uso il kill-whole-line
comando:
C-S-Backspace
C-y
C-y
I vantaggi sopra C-k
includono che non importa dove si trovi il punto sulla linea (a differenza di quello C-k
che richiede di essere all'inizio della linea) e uccide anche la newline (di nuovo qualcosa C-k
che non funziona).
Ecco un'altra funzione per farlo. La mia versione non tocca l'anello di eliminazione e il cursore finisce sulla nuova riga in cui si trovava sull'originale. Duplicherà la regione se è attiva (modalità contrassegno transitorio) o, in caso contrario, per impostazione predefinita duplicherà la linea. Farà anche più copie se viene fornito un prefisso arg e commenta la riga originale se viene fornito un prefisso arg negativo (questo è utile per testare una versione diversa di un comando / istruzione mantenendo quella precedente).
(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)))))
L'ho legato a C-c d
:
(global-set-key [?\C-c ?d] 'duplicate-line-or-region)
Questo non dovrebbe mai essere riassegnato da una modalità o altro perché C-c
seguita da una singola lettera (non modificata) è riservata per i collegamenti dell'utente.
C-c d
ottengo l'errore command-execute: Wrong type argument: commandp, duplicate-line-or-region
. Qualche idea di che succede? Sto usando Emacs 25.1.1 su Windows
L'aggiunta di Nathan al tuo file .emacs è la strada da percorrere ma potrebbe essere leggermente semplificata sostituendola
(open-line 1)
(next-line 1)
con
(newline)
cedevole
(defun duplicate-line()
(interactive)
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
installa duplicato da melpa:
Mx pacchetto-installa RET cosa duplicata
e aggiungi questo keybinding al file init :
(duplicate-global-set-key (kbd "Mc"))
Non ricordo bene come funzioni la duplicazione delle linee da nessun'altra parte, ma come ex utente di SciTE mi è piaciuta una cosa di SciTE-way: non tocca la posizione del cursore! Quindi tutte le ricette sopra non erano abbastanza buone per me, ecco la mia versione hippie:
(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))))
Si noti che nulla viene effettivamente ucciso durante il processo, lasciando intatti i segni e la selezione corrente.
A proposito, perché siete così affezionati a muovere il cursore in giro quando c'è questa cosa simpatica e pulita di tutto il mondo (CS-backspace)?
perché non lo so, inizierò questo giro di golf con uno slowball:
ctrl-k, y, y
qualcosa che potresti voler avere nel tuo .emacs è
(setq kill-whole-line t)
Il che in pratica uccide l'intera linea più la nuova linea ogni volta che invochi la linea di uccisione (cioè via Ck). Quindi, senza codice aggiuntivo, puoi semplicemente fare Ca Ck Cy Cy per duplicare la linea. Si rompe a
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.
Ma se lo usi spesso, forse un'associazione di tasti dedicata potrebbe essere un'idea migliore, ma il vantaggio di usare solo Ca Ck Cy Cy è che puoi duplicare la linea altrove, anziché appena sotto la linea corrente.
Mi sono copy-from-above-command
legato a una chiave e la uso. È fornito con XEmacs, ma non conosco GNU Emacs.
`copy-from-above-command 'è una funzione Lisp compilata interattiva
- caricata da" /usr/share/xemacs/21.4.15/lisp/misc.elc "(copia-da-above-command e ARG opzionale)Documentazione: copia i caratteri dalla precedente riga non vuota , iniziando appena sopra il punto. Copia i caratteri ARG, ma non oltre la fine di quella riga. Se non viene fornito alcun argomento, copiare l'intero resto della riga. I caratteri copiati vengono inseriti nel buffer prima del punto.
GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped]
.
C'è un pacchetto chiamato Avy Ha il comando avy-copy-line. Quando si utilizza quel comando, ogni riga nella finestra ottiene una combinazione di lettere. Quindi devi solo digitare la combinazione e ottieni quella riga. Questo funziona anche per la regione. Quindi devi solo digitare due combinazioni.
Qui puoi vedere l'interfaccia:
Le impostazioni predefinite sono orribili per questo. Tuttavia, puoi estendere Emacs in modo che funzioni come SlickEdit e TextMate, ovvero copiare / tagliare la riga corrente quando non è selezionato alcun testo:
(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)))))
Inserire quanto sopra in .emacs
. Quindi, per copiare una riga M-w
,. Per eliminare una riga C-w
,. Per duplicare una linea, C-a M-w C-y C-y C-y ...
.
'Ho scritto la mia versione di duplicate-line
, perché non voglio rovinare l'anello mortale.
(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)
Mi è piaciuta la versione di FraGGod, tranne due cose: (1) Non controlla se il buffer è già di sola lettura (interactive "*")
e (2) non riesce sull'ultima riga del buffer se quest'ultima è vuota (come te non può uccidere la linea in quel caso), lasciando il buffer di sola lettura.
Ho apportato le seguenti modifiche per risolverlo:
(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)))))
Con emacs recenti, puoi usare Mw in qualsiasi punto della riga per copiarlo. Quindi diventa:
M-w C-a RET C-y
M-w
è vincolato a easy-kill
. Verifica che è quello che ottieni quando lo faiC-h c M-w
Ho visto soluzioni molto complesse, comunque ...
(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, (posizione in una nuova posizione) ctrl-y
Aggiungi un ctrl-a se non stai iniziando all'inizio della riga. E il secondo ctrl- kè quello di afferrare il personaggio newline. Può essere rimosso se si desidera solo il testo.
Quando viene chiamato in modo interattivo senza alcuna regione attiva, COPIA (Mw) invece una singola riga:
(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)))))
Se chiamato in modo interattivo senza alcuna regione attiva, KILL (Cw) invece di una singola riga.
(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)))))
Inoltre, su una nota correlata:
(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)
Ne scrivo uno per le mie preferenze.
(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)
Ma ho scoperto che ciò avrebbe qualche problema quando la riga corrente contiene caratteri multi-byte (ad es. Caratteri CJK). Se riscontri questo problema, prova invece:
(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)
Questa funzionalità dovrebbe corrispondere all'implementazione di JetBrains in termini di duplicazione sia per linea o regione, e quindi lasciare il punto e / o la regione attiva come previsto:
Solo un wrapper per il modulo interattivo:
(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)))
Il che chiama questo,
(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))
O questo
(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))
E poi ho questo legato a meta + maiusc + d
(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
Come menzionato in altre risposte, associare i tasti premuti al codice lisp è un'idea migliore che legarli a un altro tasto. Con la risposta di @ mw, il codice duplica la linea e sposta il segno alla fine della nuova linea. Questa modifica mantiene la posizione del segno nella stessa colonna sulla nuova riga:
fun duplicate-line ()
(interactive)
(let ((col (current-column)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
(move-to-column col)))
Se stai usando Spacemacs, puoi semplicemente usare duplicate-line-or-region
, associato a:
SPC x l d
Con argomenti prefisso e cos'è (spero) un comportamento intuitivo:
(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))))))
Il cursore rimarrà sull'ultima riga. In alternativa, potresti voler specificare un prefisso per duplicare le prossime righe contemporaneamente:
(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))
Mi trovo a usarli entrambi spesso, usando una funzione wrapper per cambiare il comportamento dell'argomento prefisso.
E un keybinding:
(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.
aggiungi l'elis sopra a te init.el e ora ottieni la funzione taglia / copia intera linea, quindi puoi F3 F4 per duplicare una linea.
Il modo più semplice è il metodo di Chris Conway.
C-a C-SPACE C-n M-w C-y
Questo è il modo predefinito richiesto da EMACS. Secondo me, è meglio usare lo standard. Sono sempre attento alla personalizzazione del proprio key binding in EMACS. EMACS è già abbastanza potente, penso che dovremmo fare del nostro meglio per adattarci ai suoi legami chiave.
Anche se è un po 'lungo, ma quando ci sei abituato, puoi fare velocemente e scoprirai che è divertente!
Ecco una funzione per duplicare la riga corrente. Con argomenti prefisso, duplicherà la riga più volte. Ad esempio, C-3 C-S-o
duplicherà la riga corrente tre volte. Non cambia l'anello di uccisione.
(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)