Equivalente Emacs ao yy10p do Vim?
Pergunta
Como posso copiar uma linha 10 vezes facilmente no Emacs?Não consigo encontrar um atalho ou função de linha de cópia.Posso usar C-aC-spcC-eM-w para copiar laboriosamente a linha, mas como posso colá-la mais de uma vez?
Alguma ideia antes de escrever minhas próprias funções.
Solução
Copiando:
Se você trabalha frequentemente com linhas, você pode querer fazer cópias (kill-ring-save
) e corte (kill-region
) funcionam nas linhas quando nenhuma região está selecionada:
(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)))))
Então você pode copiar a linha apenas com Mw.
Colando:
Freqüentemente, um argumento de prefixo apenas executa uma ação várias vezes, então você esperaria que C-u 10 C-y funcionasse, mas neste caso C-y usa seu argumento para significar qual elemento do anel de morte "arrancar" (colar).A única solução que consigo pensar é o que Kronoz diz:grave uma macro com C-x ( C-y C-x ) e então deixe o argumento de C-u ir para kmacro-end-and-call-macro
em vez disso (isso é C-u 9 C-x e ou mesmo apenas C-9 C-x e ou M-9 C-x e).
Outra maneira:Você também pode simplesmente ficar em M-x viper-mode
e use yy10p :)
Outras dicas
você pode usar uma macro de teclado para isso: -
C-a C-k C-x ( C-y C-j C-x ) C-u 9 C-x e
Explicação:-
- C-a:Ir para o início da linha
- Ck:Linha de matar
- C-x ( :Comece a gravar a macro do teclado
- C-y:Linha morta de Yank
- Cj:Mover para a próxima linha
- Cx):Pare de gravar a macro do teclado
- Cu 9:Repita 9 vezes
- C-x e :Executar macro do teclado
Você pode saber disso, mas por muitos comanda um prefixo "C-u 10" resolverá o problema.Infelizmente para o comando C-y yank, "C-u" é redefinido para significar "voltar tantos itens no anel de morte e arrancar aquele item".
Achei que você poderia usar os comandos copiar para registrar e inserir registrar com o comando prefixo C-u, mas aparentemente isso também não funciona.
Além disso, Cx z, "repetir o último comando" parece ser imune a C-u.
Outro pensamento seria usar M-:para obter um prompt Eval e digite um pouco de elisp.Eu pensei que algo como (dotimes '10 'yank) poderia funcionar, mas não parece.
Portanto, parece que usar C-u em uma macro pode realmente ser o melhor que você pode fazer, exceto escrever sua própria pequena função.
Se eu votasse, votaria na resposta do kronoz.
Você não precisa de C-x ) e C-x e neste exemplo.
Você pode simplesmente fornecer o argumento de repetição diretamente para C-x ).Isso interrompe a gravação e repete a macro em uma única etapa.Ou você pode pular C-x ) e ir direto para C-x e, já que C-x e encerrará a gravação antes de fazer as repetições.
A maneira de escolher depende de como você deseja que a contagem de repetições funcione.Para C-x ) você diz quantas repetições deseja no total (ou seja, 10 neste caso).Para C-x e você precisa dizer quantas repetições faltam (ou seja,9).
C-a C-k C-k também eliminará a nova linha final, para que você não precise colocá-la de volta mais tarde.É mais rápido do que usar a marca e não precisa alterar nenhuma variável.
Melhor ainda (a menos que você esteja em um terminal), você pode usar C-S-Backspace* para eliminar a linha inteira, independentemente de onde você esteja nela.
[* Se você estiver usando X windows, certifique-se de digitar shift (não alt) ou você pode encerrar sua sessão!]
Falando em terminais, M-9 é uma boa alternativa se você achar que não consegue digitar C-9.
No Emacs 22 e superior, por padrão, F3 inicia uma macro e F4 termina/repete uma macro.Basta pressionar F3 para iniciar a gravação, pressionar F4 quando terminar e pressionar F4 novamente para repetir a macro.(F4 também aceita um argumento.)
Juntando tudo isso, para obter 10 cópias da linha atual:
- CS-Backspace:mate essa linha
- F3:iniciar macro
- C-y:arrancar a linha
- C-1 C-0 F4 :faça isso com 10 puxões
Não tão curto quanto às 10h, mas bem próximo.:)
Aqui está uma função que tirei de uma porta OS/2 do Emacs.(Sim, uso o Emacs há algum tempo.)
;; 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))))
Eu tenho isso vinculado a F9 d:
(global-set-key [f9 ?d] 'emx-dup-line)
Então eu usaria C-u 10 F9 d para duplicar uma linha 10 vezes.
A única maneira que conheço de repetir comandos arbitrários é usar o recurso "repetir por argumento" das macros do teclado.
C-a C-espaço para baixo M-w C-x ( C-y C-x ) C-9 C-x e
- C-a:Ir para o início da linha
- Espaço C:Definir marca
- abaixo :Vá para o início da linha seguinte
- M-w:Copiar região
- C-x ( :Iniciar macro do teclado
- C-y:Linha copiada
- Cx):Finalizar macro do teclado
- C-9 C-x e :Execute a macro do teclado nove vezes.
Isso é meio fraco comparado ao vim.Mas só porque o vim é incrivelmente eficiente nesse tipo de coisa.
Se você realmente deseja uma interação modal semelhante ao vi, você pode usar um dos modos de emulação do vi, como o modo viper.Verifique na seção "Emulação" do manual online do emacs.
Você vai querer matar a linha:C-a C-k e depois C-y ou?
Não conheço um equivalente direto (C-y 10 vezes é o melhor que conheço), mas você pode estar interessado no Viper, que é um pacote de emulação vi para emacs.Faz parte da distribuição padrão do emacs.
Com base na resposta de Baxissimo, desativei isso:
(defun yank-n-times (arg)
"yank prefix-arg number of times. Not safe in any way."
(interactive "*p")
(dotimes 'arg (yank)))
Defina isso para alguma chave, chame-o com um argumento de prefixo e pronto.
editar (também modificou a chamada interativa acima para ser menos ruim)
Ou aqui está uma versão que pode substituir o 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."))))
a mensagem é meio mentirosa, mas você não deve chamá-la sem um prefixo maior que 1, então.
Não tenho certeza se é uma boa ideia, mas substituí My-y por isso, vou ver no que dá.
Você poderia arrancar uma linha (ou região) dez vezes com menos pressionamentos de tecla:
- marcar uma linha (ou região)
- puxe o texto selecionado 10 vezes:
C-w C-x ( C-y C-1 C-0 C-x )
Alternativamente, use as teclas de função F3 e F4 para iniciar e finalizar a macro do teclado:
C-w F3 C-y C-1 C-0 F4
Você obtém a linha com C-k, faz o próximo comando acontecer dez vezes com C-u 10 e depois cola a linha com C-y.Bem simples.
Se você sempre quiser que C-k faça a linha inteira, você pode definir kill-whole-line como t.Chega de mexer com C-a ou C-e.
Há muito que você pode fazer com anéis, registros e macros sofisticados, e eu encorajo você a aprendê-los, mas puxar uma linha dez vezes não precisa ser difícil ou estranho.