Equivalente Emacs di yy10p di Vim?
Domanda
Come posso copiare facilmente una riga 10 volte in Emacs?Non riesco a trovare una scorciatoia o una funzione per la riga di copia.Posso usare C-aC-spcC-eM-w per copiare faticosamente la riga, ma come posso incollarla più di una volta?
Qualche idea prima di andare a scrivere le mie funzioni.
Soluzione
Copiare:
Se lavori spesso con le linee, potresti voler creare una copia (kill-ring-save
) e tagliare (kill-region
) funzionano sulle linee quando non è selezionata alcuna regione:
(defadvice kill-ring-save (before slickcopy activate compile)
"When called interactively with no active region, copy a single line instead."
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))
(defadvice kill-region (before slickcut 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)))))
Quindi puoi copiare la riga solo con M-w.
Incollare:
Spesso un argomento prefisso esegue semplicemente un'azione più volte, quindi ti aspetteresti che C-u 10 C-y funzioni, ma in questo caso C-y usa il suo argomento per indicare quale elemento del kill-ring "strappare" (incollare).L'unica soluzione che mi viene in mente è ciò che dice Kronoz:registra una macro con C-x ( C-y C-x ) e poi lascia andare l'argomento di C-u kmacro-end-and-call-macro
invece (che è C-u 9 C-x e o anche solo C-9 C-x e o M-9 C-x e).
Un altro modo:Puoi anche semplicemente restare dentro M-x viper-mode
e usa yy10p :)
Altri suggerimenti
puoi usare una macro da tastiera per questo: -
C-a C-k C-x ( C-y C-j C-x ) C-u 9 C-x e
Spiegazione:-
- Circa :Vai all'inizio della riga
- Ck:Linea di uccisione
- Cx (:Inizia a registrare la macro della tastiera
- C-y:Yank ha ucciso la linea
- Cj:Passa alla riga successiva
- C-x):Interrompe la registrazione della macro della tastiera
- Cu 9:Ripeti 9 volte
- Cxe:Esegui la macro da tastiera
Potresti saperlo, ma per molti comanda un prefisso "C-u 10" farà il trucco.Sfortunatamente per il comando C-y yank, "C-u" viene ridefinito per significare "torna indietro di tanti oggetti nel kill ring e strattona quell'oggetto".
Pensavo che potresti essere in grado di utilizzare i comandi copy-to-register e insert-register con il comando prefisso C-u, ma a quanto pare non funziona neanche questo.
Anche C-x z, "ripeti l'ultimo comando" sembra essere immune a C-u.
Un altro pensiero potrebbe essere quello di utilizzare M-:per ottenere un prompt Eval e digitare un po' di elisp.Pensavo che qualcosa come (dotimes '10 'yank) potesse farlo, ma non sembra.
Quindi sembra che usare C-u su una macro possa davvero essere la cosa migliore che puoi fare a meno di scrivere la tua piccola funzione.
Se avessi un voto, voterei per la risposta di Kronoz.
Non sono necessari sia C-x ) che C-x e in questo esempio.
Puoi semplicemente dare l'argomento ripetizione direttamente a C-x ).Ciò interrompe la registrazione e ripete la macro, in un unico passaggio.Oppure puoi saltare C-x ) e andare direttamente a C-x e, poiché C-x e terminerà la registrazione prima di eseguire le ripetizioni.
Il modo da scegliere dipende da come preferisci che funzioni il conteggio delle ripetizioni.Per C-x ) dici quante ripetizioni volevi in totale (quindi 10 in questo caso).Per C-x e devi dire quante ripetizioni restano (es.9).
C-a C-k C-k ucciderà anche il ritorno a capo finale, quindi non dovrai reinserirlo tu stesso in seguito.È più veloce dell'utilizzo del segno e non richiede la modifica di alcuna variabile.
Ancora meglio (a meno che tu non sia in un terminale), puoi usare C-S-Backspace* per terminare l'intera riga, indipendentemente da dove ti trovi.
[* Se utilizzi X Windows, assicurati di digitare MAIUSC (non alt) oppure puoi terminare la sessione!]
Parlando di terminali, M-9 è una bella alternativa se scopri di non poter digitare C-9.
In Emacs 22 e versioni successive, per impostazione predefinita F3 avvia una macro e F4 termina/ripete una macro.Basta premere F3 per avviare la registrazione, premere F4 quando hai finito e premere nuovamente F4 per ripetere la macro.(F4 accetta anche un argomento.)
Mettendo tutto insieme, per ottenere 10 copie della riga attuale:
- C-S-Backspace:uccidi questa linea
- F3:avviare la macro
- C-y:strattonare la linea
- DO-1 DO-0 FA4:fai 10 Yanks
Non così breve come le 22:00, ma abbastanza vicino.:)
Ecco una funzione che ho preso da un port OS/2 di Emacs.(Sì, uso Emacs da un po'.)
;; Author: Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
(defun emx-dup-line (arg)
"Duplicate current line.
Set mark to the beginning of the new line.
With argument, do this that many times."
(interactive "*p")
(setq last-command 'identity) ; Don't append to kill ring
(let ((s (point)))
(beginning-of-line)
(let ((b (point)))
(forward-line)
(if (not (eq (preceding-char) ?\n)) (insert ?\n))
(copy-region-as-kill b (point))
(while (> arg 0)
(yank)
(setq arg (1- arg)))
(goto-char s))))
L'ho legato a F9 d:
(global-set-key [f9 ?d] 'emx-dup-line)
Quindi utilizzerei C-u 10 F9 d per duplicare una riga 10 volte.
L'unico modo che conosco per ripetere comandi arbitrari è utilizzare la funzione "ripeti per argomento" delle macro della tastiera.
C-a C-spazio giù M-w C-x ( C-y C-x ) C-9 C-x e
- Circa :Vai all'inizio della riga
- Spazio C:Imposta il segno
- giù :Vai all'inizio della riga successiva
- M-w:Copia regione
- Cx (:Avvia la macro da tastiera
- C-y:Yank ha copiato la riga
- C-x):Termina la macro della tastiera
- C-9 C-x e :Esegui la macro da tastiera nove volte.
È un po' debole rispetto a Vim.Ma solo perché vim è sorprendentemente efficiente in questo genere di cose.
Se desideri davvero un'interazione modale simile a vi, potresti utilizzare una delle modalità di emulazione vi, come la modalità viper.Controlla nella sezione "Emulazione" del manuale online di emacs.
Avrai voglia di uccidere la linea:C-a C-k, e poi C-y o ?
Non conosco un equivalente diretto (C-y 10 volte è il massimo che conosco), ma potrebbe interessarti Viper, che è un pacchetto di emulazione vi per emacs.Fa parte della distribuzione standard di emacs.
Sulla base della risposta di Baxissimo ho definito questo:
(defun yank-n-times (arg)
"yank prefix-arg number of times. Not safe in any way."
(interactive "*p")
(dotimes 'arg (yank)))
Impostalo su una chiave, chiamalo con un argomento prefisso e il gioco è fatto.
modificare (modificata anche la chiamata interattiva sopra per essere meno schifosa)
Oppure ecco una versione che può in qualche modo sostituire lo yank-pop:
(defun yank-n-times (&optional arg)
"yank prefix-arg number of times. Call yank-pop if last command was yank."
(interactive "*p")
(if (or (string= last-command "yank")
(string= last-command "yank-pop"))
(yank-pop arg)
(if (> arg 1)
(dotimes 'arg (yank))
(message "Previous arg was not a yank, and called without a prefix."))))
il messaggio è una specie di bugia, ma non dovresti comunque chiamarlo senza un prefisso maggiore di 1, quindi.
Non sono sicuro che sia una buona idea, ma ho sostituito M-y con questo, vedrò come va.
Potresti strappare una linea (o una regione) dieci volte con meno sequenze di tasti:
- contrassegnare una linea (o una regione)
- strappa il testo selezionato 10 volte:
C-w C-x ( C-y C-1 C-0 C-x )
In alternativa, utilizzare i tasti funzione F3 e F4 per iniziare e terminare la macro della tastiera:
C-w F3 C-y C-1 C-0 F4
Ottieni la riga con C-k, fai ripetere il comando successivo dieci volte con C-u 10, quindi incolli la riga con C-y.Abbastanza semplice.
Se vuoi che C-k esegua sempre l'intera riga, puoi impostare kill-whole-line su t.Non dovrai più giocherellare con C-a o C-e.
C'è molto che puoi fare con kill ring, registri e macro fantasiosi, e ti incoraggio a impararli, ma strattonare una linea dieci volte non deve essere difficile o strano.