ユーザーからの決定を促すコマンドに対してプログラムで「はい」と答える方法


8

私は、カスタム関数を作っているコンバイン2つの機能さえずりモードtwittering-favoriteおよびtwittering-native-retweet、yesまたはnoの質問に答えることで、私からしかし、これら二つのニーズに入力。

これらの2つの関数を、私の直接の介入なしに回答を受け取るようなものでラップする方法があるかどうかを知りたいです。


8
私が使用していないtwittering-mode(と私は、コードにアクセスすることを気にしないだろう)が、アドバイスの一般的な言葉として:通常、あなたは(ユーザーの応答をシミュレートメークコードを示唆するものの代わりに行うのでyes)、そのコードを作る方が良いです答えを期待するコードを直接使用します。IOW、yes回答が呼び出される原因となるソースコードパスを活用してみてください。(単なる提案です。)
2015

これは一般的な方法で適切に行うことができないため、タイトルは誤解を招く可能性があります。
wasamasa

回答:


7

編集:@hatschipuhがコメントで指摘したように、flet-typeの構成はより簡単で、私の特異なアドバイスマクロに依存しません。少なくとも私のEmacs(24.5.1)では、cl-flet字句スコープを使用しているnofletため、次のスニペットが機能するためのパッケージが必要になります。下にスクロールして、元の特異な答えを探します。

(defun my/bypass-confirmation (function &rest args)
  "Call FUNCTION with ARGS, bypassing all `y-or-n-p' prompts."
  (require 'noflet)
  (noflet
      ((y-or-n-p (prompt) t))
    (apply function args)))

(defun my/bypass-confirmation-all (function &rest args)
  "Call FUNCTION with ARGS, bypassing all prompts.
This includes both `y-or-n-p' and `yes-or-no-p'."
  (require 'noflet)
  (noflet
      ((y-or-n-p    (prompt) t)
       (yes-or-no-p (prompt) t))
    (apply function args)))

編集:これは元の答えですが、my/bypass-confirmation-all宣伝どおりに機能するように修正し、呼び出し規約を少し変更しました。

以下は、すべての関数で機能する一般的なラッパーです。

(defun my/bypass-confirmation (function &rest args)
  "Call FUNCTION with ARGS, bypassing all `y-or-n-p' prompts."
  (my/with-advice
      ((#'y-or-n-p :override (lambda (prompt) t)))
    (apply function args)))

(defun my/bypass-confirmation-all (function &rest args)
  "Call FUNCTION with ARGS, bypassing all prompts.
This includes both `y-or-n-p' and `yes-or-no-p'."
  (my/with-advice
      ((#'y-or-n-p    :override (lambda (prompt) t))
       (#'yes-or-no-p :override (lambda (prompt) t)))
    (apply function args)))

このコードは、このマクロに依存しています。これは、Stackexchangeのすべての主要なソリューションのようです。

(defmacro my/with-advice (adlist &rest body)
  "Execute BODY with temporary advice in ADLIST.

Each element of ADLIST should be a list of the form
  (SYMBOL WHERE FUNCTION [PROPS])
suitable for passing to `advice-add'.  The BODY is wrapped in an
`unwind-protect' form, so the advice will be removed even in the
event of an error or nonlocal exit."
  (declare (debug ((&rest (&rest form)) body))
           (indent 1))
  `(progn
     ,@(mapcar (lambda (adform)
                 (cons 'advice-add adform))
               adlist)
     (unwind-protect (progn ,@body)
       ,@(mapcar (lambda (adform)
                   `(advice-remove ,(car adform) ,(nth 2 adform)))
                 adlist))))

このコードがこの状況を処理する最も賢い方法であるかどうか、私にはわかりません。一般に、元の関数のコードを複製する代わりに、この種の一時的なアドバイスを使用して既存の関数を変更するのが好きです。これは、元の関数の無関係な変更に対して変更された関数を将来にわたって保証するのに役立つためです。ただし、この場合twittering-mode、プロンプトを更新および変更したり、プロンプトを追加したりしても、変更が表示されないため、追加の注意が必要になる場合があります。y-or-nプロンプトは物議を醸す選択を示しているため、残念な結果になる可能性があります。


編集:使用例が役立つかもしれないと私は思いました。この例は、どちらの実装でも機能します。

(defun my/twittering-function ()
  ;; This will bypass `y-or-n-p' in both commands.
  (my/bypass-confirmation #'twittering-favorite arg)
  (my/bypass-confirmation #'twittering-native-retweet)
  ;; This will bypass both `y-or-n-p' and `yes-or-no-p' in this command.
  (my/bypass-confirmation-all #'twittering-favorite arg)
  ;; Prompts in this call are not bypassed.
  (twittering-native-retweet)

これは、カスタム関数内で(のみ)異なる動作をさせたい関数の動作を変更しませんか?
shackra

はい、それはあなたが欲しいものではありませんか?
アーロンハリス

正確ではありませんが、両方のコマンドの動作をどこでも変更することは、私が
不快に

1
私はあなたの以前のコメントを読み違えたかもしれません。バイパスされるプロンプトは、ラップされた関数呼び出し内のプロンプトのみです。明確にするために、使用例を回答に追加しました。
アーロンハリス

1
以下は基本的に同じを達成し、私が考える良い代替案です:(flet ((yes-or-no-p (prompt) t) (y-or-n-p (prompt) t)) body...)
クレメラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.