Рекурсивное редактирование
Петля команд Emacs запускается автоматически при запуске Emacs. Это вызов командной петли верхнего уровня никогда не завершается; она продолжает работать, пока работает Emacs. Программы Lisp также могут вызывать командную петлю. Поскольку это приводит к более чем одному запуску командной петли, мы называем это рекурсивным редактированием. Уровень рекурсивного редактирования имеет эффект приостановки команды, которая его вызвала, и разрешает пользователю выполнить произвольное редактирование перед возобновлением этой команды.
Команды, доступные во время рекурсивного редактирования, такие же, как и в петле редактирования верхнего уровня, и определены в картах клавиш. Только несколько специальных команд выходят из уровня рекурсивного редактирования; остальные возвращаются на уровень рекурсивного редактирования по завершении. (Специальные команды для выхода всегда доступны, но они ничего не делают, когда рекурсивное редактирование не выполняется.)
Все командные петли, включая рекурсивные, устанавливают обработчики ошибок общего назначения, так что ошибка в команде, запущенной из командной петли, не выведет петлю из строя.
Ввод минибуфера — это особый вид рекурсивного редактирования. Он имеет несколько специальных особенностей, таких как включение отображения минибуфера и окна минибуфера, но меньше, чем можно предположить. Некоторые клавиши ведут себя по-разному в минибуфере, но это происходит только из-за локальной карты минибуфера; если вы переключаетесь между окнами, вы получаете обычные команды Emacs.
Для вызова уровня рекурсивного редактирования вызовите функцию recursive-edit. Эта функция содержит командную петлю; она также содержит вызов catch с тегом exit, что позволяет выйти из уровня рекурсивного редактирования, выбросив в exit (см. Обработка и выброс исключений). Выброс значения t заставляет recursive-edit завершить работу, так что управление возвращается к командной петле на один уровень выше. Это называется прерыванием и выполняется с помощью C-] (abort-recursive-edit). Аналогично, вы можете выбросить строковое значение, чтобы заставить recursive-edit сообщить об ошибке, выведя эту строку в качестве сообщения. Если вы выбросите функцию, recursive-edit вызовет ее без аргументов перед возвратом. Выброс любого другого значения заставит recursive-edit вернуться к функции, которая ее вызвала. Команда C-M-c (exit-recursive-edit) делает это.
Большинство приложений не должны использовать рекурсивное редактирование, за исключением использования минибуфера. Обычно для пользователя удобнее временно изменить основной режим текущего буфера на специальный основной режим, который должен иметь команду для возврата к предыдущему режиму. (Команда e в Rmail использует эту технику.) Или, если вы хотите предоставить пользователю разные тексты для рекурсивного редактирования, создайте и выберите новый буфер в специальном режиме. В этом режиме определите команду для завершения обработки и возврата к предыдущему буферу. (Команда m в Rmail делает это.)
Рекурсивные правки полезны при отладке. Вы можете вставить вызов debug в определение функции как своего рода точку останова, чтобы вы могли осмотреться, когда функция доберется до нее. debug вызывает рекурсивное редактирование, а также предоставляет другие функции отладчика.
Уровни рекурсивного редактирования также используются, когда вы набираете C-r в query-replace или используете C-x q (kbd-macro-query).
- Команда: recursive-edit
-
Эта функция вызывает командную петлю редактора. Она вызывается автоматически при инициализации Emacs, чтобы пользователь мог начать редактирование. При вызове из программы Lisp она переходит на уровень рекурсивного редактирования.
Если текущий буфер не совпадает с буфером выбранного окна,
recursive-editсохраняет и восстанавливает текущий буфер. В противном случае, если вы переключите буферы, буфер, на который вы переключились, будет текущим после возвратаrecursive-edit.В следующем примере функция
simple-recсначала передвигает точку на одно слово, затем входит в рекурсивное редактирование, выводит сообщение в области эха. Пользователь может затем выполнить любое необходимое редактирование, а затем нажать C-M-c, чтобы выйти и продолжить выполнениеsimple-rec.(defun simple-rec () (forward-word 1) (message "Recursive edit in progress") (recursive-edit) (forward-word 1)) ⇒ simple-rec (simple-rec) ⇒ nil
- Команда: exit-recursive-edit
Эта функция выходит из самого внутреннего рекурсивного редактирования (включая ввод минибуфера). Ее определение фактически равно
(throw 'exit nil).
- Команда: abort-recursive-edit
Эта функция прерывает команду, которая запросила самое внутреннее рекурсивное редактирование (включая ввод минибуфера), отправив сигнал
quitпосле выхода из рекурсивного редактирования. Ее определение фактически равно(throw 'exit t). См. Выход.
- Команда: top-level
Эта функция выходит из всех уровней рекурсивного редактирования; она не возвращает значение, так как она полностью перескакивает любую вычисление прямо обратно в основную командную петлю.
- Функция: recursion-depth
Эта функция возвращает текущую глубину рекурсивных правок. При отсутствии активного рекурсивного редактирования она возвращает 0.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Recursive-Editing.html