Как вы «повторяете» изменения после «отмены» с Emacs?

268

В этой статье говорится, что «Emacs имеет повтор, потому что вы можете изменить направление при отмене, тем самым отменяя отмену».

Что это значит? Как пользователь может «повторить» с Emacs?

prosseek
источник
3
Ответ под принятым ответом говорит вам, как , если именно поэтому вы смотрите на этот ответ, который, учитывая то, как он написан, я ожидал бы, что большинство людей действительно его ищут.
Аарон Холл
Я просто нажимаю пробел, а затем отменяю это, отменяю пробел и возвращаю отмененные вами действия, пока он не дойдет до конца, а затем снова не вернусь ... Я знаю, что есть гораздо более сложные способы, но это быстро и легко и вот так я катаюсь.
nroose

Ответы:

294

Краткая версия: отменив отмену. Если вы отмените, а затем выполните команду без редактирования, такую ​​как C-f, то следующая отмена отменит отмену, что приведет к повторному выполнению.

Более длинная версия:

Вы можете думать об отмене как о работе со стеком операций. Если вы выполняете какую-либо команду (даже команду навигации, например C-f) после последовательности операций отмены, все отмены помещаются в стек операций. Поэтому следующая отмена отменяет последнюю команду. Предположим, у вас есть последовательность операций, которая выглядит следующим образом:

  1. Вставьте "Foo"
  2. Вставьте "бар"
  3. Вставить "Я люблю спам"

Теперь вы отменяете. Это отменяет последнее действие, приводя к следующему списку:

  1. Вставьте "Foo"
  2. Вставьте "бар"

Если вы делаете что-то кроме отмены в этот момент - скажем C-f, стек операций выглядит так:

  1. Вставьте "Foo"
  2. Вставьте "бар"
  3. Вставить "Я люблю спам"
  4. Отменить вставку "Я люблю спам"

Теперь, когда вы отменяете, первое, что отменено - это отмена. Получив исходный стек (и состояние документа):

  1. Вставьте "Foo"
  2. Вставьте "бар"
  3. Вставить "Я люблю спам"

Если вы выполните изменяющую команду, чтобы разорвать последовательность отмен, эта команда будет добавлена ​​после отмены и, таким образом, будет первым, что впоследствии будет отменено. Предположим, что вы нажали «бар» вместо удара C-f. Тогда вы бы имели

  1. Вставьте "Foo"
  2. Вставьте "бар"
  3. Вставить "Я люблю спам"
  4. Отменить вставку "Я люблю спам"
  5. Удалить "бар"

Это добавление / повторное добавление происходит до бесконечности. Требуется немного привыкнуть, но это действительно дает Emacs очень гибкий и мощный механизм отмены / повторения.

Майкл Экстранд
источник
117
На всякий случай это звучит раздражающе, главное преимущество в том, что вы всегда можете вернуть предыдущее состояние. В большинстве редакторов, отмена нескольких изменений и последующий случайный ввод символа оставят вас «застрявшими» без возможности повторить то, что вы отменили. Emacs делает это тривиальным.
Филс
3
Я полагаю, что в вашей конструкции, если кто-то хотел сделать это на бумаге, вам понадобятся два стека. Потому что, если, например, в точке, где вы написали «Теперь, вы отменяете. Это отменяет последнее действие, приводя к следующему list: «вы (по понятным причинам) не показывали отмену, и если бы он сделал много отмен, вы бы не показывали их, пока что-то не было сделано, чтобы нарушить последовательность отмен, а затем добавили бы их. Другой способ показать это состоит в том, чтобы иметь один список и добавлять отмены в список даже до того, как они будут разбиты, а затем отмечать, где находится курсор в списке, чтобы мы знали, где отмены работают в обратном направлении
barlop
25
Это звучит раздражающе.
Фелипе
13
Я не знаю, почему этот ответ был принят, когда он даже не говорит вам, КАК .
Аарон Холл
8
К сожалению, этот ответ ничего не говорит о команде повтора, которая называется Cg C- /.
Вишнупрасант
211

Отменить: C-_

Чтобы повторить после отмены: C-g C-_

Введите несколько раз, C-_ чтобы повторить то, что было отменено. C-_ Чтобы повторить команду emacs несколько раз, выполните команду, затем введите, C-xzа затем введите несколько раз zклавишу, чтобы повторить команду (интересно, если вы хотите выполнить макрос несколько раз)

