¿Cómo responder programáticamente "sí" a esos comandos que solicitan una decisión del usuario?

8

Hice una función personalizada que combina dos funciones de modo piar , twittering-favoritey twittering-native-retweet, sin embargo, estas dos necesidades de entrada de mí, respondiendo a una pregunta de sí o no.

Quiero saber si hay una manera de envolver esas dos funciones con algo que les haga recibir una respuesta sin mi intervención directa.

Shackra
fuente
8
No uso twittering-mode(y no me molestaré en acceder al código), pero como un consejo general: normalmente, en lugar de hacer lo que sugiere (hacer un código que simule la respuesta de un usuario yes), es mejor hacer un código que utiliza directamente el código que espera la respuesta. IOW, intente aprovechar la ruta del código fuente que yesprovocaría que se invocara una respuesta. (Solo una sugerencia.)
Dibujó el
El título es engañoso ya que esto no se puede hacer correctamente de manera genérica.
wasamasa

Respuestas:

7

EDITAR: Como @hatschipuh señaló en los comentarios, una fletconstrucción de tipo es más sencilla y no se basa en mi macro de consejos idiosincrásicos. Al menos en mi Emacs (24.5.1), cl-fletutiliza el alcance léxico, por lo que necesitará el nofletpaquete para que funcione el siguiente fragmento. Desplácese hacia abajo para obtener la respuesta idiosincrásica original.

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

EDITAR: Esta es la respuesta original, excepto que lo arreglé my/bypass-confirmation-allpara trabajar como se anuncia y cambié un poco las convenciones de llamadas.

Aquí hay un contenedor general que debería funcionar para cualquier función.

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

Este código depende de esta macro, que parece ser mi solución para todo en 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))))

Si este código es la forma más inteligente de manejar esta situación, no lo sé. En general, me gusta usar este tipo de consejos temporales para hacer modificaciones de las funciones existentes en lugar de duplicar el código de las funciones originales, en parte porque ayuda a proteger su función modificada en el futuro contra cambios no relacionados en el original. Pero en este caso, es posible que tenga que tener cuidado adicional, porque si twittering-modeactualiza y cambia los mensajes o agrega uno adicional, no verá los cambios. Dado que un indicador de y-n indica una elección controvertida, eso podría tener consecuencias desafortunadas.


EDITAR: Se me ocurrió que un ejemplo de uso podría ser útil. Este ejemplo funciona con cualquier implementació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)
Aaron Harris
fuente
¿No modificaría esto el comportamiento de las funciones que me gustaría que se comportaran de manera diferente (solo) dentro de mi función personalizada?
shackra
Sí, ¿no es eso lo que quieres?
Aaron Harris
Bueno, no exactamente, cambiar el comportamiento de ambos comandos en todas partes es algo con lo que no me siento cómodo :(
shackra
1
Creo que he leído mal tu comentario anterior, entonces. Las únicas indicaciones que se omiten son las que se encuentran dentro de la llamada de función ajustada. Para ayudar a aclarar, agregué un ejemplo de uso a la respuesta.
Aaron Harris
1
Lo siguiente logra básicamente lo mismo y creo que es una buena alternativa:(flet ((yes-or-no-p (prompt) t) (y-or-n-p (prompt) t)) body...)
clemera