2010-10-27 10 views
6

In emacs, a volte invoco per errore call-last-kbd-macro. In caso di annullamento mi sarei aspettato l'annullamento per annullare l'intero effetto della macro della tastiera atomicamente, ma ciò non accade. Invece mi ritrovo a dover annullare ogni passaggio di una macro alla volta. Come posso ottenere emacs per tornare allo stato del buffer prima dell'esecuzione della macro?Come annullare call-last-kbd-macro in emacs

risposta

2

Ho paura di non poterlo fare solo con il meccanismo integrato 'undo. Il sistema macro in Emacs riproduce effettivamente le cose come se l'utente stesse effettivamente digitando le sequenze di tasti (o gli eventi del mouse), e così undo history (buffer-undo-list) viene aggiornato normalmente.

Ecco un suggerimento su come estendere l'attuale meccanismo undo per fare quello che vuoi.

  1. estendere 'undo per capire una nuova voce nella lista di undo, un marcatore macro-begin e un elemento macro-end

  2. consiglio/modificare la riproduzione macro per inserire i marcatori all'inizio/fine della riproduzione macro

  3. hanno la undo codice di trattare tutte annullare eventi tra i due marcatori come unità e li annulla (e aggiungere i marcatori appropriati sulla fine della storia undo quindi, quando si redo le cose, sono ancora trattata come un unico blocco)

Caveats:

  • Ciò funziona solo per le macro che operano in un singolo buffer, se la macro buffer commutata (o ha avuto effetti collaterali in altri buffer), quelli le modifiche non sarebbero trattate come un blocco.
  • Se la tua macro è finita in un buffer diverso da quello in cui è stata avviata, dovresti gestirla in modo pulito - non vuoi che i marcatori "squilibrati" e macro-end siano presenti nell'elenco di annullamento.

Inutile dire che si tratta di uno sforzo complicato. Ti auguro buona fortuna.

+1

Grazie Trey. In effetti una risposta complessa. Una soluzione più semplice ma più hacker nello stesso spirito sarebbe quella di rendere call-last-kbd-macro (o un wrapper) inserire un qualche tipo di marcatore no-op nella lista di annullamenti. E quindi creare una nuova funzione clear-to-macro-marker che annullerebbe tutte le modifiche fino a quando il marker non è stato colpito. –

+2

Lungo queste linee è http://www.panix.com/~harley/elisp/undo-group.el che aggiunge un marker cioè due 'nil's che poi usa come limite per un comando' undo-group' . –