Жером Радикс
источник
5
C-uНапример, для повторения вы также можете использовать C-u 8 *(вставьте восемь *, где находится курсор). Таким образом, вы можете использовать, C-u x C-_чтобы отменить х шагов.
Патрик
10
Это не имеет ничего общего с исходным вопросом, но сразу после выполнения макроса клавиатуры (с C-x e), вы можете просто нажимать eтак часто, как вам нужно, чтобы выполнить его снова.
Кристиан Берг
7
Кроме того, C-/и C-x uальтернативные отмены привязок клавиш, эквивалентных C-_. Я предпочитаю, C-/так как это легче ударить.
Рори О'Кейн
8
Предупреждение: когда в этом ответе говорится, что C-g C-_«повторить после отмены», это применимо только при первом нажатии комбинации. После этого повторите ваш ключ отмены без C-g. Чтобы повторить три раза сразу после удаления, введите C-g C-_ C-_ C-_. Если вы C-g C-_ C-g C-_ C-g C-_введете текст, вы просто будете ходить кругами, отменяя повторение отмены ...
Рори О'Кейн
@ RoryO'Kane Я не знаю много об emacs, поэтому, пожалуйста, поправьте меня, где я ошибаюсь, но, учитывая, что Cg C-_ не имеет никакого эффекта после повтора, возможно, это потому, что он работает только после отмена (как предлагает ваше описание «повторить после отмены». Так что это не так много, что он идет по кругу, повторяя отмену или повтор и т. д., он ничего не делает, потому что отмена не была просто сделана до этого. так что Cg C- _ Cg C-_ не идет по кругу после первого, он буквально ничего не делает
barlop
56
  • Чтобы отменить один раз:C-/
  • Чтобы отменить дважды: C-/ C-/
  • Чтобы повторить один раз, сразу после того, как погибель:C-g C-/
  • Чтобы повторить дважды, сразу после отмены: C-g C-/ C-/. Обратите внимание, что C-gэто не повторяется.
  • Для того, чтобы отменить сразу же после того , как:C-g C-/
  • Чтобы отменить немедленно снова, дважды: C-g C-/ C-/
  • Чтобы повторить снова , то же самое ...

Если вы нажали какие-либо клавиши (будь то ввод символов или просто перемещение курсора) со времени последней команды отмены, вам не нужно вводить текст C-gперед следующей отменой / возвратом. C-gэто просто безопасный ключ для нажатия, который ничего не делает сам по себе, но считается как не отмененный ключ, сигнализирующий об окончании последовательности отмены. Нажатие другой команды, например, C-fбудет работать; просто он будет перемещать курсор от того места, где он был у вас.

Если вы нажали C-gили другую команду, когда вы не хотели, и теперь вы отменяете в неправильном направлении, просто нажмите, C-gчтобы снова изменить свое направление. Вы должны будете отменить все случайные повторы и отмены, прежде чем доберетесь до отмены, которую хотите, но если вы просто продолжите нажимать C-/, вы в конечном итоге достигнете желаемого состояния. Фактически, каждое состояние, в котором когда-либо находился буфер, достижимо, если вы нажмете C-gодин раз, а затем нажмете C-/достаточно раз.

Альтернативные ярлыки undo, кроме C-/, есть C-_, C-x uи M-x undo.

Смотрите Undo в Руководстве по Emacs для более подробной информации о системе отмены Emacs.

Рори О'Кейн
источник
38

Для тех, кто хочет иметь более общие функции отмены / повтора, кто-то написал undo-tree.el. Он обеспечивает внешний вид отмены, не связанной с Emacs, но обеспечивает доступ ко всему «дереву» истории отмен.

Мне нравится встроенная система отмены Emacs, но я нахожу этот пакет очень интуитивным.

Вот комментарий от самого файла:

Emacs имеет мощную систему отмены. В отличие от стандартной системы отмены / повтора в большинстве программ, она позволяет восстанавливать любые прошлое состояние буфера (тогда как стандартная система отмены / возврата может потерять прошлые состояния, как только вы выполните повтор). Однако эта мощь имеет свою цену: многие люди находят систему отмены Emacs запутанной и сложной в использовании, порождая ряд пакетов, которые заменяют ее на менее мощную, но более интуитивную систему отмены / возврата.

