1

emacs(具体的には)で関数のリストを呼び出す関数を書きたいのですがkill-buffer-query-functions、それらのいずれかがユーザーの操作を必要とする場合は、nil代わりに単に返すようにして、すべてが非対話的に実行されるようにします。通常は値が。の例外をdefadviceユーザーに要求するすべての関数を変更するため に使用することを考えています。次に、すべてをフォームでラップします。唯一の問題は、ユーザーに何かを促す可能性のあるすべてのemaceselisp関数の完全なリストがないことです。thrownilcatch

誰かがそのようなリストを持っていますか、またはこれについて行くより簡単な方法はありますか?例として、関数yes-or-no-py-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

4

2 に答える 2

0

「commandp」を使用して、特定の機能がインタラクティブかどうかを判断できると思います。

だからただ走る(remove-if 'commandp kill-buffer-query-functions)

于 2010-08-04T04:34:58.870 に答える
0

これに対する可能な答えに出くわしました:

M-x describe-function minibuffer-with-setup-hook

(minibuffer-with-setup-hook FUN &rest BODY)

BODY の実行中に FUN を `minibuffer-setup-hook' に追加します。BODY は、ミニバッファーを最大 1 回使用する必要があります。ミニバッファーの再帰的な使用は影響を受けません。

したがって、それを使用して、ミニバッファーを使用しようとした場合に評価をBODY中止して戻りたい場合は、おそらくこれを使用できます。nilBODY

(catch 'tried-to-use-minibuffer
  (minibuffer-with-setup-hook 
      (lambda (&rest args) (throw 'tried-to-use-minibuffer nil))
    BODY))

これは後でテストします。


それは後で、私はこれをテストしました。それはうまくいきます。これが私の最終的なコードです:

(defmacro without-minibuffer (&rest body)
  "Like `progn', but stop and return nil if any of BODY forms tries to use the minibuffer.

Also disable dialogs while evaluating BODY forms, since dialogs
are just an alternative to the minibuffer."
  `(catch 'tried-to-use-minibuffer
     (minibuffer-with-setup-hook
         (lambda (&rest args) (throw 'tried-to-use-minibuffer nil))
       (let ((use-dialog-box))          ; No cheating by using dialogs instead of minibuffer
         ,@body))))

;; This should be indented like progn
(put 'without-minibuffer 'lisp-indent-function (get 'progn 'lisp-indent-function))
于 2010-08-05T03:59:07.797 に答える