Come posso eseguire una macro di tastiera in buffer selezionati da Ibuffer o file selezionati da dired?


8

Se devo eseguire il refactoring di un nome variabile, utilizzo ag e cursori multipli .

Ma quando devo eseguire alcune operazioni di rimozione / aggiunta / spostamento del blocco di codice, utilizzo le macro della tastiera. Ma devo passare a ciascun buffer e avviare manualmente l'esecuzione di quella macro.

C'è un modo per selezionare semplicemente i buffer aperti da Ibuffer (o file da dired) ed eseguire l'ultima macro di tastiera registrata su tutti loro?

Risposte:


8

Modifica i buffer Ibuffer selezionati

Dopo aver registrato la macro della tastiera, passare a Ibuffer e,

  • Selezionare i buffer desiderati utilizzando m
  • Hit W- Eval durante la visualizzazione del buffer (il semplice eval ENON funziona per le chiamate macro)
  • (kmacro-end-or-call-macro 1)

3

È sufficiente includere la commutazione del buffer nella macro. Non sei limitato a un singolo buffer: una macro della tastiera può fare tutto ciò che puoi fare!

Ho risposto praticamente a questa stessa domanda l'altro giorno su SO, quindi fai riferimento alla macro della tastiera tra i file di emacs .


Voglio eseguire la macro solo in pochi buffer selezionati di tutti i buffer aperti.
Kaushal Modi,

Quindi contrassegnare i file su cui si desidera eseguirlo e filtrare l'elenco solo per quei file. In dired e ibuffer è possibile utilizzare tper attivare / disattivare i segni e krimuovere le voci contrassegnate. Un successivo gaggiornamento ripristinerà le linee rimosse.
phils,

1
Posso semplicemente usare M-{e M-}saltare agli elementi contrassegnati successivo e precedente in Ibuffer e diretto.
Kaushal Modi,

Ah, ancora meglio!
phils,

1

Ecco un comando che rende l'esecuzione di comandi, macro e la valutazione di espressioni Lisp in più file un gioco da ragazzi. Si noti che l'argomento prefisso consente di eseguire una macro per ciascun file fino a quando si verifica un errore. L'ho già pubblicato su superuser, ma funziona così bene che ho pensato che anche le persone che arrivano su questa pagina potrebbero trovarlo utile. Mi piace associare questo a 'E' in dired.

Aggiornamento: la vecchia versione di questa funzione supportava solo macro. Quello aggiornato è sia più semplice che più potente, consentendo di eseguire comandi arbitrari (per sequenza di tasti o nome) e espressioni Lisp. Ora è anche attento a registrare eventuali errori nel buffer Messaggi .

;; 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)))))

0

Modifica dei file selezionati in dired

La soluzione seguente richiede l'installazione del dired+pacchetto, disponibile su Melpa.

  1. Prima di tutto, converti la macro della tastiera in una funzione elisp. Ecco un emacs.SE QnA correlato (Come salvare una macro di tastiera come funzione Lisp?).

    È ancora più veloce se sai come modificare tutti i file usando direttamente una funzione elisp. Diciamo che si desidera aggiungere "- * - mode: org - * -" all'inizio di tutti i file selezionati in dired. 1

    In tal caso, l'esecuzione della funzione elisp di seguito in ciascuno dei file selezionati funzionerebbe.

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

    Quindi, per ora basta valutare la funzione sopra; verrà utilizzato in un passaggio successivo di seguito.

  2. Fare M-x direde aprire la directory contenente i file in cui si desidera eseguire la funzione sopra.
  3. Contrassegnare tutti questi file con il mtasto (associato a dired-markin dired).
  4. * passaggio magico * : eseguire C-u @e selezionare il nome della funzione valutata nel passaggio 1 ( my/set-org-mode). @è legato al diredp-do-apply-functionquale è definito in dired+.el.
  5. Boom! La riga "- * - mode: org - * -" verrà aggiunta nella parte superiore di tutti i file contrassegnati. Ma le cose non sono ancora salvate. Puoi rivedere tutto ciò che è cambiato se lo desideri e poi premere C-x s !per salvare tutti i file modificati in una volta sola.

1 : ispirato da questa domanda su reddit .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.