Come rispondere programmaticamente "sì" a quei comandi che richiedono una decisione da parte dell'utente?


8

Ho fatto una funzione personalizzata che combina due funzioni di cinguettio-mode , twittering-favoritee twittering-native-retweet, tuttavia questi due esigenze di input da me per rispondere a una domanda sì o no.

Voglio sapere se c'è un modo per avvolgere quelle due funzioni con qualcosa che le farà ricevere una risposta senza il mio intervento diretto.


8
Non uso twittering-mode(e non mi preoccuperò di accedere al codice), ma come consiglio generale: in genere, invece di fare ciò che suggerisci (crea codice che simula la risposta di un utente yes) è meglio creare codice che utilizza direttamente il codice che prevede la risposta. IOW, prova a sfruttare il percorso del codice sorgente che yespotrebbe essere invocata una risposta. (Solo un suggerimento.)
Estratto il

Il titolo è fuorviante in quanto non può essere fatto correttamente in modo generico.
Wasamasa,

Risposte:


7

EDIT: Come sottolineato da @hatschipuh nei commenti, una fletcostruzione di tipo è più semplice e non si basa sulla mia macro di consigli idiosincratici. Almeno su my Emacs (24.5.1), cl-fletusa l'ambito lessicale, quindi avrai bisogno del nofletpacchetto per far funzionare il seguente frammento. Scorri verso il basso per la risposta originale, idiosincratica.

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

EDIT: Questa è la risposta originale, tranne per il fatto che ho riparato my/bypass-confirmation-allper funzionare come pubblicizzato e ho cambiato un po 'le convenzioni di chiamata.

Ecco un wrapper generale che dovrebbe funzionare per qualsiasi funzione.

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

Questo codice dipende da questa macro, che sembra essere la mia soluzione ideale per tutto su 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))))

Non so se questo codice sia il modo più intelligente per gestire questa situazione. In generale, mi piace usare questo tipo di consiglio temporaneo per apportare modifiche alle funzioni esistenti invece di duplicare il codice delle funzioni originali, in parte perché aiuta a rendere la tua funzione modificata a prova di futuro contro cambiamenti non correlati all'originale. Ma in questo caso potrebbe essere necessario prestare particolare attenzione, perché se twittering-modeaggiorna e modifica le istruzioni o ne aggiunge una aggiuntiva, non vedrai le modifiche. Poiché un prompt y-or-n indica una scelta controversa, ciò potrebbe avere conseguenze sfavorevoli.


EDIT: mi è venuto in mente che un esempio di utilizzo potrebbe essere utile. Questo esempio funziona con entrambe le implementazioni.

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

Ciò non modificherebbe il comportamento delle funzioni che vorrei comportarmi diversamente (solo) all'interno della mia funzione personalizzata?
Shackra,

Sì, non è quello che vuoi?
Aaron Harris il

Beh, non esattamente, cambiare il comportamento di entrambi i comandi ovunque è qualcosa con cui non mi sento a mio agio :(
shackra,

1
Penso che potrei aver letto male il tuo commento precedente, quindi. Le uniche istruzioni ignorate sono quelle all'interno della chiamata di funzione incartata. Per chiarire, ho aggiunto un esempio di utilizzo alla risposta.
Aaron Harris,

1
Quanto segue raggiunge sostanzialmente lo stesso ed è una buona alternativa penso:(flet ((yes-or-no-p (prompt) t) (y-or-n-p (prompt) t)) body...)
Clemera,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.