Fundamentos de cursores múltiplos

55

Eu aprendi recentemente multiple-cursorse parece um pacote muito útil. Examinei a documentação do repositório original , mas os comandos ainda me parecem um pouco obscuros.

Eu assisti o vídeo no Emacs Rocks !, e o vídeo é ótimo, mas ele se concentra principalmente no que multiple-cursorsé capaz de fazer, e não em como fazê-lo.

Existem orientações, tutoriais ou exemplos que ilustram sua funcionalidade mais básica?

Amelio Vazquez-Reina
fonte
4
Consegui começar a trabalhar multiple-cursorsrapidamente, apenas lendo o arquivo README. Minha recomendação é apenas aprender mc/mark-next-like-this. Experimente e familiarize-se com o que faz. A partir daí, consulte o README sempre que houver uma pergunta que comece com "Gostaria de saber se vários cursores podem fazer ..." Tudo isso dito, acho que é uma introdução mais básica do que o Emacs Rocks! o vídeo seria útil para iniciantes.
Nispio 7/10
Concordo plenamente! Absolutamente claro como usá-lo. Eu apenas mascarar linhas, em seguida, fazer mc / editar linhas com KBD binded (não através Mx como observado no Github) Então eu vejo vários cursores mas eles simplesmente desaparece depois de qualquer entrada de texto
Dima Fomin

Respostas:

19

Além dos usos que o @bastibe descreve, eu uso vários cursores para adicionar ou remover texto do início / fim de um grupo de linhas:

  1. Mover ponto para o início ou fim da área de interesse
  2. chamada set-rectangular-region-anchor(ligada a qualquer tecla que você quiser, acho que a sugestão do Magnars foi H-space, se você tiver uma hiper-chave)
  3. Movido para a frente ou para trás pela linha ( C-ne C-p) até que você tenha um cursor em cada linha que deseja editar
  4. Insira ou exclua o texto conforme necessário, movendo-se opcionalmente para o final da linha ( C-e) para fazer alterações.

Você pode usar forward-word, forward sentenceetc, para frente e para trás ao longo das linhas, o que permite que você edite a quarta palavra em cada linha, mesmo se o texto em cada linha não é idêntico.

Como exemplo, eu faço esse tipo de trabalho o tempo todo:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Isso insere o conteúdo do diretório pp5 no buffer. Coloco ponto !no início da listagem:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Adicione cursores a cada linha com H-space, C-nx 4
  • duplicar cada linha com C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • corte a primeira seção em nomes de variáveis ​​com M-dx 3 C-d C-fx3 M-dx3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Depois, envolva o nome do arquivo real na função para carregá-lo: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

E pronto, você converteu uma lista de arquivos no código para ler essa lista. Na verdade, é muito mais difícil descrever do que realmente fazer!

Tyler
fonte
3
Se você fizer o mesmo com frequência, poderá envolvê-lo em uma macro do teclado. Macros de teclado e multiple-cursorspodem fazer uma combinação realmente poderosa.
Nispio 7/10
@nispio concordou! Às vezes, estou repetindo o mesmo processo e uma macro seria útil. Muitas vezes, porém, existem pequenas diferenças no meio do fluxo de trabalho que exigem pequenas alterações que "quebrariam" uma macro.
Tyler
11
Muitas vezes, você pode descrever com precisão o local em que deseja que o cursor pule para usar uma regexp. Nesses casos, utilizando phi-searchpode ser mais robusto do que navegar com comandos comoM-f (x3)
nispio
@nispio claro, depende da situação. Com nomes estruturados de maneira consistente, é fácil mover por palavra. Eu não tinha usado a pesquisa em vários cursores, pois os comandos de pesquisa do emacs são frágeis com o mc. Eu não sabia phi-search, isso parece ótimo!
Tyler
22

