Comment «refaire» les changements après «annuler» avec Emacs?

268

Cet article dit que "Emacs a recommencé parce que vous pouvez inverser la direction pendant l'annulation, annulant ainsi l'annulation".

Qu'est-ce que ça veut dire? Comment un utilisateur peut-il «refaire» avec Emacs?

prosseek
la source
3
La réponse sous la réponse acceptée vous indique comment , si c'est pourquoi vous regardez cette réponse, qui, compte tenu de la façon dont elle est écrite, je m'attendrais à ce que la plupart des gens la recherchent réellement.
Aaron Hall
Je viens d'appuyer sur la barre d'espace, puis d'annuler après cela, d'annuler l'espace et de refaire les annulations que vous avez faites jusqu'à la fin, puis de recommencer ... Je sais qu'il existe des moyens beaucoup plus compliqués, mais c'est rapide et facile, et c'est comme ça que je roule.
nroose

Réponses:

294

Version courte: en annulant l'annulation. Si vous annulez, puis effectuez une commande de non-édition telle que C-f, l'annulation suivante annulera l'annulation, ce qui entraînera une répétition.

Version plus longue:

Vous pouvez penser à annuler comme opérant sur une pile d'opérations. Si vous exécutez une commande (même une commande de navigation telle que C-f) après une séquence d'opérations d'annulation, toutes les annulations sont poussées vers la pile d'opérations. Ainsi, la prochaine annulation annule la dernière commande. Supposons que vous ayez une séquence d'opérations qui ressemble à ceci:

  1. Insérer "foo"
  2. Insérer une "barre"
  3. Insérer "J'aime le spam"

Maintenant, vous annulez. Il annule la dernière action, ce qui donne la liste suivante:

  1. Insérer "foo"
  2. Insérer une "barre"

Si vous faites autre chose que l'annulation à ce stade - disons C-f, la pile d'opérations ressemble à ceci:

  1. Insérer "foo"
  2. Insérer une "barre"
  3. Insérer "J'aime le spam"
  4. Annuler l'insertion "J'aime le spam"

