【发布时间】:2010-08-04 01:33:34
【问题描述】:
我想编写一个函数来调用 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 并使用这些临时函数重新定义。
现在,该代码中可能存在一些引用错误,但我认为如果我有要重新定义的函数的适当列表,它会起作用。
请注意,如果需要任何用户交互,我希望返回整个表单,而不仅仅是表单中需要用户交互的特定函数调用。要了解我为什么需要这个,请考虑该表单可能想问以下任一问题:
- 您要删除这个非常重要的文件吗?是或否
- 您要保留这个非常重要的文件吗?是或否
显然,如果我只是将yes-or-no-p 修改为始终返回nil(这意味着“否”),仍然不能保证我的重要文件不会被删除。所以,因为我不知道可能会问什么问题,所以我想让整个表单简单地中止并返回一个特定的值,如果它想问用户任何问题。
本质上,我想说“评估此代码,但如果您必须问我任何事情才能这样做,请忘记它并返回nil。”
【问题讨论】:
标签: try-catch elisp non-interactive