И потеря данных со стандартными отменами / повторами, и путаница отмены Emacs проистекают из попытки трактовать историю отмен как линейную последовательность изменений. Это не. `Режим отмены дерева ', предоставляемый этим пакетом, заменяет систему отмены Emacs системой, которая обрабатывает историю отмены как то, что она есть: ветвящееся дерево изменений. Эта простая идея позволяет сочетать более интуитивное поведение стандартной системы отмены / возврата с возможностью никогда не потерять историю. Дополнительный побочный бонус заключается в том, что в некоторых случаях история отмен может быть сохранена более эффективно, что позволяет накопить больше изменений, прежде чем Emacs начнет отбрасывать историю.

Трей Джексон
источник
3
Фантастика! Кто сказал, что emacs отменить было непостижимо? :-)
Peter.O
Удивительный! концептуально звучит и интуитивно понятен пользователю. Это должно быть в пакетах по умолчанию. Один комментарий: Я хотел бы, чтобы какое-то предупреждающее сообщение также отображалось при повторном выполнении с точки ветвления, а не только при возврате к нему. Например, когда пользователь вызывает повтор: «Повтор с точки ветвления» или «Используется ответная ветвь по умолчанию» - просто для предупреждения пользователя о наличии нескольких ветвей.
Базель Шишани
1
Другой подход к этой проблеме, который намного проще реализовать и не требует визуализатора, состоит в том, чтобы сохранить ТОЛЬКО последнюю точку ветвления и предоставить 3 команды: отменить, повторить, переключить ветвь. Undo / redo предупредит, когда будет нажата ветвь THE, и switch-branch просто переключится, если в ветке просто выдаст сообщение «not at a branch». Если ветвление происходит в любое время, предыдущая точка ветвления теряется. Это позволило бы решить проблему потери состояния достаточно хорошо и с минимальной сложностью.
Базель Шишани
1
Остерегайтесь, это имеет давнюю ошибку в повторении, которая может случайно привести к ошибке: github.com/syl20bnr/spacemacs/issues/9903 - известна с 2014 года
ideasman42
@ ideasman42 По-видимому, это «не ошибка»: dr-qubit.org/Lost_undo-tree_history.html
Dalker
19

Остерегайтесь причудливого причудливого дерева для повторения !

Многие популярные «стартовые наборы» (прелюдия, purcell, spacemacs) поставляются в комплекте с отменить дерево. Большинство (все?) Даже автоматически включают его. Как уже упоминалось, дерево отмены - это удобный способ визуализации и обхода дерева отмены / повтора. Прелюдия даже дает ему клавишный аккорд ( uu), а также C-x u.

Проблема заключается в том : уничтожьте дерево , кажется, разрушит по умолчанию Emacs' и хорошо известно обязательным для повтора :C-g C-/ .

Вместо этого вы можете использовать эти симметричные ключи для отмены / повтора :

C-/     undo
C-S-/   redo

Это полезно, поскольку иногда вы хотите быстро повторить, не открывая визуализатор.

Мика Эллиотт
источник
Это. Я использую Spacemacs и не могу понять, почему это не работает для меня. Спасибо!
mghaoui
11

Я нахожу redo.elчрезвычайно удобным для выполнения «нормальной» отмены / повтора, и я обычно привязываю это к CSz и отмену к Cz, вот так:

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

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

Просто скачайте файл, вставьте его в свой lisp-путь и вставьте вышеупомянутый в свой .emacs.

monotux
источник
Комментарии в заголовке redo.el говорят, что это сделано для XEmacs. Есть ли проблемы с использованием его в GNU Emacs и других связанных Emacsen?
А. Леви
У меня еще не было никаких проблем, и я использую это по крайней мере 6 месяцев :)
monotux
4
Из emacswiki.org/emacs/RedoMode : Однако redo.el устарел и часто уничтожает содержимое буфера, поскольку поведение 'primitive-undo' немного отличается от старого, так как Emacs 22. RedoPlus является вилка redo.el и корректно работает в более новой версии Emacs. Вы можете получить RedoPlus здесь: emacswiki.org/emacs/redo+.el
rofrol
2

Emacs 28 добавляет команду повтора (вызывается undo-redo).

Если вы хотите иметь более типичную отмену / повтор, используйте следующие команды.

(global-set-key (kbd "C-z") 'undo-only)
(global-set-key (kbd "C-S-z") 'undo-redo)
ideasman42
источник
1

Если вы хотите повторить последнюю операцию, сделайте следующее.

  1. ESC
  2. Сделать еще один отменить ( C + /)
vineeshvs
источник
0

По умолчанию для повтора в Emacs требуется нажать Cg, а затем отменить.

Однако возможно использовать встроенную в Emacs отмену, чтобы также реализовать команду повтора.

Пакет undo-fu использует встроенную функцию отмены Emacs для предоставления как отмен, так и повторения.

ideasman42
источник