Maintenant, lorsque vous annulez, la première chose qui est annulée est l'annulation. Résultat dans votre pile d'origine (et l'état du document):

  1. Insérer "foo"
  2. Insérer une "barre"
  3. Insérer "J'aime le spam"

Si vous effectuez une commande de modification pour interrompre la séquence d'annulation, cette commande est ajoutée après l'annulation et est donc la première chose à annuler ensuite. Supposons que vous ayez reculé sur "bar" au lieu de frapper C-f. Vous auriez alors eu

  1. Insérer "foo"
  2. Insérer une "barre"
  3. Insérer "J'aime le spam"
  4. Annuler l'insertion "J'aime le spam"
  5. Supprimer "bar"

Cet ajout / rajout se produit à l'infini. Il faut un peu de temps pour s'y habituer, mais cela donne vraiment à Emacs un mécanisme d'annulation / rétablissement très flexible et puissant.

Michael Ekstrand
la source
117
Juste au cas où cela semble ennuyeux, le principal avantage est que vous pouvez toujours retrouver un état antérieur. Dans la plupart des éditeurs, l'annulation de plusieurs modifications, puis la saisie accidentelle d'un caractère vous laisseraient «bloqués» sans aucun moyen de refaire ce que vous aviez annulé. Emacs rend cela trivial.
phils
3
Je suppose que dans votre construction, si une personne voulait le faire sur papier, vous auriez besoin de deux piles.Par exemple, au point où vous avez écrit "Maintenant, vous annulez. Cela annule la dernière action, résultant en ce qui suit list: "vous (naturellement) n'avez pas montré l'annulation, et s'il avait fait plusieurs annulations, vous ne les montreriez pas tant que quelque chose n'a pas été fait pour casser la séquence d'annulation, alors vous les ajouteriez. Une autre façon de le montrer serait d'avoir une liste et d'ajouter des annulations à la liste avant même qu'elles ne soient cassées, mais de noter où se trouve le curseur dans la liste, afin que nous sachions où les annulations fonctionnent à l'envers à partir de
barlop
25
Cela semble ennuyeux.
Felipe
13
Je ne sais pas pourquoi cette réponse a été acceptée alors qu'elle ne vous dit même pas COMMENT .
Aaron Hall
8
Malheureusement, cette réponse ne dit rien sur la commande de rétablissement qui est Cg C- /.
vishnuprasanth
211

Défaire: C-_

Pour refaire après une annulation: C-g C-_

Tapez plusieurs fois C-_ pour refaire ce qui a été annulé par C-_ Pour refaire une commande emacs plusieurs fois, exécutez votre commande puis tapez C-xzpuis tapez plusieurs fois sur la ztouche pour répéter la commande (intéressant lorsque vous voulez exécuter plusieurs fois une macro)

Jérôme Radix
la source
4
Pour répéter des trucs, vous pouvez également utiliser C-u, par exemple C-u 8 *(insère huit * où se trouve le curseur). Vous pouvez donc utiliser C-u x C-_pour annuler x étapes.
Patrick
10
Cela n'a rien à voir avec la question d'origine, mais juste après avoir exécuté une macro clavier (avec C-x e), vous pouvez simplement appuyer eaussi souvent que nécessaire pour l'exécuter à nouveau.
Christian Berg
7
Aussi, C-/et C-x usont des raccourcis clavier alternatifs, équivalents à C-_. Je préfère C-/car c'est plus facile à toucher.
Rory O'Kane
8
Attention: lorsque cette réponse indique que C-g C-_"refaire après une annulation", cela ne s'applique que la première fois que vous appuyez sur la combinaison. Après cela, répétez votre touche d'annulation sans C-g. Donc, pour refaire trois fois juste après l'annulation, tapez C-g C-_ C-_ C-_. Si vous tapez C-g C-_ C-g C-_ C-g C-_, vous allez simplement tourner en rond, défaire votre rétablissement de votre défaite ...
Rory O'Kane
@ RoryO'Kane Je ne connais pas grand-chose à emacs, alors corrigez-moi où je me trompe, mais étant donné que Cg C-_ n'a aucun effet après un rétablissement, est-ce possible parce qu'il ne fonctionne qu'après une annulation (comme le suggère votre description "refaire après une annulation". Donc, ce n'est pas tellement que ça tourne en rond en refaisant une annulation ou une redo, etc. ça ne fait rien parce qu'une annulation n'a pas été faite juste avant. donc Cg C- _ Cg C-_ ne
tourne
56
  • Pour annuler une fois:C-/
  • Pour annuler deux fois: C-/ C-/
  • Pour refaire une fois, immédiatement après l'annulation:C-g C-/
  • Pour refaire deux fois, immédiatement après défaisant: C-g C-/ C-/. Notez que cela C-gn'est pas répété.
  • Pour annuler à nouveau immédiatement , une fois:C-g C-/
  • Pour annuler à nouveau immédiatement, deux fois: C-g C-/ C-/
  • Pour refaire encore , pareil…

Si vous avez appuyé sur une touche (que ce soit en tapant des caractères ou en déplaçant simplement le curseur) depuis votre dernière commande d'annulation, il n'est pas nécessaire de taper C-gavant votre prochaine annulation / restauration. C-gest juste une touche sûre à frapper qui ne fait rien par elle-même, mais compte comme une touche non annulée pour signaler la fin de votre séquence d'annulation. Appuyez sur une autre commande telle que celle C-fqui fonctionnerait aussi; c'est juste que cela déplacerait le curseur de l'endroit où vous l'aviez.

Si vous frappez C-gou une autre commande alors que vous ne le vouliez pas, et que vous annulez maintenant dans la mauvaise direction, appuyez simplement sur C-gpour inverser à nouveau votre direction. Vous devrez annuler tout au long de vos annulations et annulations accidentelles avant d'arriver aux annulations que vous voulez, mais si vous continuez à frapper C-/, vous finirez par atteindre l'état que vous voulez. En fait, chaque état dans lequel le tampon a jamais été accessible est accessible si vous appuyez C-gune fois, puis appuyez C-/suffisamment de fois.

Raccourcis alternatifs pour undo, autres que C-/sont C-_, C-x uet M-x undo.

Voir Annuler dans le manuel Emacs pour plus de détails sur le système d'annulation d'Emacs.

Rory O'Kane
la source
38

Pour ceux qui souhaitent avoir la fonctionnalité d'annulation / rétablissement la plus courante, quelqu'un a écrit undo-tree.el. Il offre l'aspect et la convivialité de l'annulation non Emacs, mais donne accès à l'ensemble de l'arborescence de l'histoire de l'annulation.

J'aime le système d'annulation intégré d'Emacs, mais je trouve ce package très intuitif.

Voici le commentaire du fichier lui-même:

Emacs dispose d'un puissant système d'annulation. Contrairement au système d'annulation / de restauration standard de la plupart des logiciels, il vous permet de récupérer tout état antérieur d'un tampon (alors que le système d'annulation / de restauration standard peut perdre des états passés dès que vous le refaitez). Cependant, cette puissance a un prix: beaucoup de gens trouvent le système d'annulation d'Emacs déroutant et difficile à utiliser, engendrant un certain nombre de packages qui le remplacent par le système d'annulation / restauration moins puissant mais plus intuitif.

La perte de données avec l'annulation / la restauration standard et la confusion de l'annulation d'Emacs découlent de la tentative de traiter l'historique de l'annulation comme une séquence linéaire de changements. Ce n'est pas. Le «mode d'annulation d'arbre» ​​fourni par ce paquet remplace le système d'annulation d'Emacs par un système qui traite l'historique d'annulation comme ce qu'il est: un arbre de branchement des changements. Cette idée simple permet de combiner le comportement plus intuitif du système d'annulation / rétablissement standard avec le pouvoir de ne jamais perdre d'historique. Un autre avantage supplémentaire est que l'historique d'annulation peut dans certains cas être stocké plus efficacement, permettant à plus de modifications de s'accumuler avant qu'Emacs ne commence à supprimer l'historique.

Trey Jackson
la source
3
Fantastique! Qui a dit qu'emacs undo était insondable? :-)
Peter.O
Incroyable! conceptuellement solide et intuitif pour l'utilisateur. Cela devrait être dans les packages par défaut. Un commentaire: je souhaite qu'un message d'alerte soit également affiché lors de la reprise à partir d'un point de branchement, et pas seulement lorsque vous y revenez. Par exemple, lorsque l'utilisateur appelle un rétablissement: «Refaire à partir d'un point de branche» ou «Branche de rétablissement par défaut utilisée» - simplement pour alerter l'utilisateur qu'il existe plusieurs branches.
Basel Shishani
1
Une autre approche de ce problème qui est beaucoup plus simple à implémenter et ne nécessite pas de visualiseur consiste à conserver UNIQUEMENT le dernier point de branchement et à fournir 3 commandes: annuler, rétablir, changer de branche. Undo / redo alertera lorsque la branche sera touchée, et switch-branch changera simplement si dans une autre branche émet simplement un message 'not at a branch'. Si un branchement se produit à tout moment, le point de branchement précédent est perdu. Cela résoudrait le problème de la perte d'état raisonnablement bien et avec une complexité minimale.
Basel Shishani
1
Attention, il y a un bogue de longue date dans redo qui peut échouer au hasard: github.com/syl20bnr/spacemacs/issues/9903 - connu depuis 2014
ideasman42
@ ideasman42 Apparemment, il s'agit d'un "non-bug": dr-qubit.org/Lost_undo-tree_history.html
Dalker
19

Méfiez-vous de la bizarrerie d'un arbre à restaurer !

De nombreux «kits de démarrage» populaires (prélude, purcell, spacemacs) sont livrés avec un arbre d'annulation. La plupart (tous?) L'activent même automatiquement. Comme mentionné, l'annulation de l'arbre est un moyen pratique de visualiser et de parcourir l'arbre d'annulation / de rétablissement. Prelude lui donne même un accord de touche ( uu), et aussi C-x u.

Le problème est: undo-arbre semble épave par défaut Emacs et bien connu pour la liaison redo :C-g C-/ .

Au lieu de cela, vous pouvez utiliser ces touches symétriques pour annuler / rétablir :

C-/     undo
C-S-/   redo

Celles-ci sont utiles car vous voulez parfois refaire rapidement sans ouvrir le visualiseur.

Micah Elliott
la source
Ce. J'utilise Spacemacs et je n'ai pas pu comprendre pourquoi cela ne fonctionnait pas pour moi. Merci!
mghaoui
11

Je trouve redo.elextrêmement pratique pour faire des annulations / rétablissements "normaux", et je les lie généralement à CSz et annuler à Cz, comme ceci:

(when (require 'redo nil 'noerror)
    (global-set-key (kbd "C-S-z") 'redo))

(global-set-key (kbd "C-z") 'undo)

Téléchargez simplement le fichier, placez-le dans votre lisp-path et collez ce qui précède dans votre .emacs.

monotux
la source
Les commentaires dans l'en-tête de redo.el indiquent qu'il est fait pour XEmacs. Y a-t-il un problème à l'utiliser dans GNU Emacs et d'autres Emacsen associés?
A. Levy
Je n'ai pas encore eu de problèmes et je l'utilise depuis au moins 6 mois :)
monotux
4
De emacswiki.org/emacs/RedoMode : Cependant, redo.el est obsolète et détruit souvent le contenu de "buffer car le comportement de" primitive-undo "a été légèrement différent de l'ancien depuis Emacs 22. RedoPlus est une fourche de redo.el et fonctionne correctement dans la nouvelle version d'Emacs. Vous pouvez obtenir RedoPlus ici: emacswiki.org/emacs/redo+.el
rofrol
2

Emacs 28 ajoute une commande de rétablissement (appelée undo-redo).

Si vous souhaitez effectuer des annulations / rétablissements plus typiques, les commandes suivantes peuvent être utilisées.

(global-set-key (kbd "C-z") 'undo-only)
(global-set-key (kbd "C-S-z") 'undo-redo)
ideasman42
la source
1

Si vous souhaitez refaire la dernière opération, procédez comme suit.

  1. ESC
  2. Faire une autre annulation ( C + /)
Vesheshvs
la source
0

Par défaut, refaire dans Emacs nécessite d'appuyer sur Cg, puis d'annuler.

Cependant, il est possible d'utiliser l'annulation intégrée d'Emacs pour implémenter une commande de rétablissement également.

Le package undo-fu , utilise la fonctionnalité d'annulation intégrée d'Emacs pour exposer à la fois l'annulation et la restauration.

ideasman42
la source