Я хочу написать функцию, которая вызовет список функций в emacs (в частности, kill-buffer-query-functions
), но если кто-то из них требует взаимодействия с пользователем, я хочу, чтобы они просто вернули nil
, так что все это будет работать без -interactively. Я думаю использовать defadvice
для изменения каждой функции, которая обычно запрашивает у пользователя вместо throw
исключение со значением nil
. Затем я буду обернуть все форму catch
. Единственная проблема заключается в том, что у меня нет исчерпывающего списка всех функций emacs elisp, которые могли бы спросить пользователя о чем-то.Как поймать все вызовы функций elisp, требующие взаимодействия с пользователем?
У кого-нибудь есть такой список, или есть более простой способ сделать это? В качестве примеров функции yes-or-no-p
и y-or-n-p
, несомненно, будут указаны в этом списке, равно read-string
и completing-read
.
В принципе, я хочу, чтобы заполнить многоточие в этом коде:
(defun eval-but-return-if-requires-user (form &optional interactive-return)
"Evaluate FORM, but immediately stop and return INTERACTIVE-RETURN if any part of FORM would require user interaction."
;; Set up the safety net
(catch 'ui-required
(let ((ui-requiring-functions '( ... )) ; What goes in this list?
(ui-required-callback
;; A function that takes any number of args and throws an exception
'(lambda (&rest args)
(throw 'ui-required interactive-return)))
(flet-redefinitions
;; Use the above callback to create a list of redefinitions for `flet'
(mapcar (lambda (func)
(cons func (cdr ui-required-callback)))
ui-requiring-functions)))
`(flet
,flet-redefinitions ; Perform the function redefinitions,
,form)))) ; Then evaluate FORM
В принципе, я обернуть все в водосборный блоке, то я определить функцию органа, который будет просто принимать какие-либо аргументы и бросить соответствующий исключение. Я установил список переопределений для передачи flet
, который временно переопределит эти функции для использования вышеупомянутого тела исключения. Наконец, я оцениваю form
с этими временными переопределениями функций.
Теперь, вероятно, в этом коде есть некоторые ошибки цитирования, но я думаю, что это сработает, если у меня будет только соответствующий список функций для переопределения.
Обратите внимание, что я хочу, чтобы вся форма возвращалась, если требуется какое-либо взаимодействие с пользователем, а не только конкретный вызов функции в форме, требующей взаимодействия с пользователем. Чтобы узнать, зачем мне это нужно, подумайте, что в этой форме могут возникнуть вопросы:
- Вы хотите удалить этот очень важный файл? да или нет
- Вы хотите сохранить этот очень важный файл? да или нет
Очевидно, что если бы я только изменил yes-or-no-p
не всегда возвращать nil
(что означает «нет»), что до сих пор не гарантировано, чтобы сохранить свой важный файл от удаления. Поэтому, поскольку я не знаю, какие вопросы могут быть заданы, я хочу, чтобы вся форма просто прерывалась и возвращала определенное значение, если она хочет спросить что-либо о пользователе.
По сути, я хочу сказать «Оцените этот код, но если вам нужно что-то спросить, просто забудьте об этом и верните nil
».
Это, кажется, отлично работает. Может ли кто-нибудь подумать о разумном способе запроса пользователя, который не включает ни минибуфер, ни диалоговое окно? –