Eu vi essa mesma pergunta para o VIM e foi algo que eu mesmo queria saber como fazer para o Emacs. No ReSharper, uso CTRL-D para esta ação. Qual é o menor número de comandos para executar isso no Emacs?
Eu vi essa mesma pergunta para o VIM e foi algo que eu mesmo queria saber como fazer para o Emacs. No ReSharper, uso CTRL-D para esta ação. Qual é o menor número de comandos para executar isso no Emacs?
Respostas:
eu uso
C-a C-SPACE C-n M-w C-y
que se divide em
C-a
: move o cursor para o início da linhaC-SPACE
: inicia uma seleção ("set mark")C-n
: move o cursor para a próxima linhaM-w
: copiar regiãoC-y
: colar ("puxar")O mencionado acima
C-a C-k C-k C-y C-y
equivale à mesma coisa (TMTOWTDI)
C-a
: move o cursor para o início da linhaC-k
: cortar ("matar") a linhaC-k
: cortar a nova linhaC-y
: paste ("yank") (estamos de volta à estaca zero)C-y
: cole novamente (agora temos duas cópias da linha)Ambos são embaraçosamente detalhados em comparação com o C-d
seu editor, mas no Emacs sempre há uma personalização. C-d
está vinculado delete-char
por padrão, e daí C-c C-d
? Basta adicionar o seguinte ao seu .emacs
:
(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")
(A versão elisp de Nathan é provavelmente preferível, porque não será interrompida se alguma das combinações de teclas for alterada.)
Cuidado: alguns modos do Emacs podem se recuperar C-c C-d
para fazer outra coisa.
C-S-backspace C-y C-y
?
Além das respostas anteriores, você também pode definir sua própria função para duplicar uma linha. Por exemplo, colocar o seguinte no seu arquivo .emacs fará com que o Cd duplique a linha atual.
(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
dessa função?
Del
voltar ao normal, mantendo o novo C-d
: (global-set-key (kbd "<delete>") 'delete-char)
precisa ser adicionado após a C-d
definição.
Coloque o cursor na linha, se não estiver no início, faça um CTRL- A, então:
CTRL-K
CTRL-K
CTRL-Y
CTRL-Y
Minha versão de uma função para duplicar uma linha que funciona bem com desfazer e não mexe com a posição do cursor. Foi o resultado de uma discussão no gnu.emacs.sources de novembro de 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))
Então você pode definir CTRL-D para chamar esta função:
(global-set-key (kbd "C-d") 'duplicate-line)
crux-duplicate-current-line-or-region
funciona melhor para mim, porque com sua função ele desfaz a duplicação de linha e a última operação também.
Em vez de kill-line
( C-k
) como em C-a
C-k
C-k
C-y
C-y
uso, o kill-whole-line
comando:
C-S-Backspace
C-y
C-y
As vantagens C-k
incluem que não importa onde o ponto está na linha (ao contrário do C-k
que exige estar no início da linha) e também mata a nova linha (novamente algo C-k
não serve).
Aqui está outra função para fazer isso. Minha versão não toca no anel final e o cursor termina na nova linha em que estava no original. Ele duplicará a região se estiver ativo (modo de marca transitória) ou o padrão será duplicar a linha. Ele também fará várias cópias se receber um prefixo arg e comentar a linha original se receber um prefixo negativo arg (isso é útil para testar uma versão diferente de um comando / instrução, mantendo a antiga).
(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)))))
Eu tenho que vincular a C-c d
:
(global-set-key [?\C-c ?d] 'duplicate-line-or-region)
Isso nunca deve ser reatribuído por um modo ou qualquer coisa, porque C-c
seguido por uma única letra (não modificada) é reservada para ligações do usuário.
C-c d
, recebo o erro command-execute: Wrong type argument: commandp, duplicate-line-or-region
. Alguma idéia do que se passa? Estou usando o Emacs 25.1.1 no Windows
A adição de Nathan ao seu arquivo .emacs é o caminho a seguir, mas poderia ser um pouco simplificada substituindo
(open-line 1)
(next-line 1)
com
(newline)
produzindo
(defun duplicate-line()
(interactive)
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
instale coisa duplicada do melpa:
Mx pacote-instalar RET duplicado-coisa
e adicione esta combinação de teclas ao arquivo init :
(coisa duplicada da chave de conjunto global (kbd "Mc")))
Não me lembro bem como a duplicação de linhas funciona em qualquer outro lugar, mas como um ex-usuário do SciTE, gostei de algo no SciTE-way: ele não toca na posição do cursor! Portanto, todas as receitas acima não eram boas o suficiente para mim, aqui está a minha versão 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))))
Observe que nada é realmente eliminado no processo, deixando marcas e a seleção atual intacta.
BTW, por que vocês gostam tanto de puxar o cursor quando existe esse negócio legal de matar toda a linha (CS-backspace)?
porque eu não sei, vou começar essa partida com uma bola lenta:
ctrl-k, y, y
algo que você pode querer ter no seu .emacs é
(setq kill-whole-line t)
O que basicamente mata a linha inteira mais a nova linha sempre que você chama a linha de interrupção (ou seja, via Ck). Então, sem código extra, você pode simplesmente fazer Ca Ck Cy Cy para duplicar a linha. Quebra para
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.
Mas se você usar isso com frequência, talvez uma ligação de tecla dedicada possa ser uma idéia melhor, mas a vantagem de usar apenas o Ca Ck Cy Cy é que você pode duplicar a linha em outro lugar, em vez de logo abaixo da linha atual.
Eu copy-from-above-command
vinculei a uma chave e use isso. É fornecido com o XEmacs, mas eu não sei sobre o GNU Emacs.
`copy-from-above-command 'é uma função interativa do Lisp compilada
- carregada em" /usr/share/xemacs/21.4.15/lisp/misc.elc "(cópia do comando acima e ARG opcional)Documentação: Copie caracteres da linha anterior não vazia , começando logo acima do ponto. Copie caracteres ARG, mas não depois do final dessa linha. Se nenhum argumento for fornecido, copie o restante da linha. Os caracteres copiados são inseridos no buffer antes do ponto.
GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped]
.
Existe um pacote chamado Avy. Ele possui o comando avy-copy-line. Quando você usa esse comando, todas as linhas da sua janela obtêm uma combinação de letras. Então você só precisa digitar a combinação e obter essa linha. Isso também funciona para a região. Então você só precisa digitar duas combinações.
Aqui você pode ver a interface:
Os padrões são horríveis para isso. No entanto, você pode estender o Emacs para funcionar como SlickEdit e TextMate, ou seja, copiar / cortar a linha atual quando nenhum texto for selecionado:
(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)))))
Coloque o item acima em .emacs
. Então, para copiar uma linha M-w
,. Para excluir uma linha C-w
,. Para duplicar uma linha C-a M-w C-y C-y C-y ...
,.
- Eu escrevi minha própria versão duplicate-line
, porque não quero estragar o anel da morte.
(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)
Gostei da versão do FraGGod, exceto por duas coisas: (1) Ele não verifica se o buffer já está somente leitura (interactive "*")
e (2) falha na última linha do buffer se essa última linha estiver vazia (como você não pode eliminar a linha nesse caso), deixando seu buffer somente leitura.
Fiz as seguintes alterações para resolver isso:
(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)))))
Com o emacs recente, você pode usar Mw em qualquer lugar da linha para copiá-lo. Então se torna:
M-w C-a RET C-y
M-w
está vinculado a easy-kill
. Verifique se é o que você começa quando você fazC-h c M-w
Eu vi soluções muito complexas, de qualquer maneira ...
(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, (posição para o novo local) ctrl-y
Adicione a ctrl- ase você não estiver começando no início da linha. E o segundo ctrl- ké pegar o personagem nova linha. Pode ser removido se você quiser apenas o texto.
Quando chamado interativamente sem região ativa, COPY (Mw) uma única linha:
(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)))))
Quando chamado interativamente sem região ativa, KILL (Cw) uma única linha.
(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)))))
Além disso, em uma nota relacionada:
(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)
Eu escrevo um para minha preferência.
(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)
Mas eu achei que isso teria algum problema quando a linha atual contiver caracteres de vários bytes (por exemplo, caracteres CJK). Se você encontrar esse problema, tente o seguinte:
(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)
Essa funcionalidade deve corresponder à implementação do JetBrains em termos de duplicação por linha ou região e, em seguida, deixar o ponto e / ou região ativa conforme o esperado:
Apenas um wrapper para o formulário interativo:
(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)))
O que chama isso,
(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))
Ou isto
(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 então eu tenho isso vinculado a meta + shift + d
(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
Como mencionado em outras respostas, vincular pressionamentos de tecla ao código lisp é uma idéia melhor do que vinculá-los a outros pressionamentos de tecla. Com a resposta de @ mw, o código duplica a linha e move a marca para o final da nova linha. Essa modificação mantém a posição da marca na mesma coluna na nova linha:
fun duplicate-line ()
(interactive)
(let ((col (current-column)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
(move-to-column col)))
Se você estiver usando o Spacemacs, pode simplesmente usar duplicate-line-or-region
, vinculado a:
SPC x l d
Com argumentos de prefixo e qual é (espero) 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))))))
O cursor permanecerá na última linha. Como alternativa, convém especificar um prefixo para duplicar as próximas linhas ao mesmo tempo:
(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))
Encontro-me usando os dois com freqüência, usando uma função de invólucro para mudar o comportamento do argumento do prefixo.
E uma combinação de teclas:
(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.
adicione o elisp acima a você init.el, e você terá a função de cortar / copiar toda a linha agora, então você pode F3 F4 para duplicar uma linha.
A maneira mais simples é o método de Chris Conway.
C-a C-SPACE C-n M-w C-y
Essa é a maneira padrão exigida pelo EMACS. Na minha opinião, é melhor usar o padrão. Sempre sou cuidadoso com a personalização das próprias vinculações de chaves no EMACS. O EMACS já é poderoso o suficiente, acho que devemos tentar o nosso melhor para nos adaptar às suas próprias combinações de teclas.
Embora seja um pouco demorado, mas quando você está acostumado, você pode fazer rápido e achar isso divertido!
Aqui está uma função para duplicar a linha atual. Com argumentos de prefixo, duplicará a linha várias vezes. Por exemplo, C-3 C-S-o
duplicará a linha atual três vezes. Não muda o anel da morte.
(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)