2010-10-27 22 views
6

Dans emacs, j'appelle parfois appel-last-kbd-macro par erreur. Lors de la défaite, je m'attendais à annuler pour annuler tout l'effet de la macro du clavier atomiquement, mais cela n'arrive pas. Au lieu de cela, je me retrouve à devoir défaire chaque étape de la macro à la fois. Comment puis-je obtenir emacs pour revenir à l'état de tampon avant l'exécution de la macro?Comment annuler call-last-kbd-macro dans emacs

Répondre

2

Je crains que vous ne pouvez pas faire cela avec seulement le mécanisme 'undo intégré. Le système de macros dans Emacs reproduit les choses comme si l'utilisateur tapait réellement les frappes (ou les événements de la souris), et donc le undo history (buffer-undo-list) est mis à jour comme d'habitude.

Voici une suggestion sur la façon d'étendre le mécanisme actuel undo pour faire ce que vous voulez.

  1. étendre 'undo à comprendre une nouvelle entrée dans la liste d'annulation, un marqueur macro-begin et un élément macro-end

  2. conseiller/changer la lecture macro pour insérer les marqueurs au début/fin de la lecture macro

  3. ont le traitement de code undo tous les événements undo entre les deux marqueurs comme une unité et les annuler tous (et ajouter les marqueurs appropriés à la fin de l'histoire undo donc quand vous redo les choses, ils sont encore traité comme un seul bloc)

Avertissements:

  • Cela ne fonctionne que pour les macros qui fonctionnent dans un seul tampon, si les tampons macro commuté (ou avaient des effets secondaires dans d'autres tampons), les les changements ne seraient pas traités comme un bloc.
  • Si votre macro se terminait dans un tampon différent de celui démarré, vous deviez gérer cela correctement - vous ne voulez pas de marqueurs "déséquilibrés" macro-begin et macro-end dans la liste d'annulation.

Inutile de dire que c'est une entreprise compliquée. Je te souhaite bonne chance.

+1

Merci Trey. En effet une réponse complexe. Une solution plus simple mais plus hackish dans le même esprit serait de faire en sorte que call-last-kbd-macro (ou un wrapper) insère une sorte de marqueur non-op dans la liste d'annulation. Ensuite, créez une nouvelle fonction clear-to-macro-marker qui annulerait toutes les modifications jusqu'à ce que le marqueur soit frappé. –

+2

Le long de ces lignes est http://www.panix.com/~harley/elisp/undo-group.el qui ajoute un marqueur à savoir deux 'nil's qu'il utilise ensuite comme une limite pour une commande' undo-group' . –