Basicamente, tenho dois casos de uso frequentes para multiple-cursors:

  • Substitua alguma corda. Marque uma instância de uma sequência e use mc/mark-next-like-thise mc/mark-previous-like-thispara marcar mais instâncias. Em seguida, pressionei imediatamente C-wpara excluir todas as instâncias e, em vez disso, escrevi uma nova string. Eu uso isso frequentemente para renomear uma variável no código.
  • Edite vários lugares simultaneamente. Marque várias instâncias de uma sequência como antes, mas cancele a seleção (mas não os cursores) imediatamente usando C-g, ou coloque marca e ponto na mesma coluna de linhas diferentes e use mc/edit-linespara obter um cursor por linha. Agora você pode usar comandos de edição regulares que operam em cada um desses cursores.

O primeiro caso de uso é particularmente útil com expand-region. Eu er/expand-regionliguei para C-j, e mc/mark-next-like-thise mc/mark-previous-like-thispara C->e C-<. Com isso, posso selecionar facilmente a palavra em que o ponto está ativado e marcar a ocorrência seguinte / anterior dessa palavra instantaneamente.

O segundo caso de uso substituiu a maioria dos usos de macros para mim. Em vez de gravar uma macro e, em seguida, aplicá-la em vários lugares, eu colocaria um cursor em todos os lugares e faria a operação em todos os lugares ao mesmo tempo.

bastibe
fonte
Obrigado @bastibe. Alguma ligação específica que você multiple-cursors recomenda ou, por exemplo, mark-next-like-this& mark-previous-like-this?
Amelio Vazquez-Reina
@ user815423426 conforme descrito na postagem, eu uso C->e C-<para mark-next-like-thise mark-previous-like-this.
bastibe
por que não usar o padrão M-% para pesquisar e substituir ?
Dima Fomin
6

Eu gostaria de adicionar alguns extras que às vezes uso multiple-cursors.

Eu achei o seguinte útil:

iy-go-to-char

Às vezes, você precisa mudar para o próximo #ou o próximo ,ou algum delimitador específico. Isso é especialmente útil quando você precisa mover diferentes números de palavras para cada cursor. Ele fornece as funções iy-go-to-chare iy-go-to-char-backward, as quais você pode vincular e usar de maneira adequada.

região de expansão

Isso é realmente útil por uma razão semelhante a iy- quando você tem linhas ligeiramente diferentes sob cada cursor e talvez queira selecionar a sequência de caracteres citada sob o ponto ou similar.

coisas personalizadas

Essas são coisas que acabam de aparecer na minha configuração, mas acho útil. Provavelmente não foi escrito por mim.

Solicitação de entrada
Eu recebi este da Magnars em resposta a uma solicitação para colocar uma string diferente sob cada cursor. O código é simples, mas vinculá-lo a algo e usá-lo em vários cursores é uma maneira prática de inserir itens ligeiramente diferentes em cada local.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Número de incremento no ponto
Isso veio do SO ou do emacswiki. Não tenho certeza qual. É bastante útil por si só e também quando usado em combinação commc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-replace
Isso é super poderoso e permite alguns bits 'n' pedaços realmente úteis. Ele avalia o sexp que está por trás do cursor e insere o resultado da avaliação.
Combine-o com, multiple-cursors-numberspor exemplo, para inserir potências de dois ou uma série que 0 1 2 0 1 2 0 1 2atravesse cada linha ou algo assim. (Eu fiz as duas coisas de maneira útil). Ou use-a s.elpara escrever essas configurações tediosas de java com itens padrão. Você escreve cada um CONFIG_VALUE_VARIABLEe depois transforma isso em CONFIG_VALUE_VARIABLE = "configValueVariable"execução s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))
Squidly
fonte
iy-go-to-char é super útil. É mesmo o que eu procurava.
Heinrich Hartmann
1
  1. Vá para o final * do que você deseja selecionar.
  2. Pressione C-S-bou M-S-bpara selecionar para trás até obter uma parte selecionada. Você também pode usar a tecla Shift esquerda.
  3. Em seguida, pressione C->(pressione Shift se a tecla >estiver em cima da tecla do teclado) até obter mais de um item selecionado.

* É importante selecionar para trás ou a primeira seleção colocará o cursor na posição errada.

morishi
fonte