Я хочу написать функцию, которая будет вызывать список функций в emacs (в частности, kill-buffer-query-functions
), но если какая-либо из них требует взаимодействия с пользователем, я хочу, чтобы они просто возвращали nil
вместо этого, чтобывсе будет работать не в интерактивном режиме.Я думаю об использовании defadvice
для изменения каждой функции, которая обычно предлагает пользователю вместо throw
исключение со значением nil
.Тогда я заверну все с catch
формой.Единственная проблема в том, что у меня нет исчерпывающего списка всех функций emacs 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
По сути, я оборачиваю все в блок catch, затем определяю тело функции, которое будет просто принимать любые аргументы и выдавать соответствующее исключение.Я настроил список переопределений, которые должны быть переданы в flet
, который временно переопределит эти функции для использования вышеупомянутого тела, генерирующего исключения.Наконец, я оцениваю form
с учетом этих временных переопределений функций.
Теперь, возможно, в этом коде есть некоторые ошибки цитирования, но я думаю, что это сработало бы, если бы у меня был только соответствующий список функций, которые нужноredefine.
Обратите внимание, что я хочу, чтобы вся форма возвращалась, если требуется какое-либо взаимодействие с пользователем, а не только вызов конкретной функции в форме, которая требовала взаимодействия с пользователем.Чтобы понять, зачем мне это нужно, подумайте, что в форме можно задать один из следующих вопросов:
- Хотите удалить этот очень важный файл?да или нет
- Хотите сохранить этот очень важный файл?да или нет
Очевидно, что если я только что изменил yes-or-no-p
, чтобы всегда возвращать nil
(что означает "нет"), это все равно не спасет мой важный файл от удаления.Итак, поскольку я не знаю, какие вопросы могут быть заданы, я хочу, чтобы вся форма просто прерывалась и возвращала определенное значение, если она хочет что-то спросить у пользователя.
По сути, я хочускажите «Оцените этот код, но если вам нужно что-то спросить у меня, просто забудьте об этом и верните nil
».