Как возобновить незавершенную запись макросов клавиатуры?

10

Классический вариант использования:

  1. Вы начинаете запись макроса: C-x (
  2. Вы делаете некоторые вещи, скажем hello.
  3. Допустим, вы запускаете команду, которая выдает ошибку C-g(например, вы по ошибке запустили, C-sи вам нужно отменить ее C-g, теперь ваша работа потеряна).

Теперь ваша запись потеряна.

Я хотел бы продолжить с того места, где остановился, прежде чем выполнил команду, которая прервала мою запись. Я посмотрел C-h f start-kbd-macro, но он написан на C, поэтому я не могу настроить его. Я также искал переменную типа current-kbd-macro, но пока не нашел ничего.

Это можно восстановить?

Обновить:

Я не мог понять, почему C-u C-x (это не работает для меня, но я обнаружил, что это потому, что я тестировал с C-g.

Оказывается, это C-gособенное - если вы запускаете ошибку другого типа, например

C-x ( M-: (signal 'quit nil) 

Тогда это остановит запись, но last-kbd-macroбудет содержать "M-: M-( signal 'quit nil", но с

C-x ( C-g

Это останавливает запись и удаляет все записанное. Как пользователь Cg-happy (как и двое моих друзей), это довольно неудачное различие. Я пытался редактировать keyboard-quit, но там я ничего не могу сделать.

Похоже, что единственный способ восстановить это - через recent-keysи автоматически определить, где был вызван макрос start-kbd (или аналогичный), как в kmacro-edit-lossage.

Кристофер Готово
источник

Ответы:

8

Я начал реализацию здесь, которая позволяет вам привязать C-x (к resmacro-start-macro.

Теперь предположим, что вы прошли половину макроса, ошиблись и нажали C-g, например, вы бежали C-sпо ошибке и ударили, C-gчтобы отменить его, или ж / д.

C-x ( hello C-s C-g 

Теперь запустите, C-u C-x (который подскажет в минибуфере:

Возобновить макрос с (RET: продолжить, DEL: удалить последний): h e l l o C-s

Таким образом, вы нажали Backspace ( DEL), чтобы удалить C-sи затем RETпродолжить. Теперь это говорит:

Присоединение к макросу kbd ...

И вы можете продолжить.

В целом:

C-x (      -- start macro
hello
C-s        -- mistake
C-g        -- cancel mistake (and macro)
C-u C-x (  -- recover lost macro
DEL        -- remove mistake
RET        -- continue recording
world!

Удобный, без переключения контекста, минимальное количество сочетаний клавиш для выполнения задачи, автоматически определяет, откуда ваш макрос (с C-x () начался (recent-keys).

Кристофер Готово
источник
1
Эй, это звучит очень мило. Хотите отправить его как патч в Emacs?
Стефан
Вы можете сделать это / relicense, как вам нравится! Я собираюсь на некоторое время опробовать его на месте, прежде чем объявить где-либо, чтобы я знал, что это надежно. Тем не менее, разработчики Emacs могут подумать, что это слишком глупо. ;-)
Кристофер Готово
Чтобы включить его в Emacs, нам нужно, чтобы автор подписал документы об авторских правах (конечно, эта же документация также распространяется на режим бога).
Стефан
Ссылка сейчас не работает :(
DirtY iCE
2

Выполните kmacro-start-macro-or-insert-counterс префиксом ( C-u), чтобы добавить к предыдущему макросу.

artagnon
источник
2
Строка документация не говорит об этом, но двойном префиксе Arg ( C-u C-u) устанавливает какAPPEND и NO-EXECаргументы start-kbd-macro, которая позволяет добавлять без первоначальной переигровки макро-так далеко. Такое поведение является документально в руководстве, однако:(emacs) Basic Keyboard Macro
Phils
Попробуйте это с примером в моем вопросе, не работает.
Кристофер Совершено
2

Сочетание хороших ответов от stsquad и artagnon дает (на мой взгляд) полное решение проблемы, которое вполне разумно:

  • C-xC-keC-hl редактировать макрос, сгенерированный из потерь
  • редактировать макрос, чтобы уменьшить его до исходной записи
  • C-cC-c хранить отредактированный макрос
  • Либо C-u<f3>сначала воспроизвести этот макрос, а затем продолжить запись последующих нажатий клавиш, которые будут добавлены в определение макроса
  • ... или C-uC-u<f3>продолжить запись без первоначального воспроизведения макроса до сих пор.

Возможно, необходимость редактировать макрос с потерями не идеальна , но (а) вам обязательно нужно редактировать макрос независимо от того, прервали ли вы запись, и (б) это не должно происходить очень часто, если вы просто помните, как нормально останавливать макрос (например, с помощью <f4>вместо C-g).

Ничто из этого не говорит о том, что было бы бесполезно, если прерванный макрос где-то хранился; просто я не думаю, что это на самом деле происходит. Вероятно, стоило M-x report-emacs-bugбы предложить эту функцию.

Phils
источник
Это не решает проблему. С вашим решением половину времени было бы проще просто запустить макрос заново. Я отправил ответ в другом месте, который действительно решает проблему.
Кристофер Сделано
1
Конечно, для простых случаев начать было бы проще. Это все еще полезно для остальных, однако, это означает, что некоторые люди найдут это полезным; тем более что он доступен по умолчанию. Как я уже указывал, я думаю, что идея более автоматизированного подхода является хорошей, поэтому я рад видеть, что вы работаете над решением и, безусловно, проголосовали за ваш ответ.
phils
0

Каноническое решение - это C-x C-k C-e( kmacro-edit-macro), которое позволит вам проходить каждое нажатие клавиши и вставлять / удалять все, что вы хотите. Синтаксис команды для редактора немного лаконичен, но ?приведёт руководство. Существует более естественный редактор, связанный с C-x C-k e( edit-kbd-macro), который предоставляет текстовый редактор макросов с комментариями.

Другой вариант, M-x insert-kbd-macroкоторый позволит вам редактировать макрос как Lisp, но это не самая читаемая вещь в мире.

Что касается переменных, вы ищете last-kbd-macroи kmacro-ring.

Поскольку вы упоминаете, что не завершили свой макрос, вы можете просто создать его из своей потери. C-x C-k e C-h lи удалите до 300 предыдущих символов.

stsquad
источник
Это плохой ответ, который я бы понизил, если бы мог. Вы либо не читали вопрос, либо игнорируете его. Ни содержат, last-kbd-macroни kmacro-ringсодержат клавиши, нажатые ранее, C-gили произошла ошибка. Я специально поставил в своем заглавии INCOMPLETE заглавными буквами, ожидая таких плохих ответов. Спасибо за попытку помочь.
Кристофер Совершено
1
@ChristopherDone: конечно, вы можете - я добавил примечание внизу, чтобы упомянуть потерю. Вы можете создать макрос из 300 ранее набранных символов.
Stsquad
Да, кто-то упоминал потерю на #emacs. Я просто хочу возобновить, где я остановился. Я не хочу открывать редактор и начинать удалять что-то из этого, когда я нахожусь в процессе выполнения чего-либо.
Кристофер Сделано
2
Комбинация этого и ответов артаньона дает прекрасное решение: C-x C-k e C-h lотредактировать, а C-c C-cзатем C-u f3продолжить запись (отметив, что этот последний f3сначала будет воспроизводить макрос до тех пор, пока не будет ожидать дальнейшего ввода). Возможно, необходимость редактировать макрос с потерями не идеальна , но (а) вам обязательно нужно редактировать макрос независимо от того, прервали ли вы запись, и (б) это не должно происходить очень часто, если вы просто помните, как остановить макрос нормально.
phils
1
@phils +1 Может быть, вы должны превратить это в отдельный ответ.
itjeyd