Como posso executar uma macro de teclado em buffers selecionados do Ibuffer ou em arquivos selecionados do dired?

8

Se eu precisar refatorar o nome de uma variável, utilizarei cursores ag e múltiplos .

Mas quando tenho que fazer alguma remoção / adição / movimentação de blocos de código, uso macros do teclado. Mas preciso mudar para cada buffer e iniciar a macro manualmente.

Existe uma maneira de simplesmente selecionar os buffers abertos do Ibuffer (ou arquivos de dired) e executar a última macro de teclado gravada em todos eles?

Kaushal Modi
fonte

Respostas:

8

Modifique os buffers selecionados do Ibuffer

Depois de gravar a macro do teclado, mude para Ibuffer e,

  • Marque os buffers desejados usando m
  • Acerto W- Avaliação durante a visualização do buffer (a avaliação simples ENÃO funciona para chamadas de macro)
  • (kmacro-end-or-call-macro 1)
Kaushal Modi
fonte
3

Você simplesmente inclui a troca de buffer na macro. Você não está restrito a um único buffer - uma macro de teclado pode fazer qualquer coisa!

Eu respondi praticamente a mesma pergunta no outro dia no SO, portanto, consulte a macro do teclado entre arquivos do emacs .

phils
fonte
Eu quero executar a macro apenas em alguns buffers selecionados de todos os buffers abertos.
precisa
Marque os arquivos nos quais deseja executá-lo e filtre a listagem apenas para esses arquivos. No dired e no ibuffer, você pode usar tpara alternar as marcas e kremover as entradas marcadas. Uma gatualização subsequente restaurará as linhas removidas.
Phs #
1
Eu posso simplesmente usar M-{e M-}pular para os itens marcados seguintes e anteriores no Ibuffer e direcionado.
precisa
Ah, melhor ainda!
Phs #
1

Aqui está um comando que torna a execução de comandos, macros e a avaliação de expressões Lisp em vários arquivos um acéfalo. Observe que o argumento prefix permite executar uma macro para cada arquivo até que ocorra um erro. Já postei isso no superusuário, mas funciona tão bem que achei que as pessoas que acessavam esta página também poderiam achar útil. Eu gosto de vincular isso a 'E' em dired.

Atualização: a versão antiga desta função suportava apenas macros. O atualizado é mais simples e mais poderoso, permitindo executar comandos arbitrários (por sequência ou nome de chave), bem como expressões Lisp. Agora também é cuidadoso registrar quaisquer erros no buffer de Mensagens .

;; Inspired by M-x edit-kbd-macro and https://superuser.com/q/176627.
(defun my-dired-do-execute (keys &optional arg)
  "Execute a command in all marked files.
If an error occurs, execution in other files is not affected.
(Notably, this allows to run keyboard macros until there is an error.)

At the prompt, type any bound key sequence, or `\\[execute-extended-command]'
to choose a command by its name, or `\\[eval-expression]' to enter a Lisp expression.

The prefix ARG, if given, is passed on to the chosen command.
"
  (interactive
   (list (read-key-sequence (substitute-command-keys "Key sequence to execute, \
or \\[eval-expression], or \\[execute-extended-command]: "))
         current-prefix-arg))
  (when keys
    (let ((cmd (if (arrayp keys) (key-binding keys) keys))
          exp)
      (cond ((eq cmd 'execute-extended-command)
             (setq cmd (read-command "Name of command to execute: "))
             (if (string-equal cmd "")
                 (error "No command name given")))
            ((eq cmd 'eval-expression)
             (setq exp (read--expression "Eval in selected files: "))
             (setq cmd nil))
            ((null cmd)
             (error "Key sequence %s is not defined" (key-description keys))))
      (mapc (lambda (filename)
              (save-selected-window
                (find-file-other-window filename)
                (setq current-prefix-arg arg)
                (condition-case-unless-debug err
                    (if cmd
                        (call-interactively cmd)
                      (message "Result in file %s:" filename)
                      (eval-expression exp))
                  (error (message "In file %s: %S" filename err)))))
            (dired-get-marked-files)))))
spheniscus
fonte
0

Modificando arquivos selecionados no dired

A solução abaixo precisa da instalação do dired+pacote, que está disponível no Melpa.

  1. Primeiro, converta a macro do teclado em uma função elisp. Aqui está um emacs.SE QnA relacionado (como salvar uma macro de teclado como uma função Lisp?).

    É ainda mais rápido se você souber como deseja modificar todos os arquivos usando uma função elisp diretamente. Digamos que você queira adicionar "- * - mode: org - * -" no início de todos os arquivos selecionados em dired. 1 1

    Nesse caso, a execução da função elisp abaixo em cada um dos arquivos selecionados funcionaria.

    (defun my/set-org-mode ()
      (goto-char (point-min))
      (insert "-*- mode: org -*-\n"))
    

    Portanto, basta avaliar a função acima por enquanto; ele será usado em uma etapa posterior abaixo.

  2. Faça M-x direde abra o diretório que contém os arquivos nos quais você deseja executar a função acima.
  3. Marcar todos esses arquivos usando a mchave (obrigado a dired-marknos dired).
  4. * etapa mágica * : faça C-u @e selecione o nome da função que você avaliou na etapa 1 ( my/set-org-mode). @está vinculado ao diredp-do-apply-functionqual está definido em dired+.el.
  5. Estrondo! A linha "- * - mode: org - * -" será adicionada na parte superior de todos os arquivos marcados. Mas as coisas ainda não estão salvas. Você pode revisar o que mudou, se quiser, e pressionar C-x s !para salvar todos os arquivos modificados de uma só vez.

1 : Inspirado nesta pergunta no reddit .

Kaushal Modi
fonte