Wie kann ich programmgesteuert mit "Ja" auf die Befehle antworten, die den Benutzer zur Entscheidung auffordern?

8

Ich habe eine benutzerdefinierte Funktion , die vereint zwei Funktionen von Zwitschern-Modus , twittering-favoriteund twittering-native-retweet, aber diese beiden Bedürfnisse Eingabe von mir durch ein Ja oder Nein Frage beantworten.

Ich möchte wissen, ob es eine Möglichkeit gibt, diese beiden Funktionen mit etwas zu versehen, mit dem sie ohne mein direktes Eingreifen eine Antwort erhalten.

Shackra
quelle
8
Ich verwende es nicht twittering-mode(und ich werde mich nicht darum kümmern, auf den Code zuzugreifen), aber als allgemeinen Ratschlag: Normalerweise yesist es besser, Code zu erstellen , anstatt das zu tun, was Sie vorschlagen (Code erstellen, der die Beantwortung eines Benutzers simuliert ) Verwendet direkt den Code, der die Antwort erwartet. IOW, versuchen Sie, den Quellcodepfad zu nutzen, den eine yesAntwort aufrufen würde. (Nur ein Vorschlag.)
Drew
Der Titel ist irreführend, da dies nicht generisch richtig gemacht werden kann.
Wasamasa
Siehe auch
YoungFrog

Antworten:

7

EDIT: Wie @hatschipuh in den Kommentaren betonte, ist eine fletKonstruktion vom Typ einfacher und beruht nicht auf meinem eigenwilligen Ratgeber-Makro. Zumindest auf meinem Emacs (24.5.1) cl-fletwird lexikalisches Scoping verwendet, sodass Sie das nofletPaket benötigen , damit das folgende Snippet funktioniert. Scrollen Sie nach unten, um die ursprüngliche, eigenwillige Antwort zu erhalten.

(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)))

BEARBEITEN: Dies ist die ursprüngliche Antwort, außer dass ich mich darauf festgelegt habe my/bypass-confirmation-all, wie angekündigt zu arbeiten, und die Aufrufkonventionen ein wenig geändert habe.

Hier ist ein allgemeiner Wrapper, der für jede Funktion funktionieren sollte.

(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)))

Dieser Code hängt von diesem Makro ab, das meine Lösung für alles in Stackexchange zu sein scheint.

(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))))

Ob dieser Code der klügste Weg ist, mit dieser Situation umzugehen, weiß ich nicht. Im Allgemeinen verwende ich diese Art von temporären Ratschlägen gerne, um Änderungen an vorhandenen Funktionen vorzunehmen, anstatt den Code der ursprünglichen Funktionen zu duplizieren, auch weil dies dazu beiträgt, Ihre geänderte Funktion gegen nicht verwandte Änderungen im Original zukunftssicher zu machen. In diesem Fall müssen Sie jedoch möglicherweise zusätzliche Sorgfalt walten lassen, da twittering-modedie Änderungen nicht angezeigt werden, wenn die Eingabeaufforderungen aktualisiert und geändert oder eine zusätzliche hinzugefügt wird. Da eine y-or-n-Eingabeaufforderung auf eine kontroverse Auswahl hinweist, kann dies unglückliche Folgen haben.


EDIT: Mir ist aufgefallen, dass ein Anwendungsbeispiel hilfreich sein könnte. Dieses Beispiel funktioniert mit beiden Implementierungen.

(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)
Aaron Harris
quelle
Würde dies nicht das Verhalten der Funktionen ändern, die sich in meiner benutzerdefinierten Funktion (nur) anders verhalten sollen?
Shackra
Ja, ist das nicht was du willst?
Aaron Harris
Nun, nicht genau, das Verhalten beider Befehle überall zu ändern, ist etwas, mit dem ich mich nicht wohl fühle :(
Shackra
1
Ich glaube, ich habe Ihren früheren Kommentar dann falsch verstanden. Die einzigen umgangenen Eingabeaufforderungen sind die im umschlossenen Funktionsaufruf enthaltenen. Zur Verdeutlichung habe ich der Antwort ein Verwendungsbeispiel hinzugefügt.
Aaron Harris
1
Das Folgende erreicht im Grunde das Gleiche und ist meiner Meinung nach eine gute Alternative:(flet ((yes-or-no-p (prompt) t) (y-or-n-p (prompt) t)) body...)
Clemera