Comment puis-je répondre à une invite de mini-tampons d'elisp?

10

Je me retrouve parfois à utiliser des fonctions interactives à l'intérieur d'une fonction que j'écris pour mon propre usage. Si une fonction demande des informations (par exemple, "Fichier de sortie: ~ /"), existe-t-il une manière générale et simple d'ajouter du texte au mini-tampon, puis d'appuyer sur Entrée pour que l'utilisateur n'ait pas à le faire?

Par exemple, supposons que je souhaite exécuter à l' org-latex-export-to-pdfintérieur d'une fonction mais je ne veux pas que l'utilisateur doive spécifier un nom de fichier. Courir (org-latex-export-to-pdf)déplacera le point vers le mini-tampon, mais mettre quelque chose comme (insert "filename.tex")sur la ligne suivante ne semble pas fonctionner.

Seth Rothschild
la source
3
En règle générale, une fonction interactive doit demander ces informations dans sa interactiveclause. Lorsqu'il est appelé depuis elisp, votre devrait pouvoir transmettre les informations en tant qu'argument de fonction. Bien sûr, cela ne vous aide pas, au cas où la fonction que vous essayez d'appeler ne suit pas cette conception.
Lindydancer
Oui, j'ai trouvé que c'était aussi le cas généralement (malheureusement pas pour le moment), ce qui pourrait expliquer pourquoi la réponse à cette question a été si difficile à trouver. Savez-vous s'il y a une raison de vouloir vraiment que l'utilisateur tape des réponses aux invites du mini-tampon?
Seth Rothschild
Votre commentaire n'est pas clair pour moi. Voulez-vous que l'utilisateur soit interrogé et qu'il réponde ou non? Si ce n'est pas le cas, définissez par programme les valeurs d'argument (nom du fichier de sortie) que vous voulez / besoin et passez-les à la fonction. Je vous suggère de montrer du code ou d'une autre manière de préciser et de préciser votre problème et votre question , ou la question risque d'être fermée car peu claire.
Drew
Je ne veux pas que l'utilisateur (moi) soit interrogé. Je peux clarifier la question. Après avoir lu une partie d'un fil de discussion vous impliquant il y a quelques années à propos de tirer sur le mini-tampon, je pense que je sais comment faire. Si je le fais fonctionner, je l'écrirai.
Seth Rothschild
1
Veuillez poster un exemple spécifique d'une fonction interactive que vous souhaitez utiliser lors de l'écriture de votre propre fonction, afin qu'un autre participant au forum puisse montrer comment passer un argument à la fonction et contourner entièrement le mini-tampon.
Lawlist

Réponses:

3

Problème intéressant. On dirait que l'éditeur s'exécute à post-command-hookchaque fois qu'il entre dans une nouvelle boucle de commande, c'est-à-dire a recursive-edit. Mais nous pouvons commencer par minibuffer-setup-hook, qui exécute une fonction après avoir entré le mini-tampon. Bien que cela permette l'insertion d'une entrée, il est trop tôt pour quitter le mini-tampon, car la capture n'a pas encore été configurée.

(defmacro with-minibuffer-input (form &rest inputs)
  (declare (indent 1))
  `(minibuffer-with-setup-hook
       (lambda ()
         (minibuffer-input-provider ',inputs))
     ,form))

C'est là que nous devons encapsuler les `` arguments '' dans notre propre `` boucle de commande '', qui est exécutée chaque fois que nous entrons dans a recursive-edit, auquel cas il affiche un argument et lève un niveau, via exit-minibuffer.

;; -*- lexical-binding: t -*-
(defun minibuffer-input-provider (inputs)
  (let ((hook (make-symbol "hook")))
    (fset hook (lambda ()
                 (remove-hook 'post-command-hook hook)
                 (when inputs
                   (when (= 0 (minibuffer-depth))
                     (error "Too many inputs"))
                   (when (cdr inputs)
                     (add-hook 'post-command-hook hook))
                   (insert (pop inputs))
                   (exit-minibuffer))))
    (add-hook 'post-command-hook hook)))


(with-minibuffer-input (call-interactively 'find-file)
  "/")

(with-minibuffer-input (call-interactively 'occur)
  "\\(foo\\)\\(bar\\)" "\\1");;C-u C-x C-e

;;foobar

(with-minibuffer-input (call-interactively 'replace-string)
  "foo" "bar")

;; foo
politza
la source
3

J'ai écrit une macro pour cela appelé with-simulated-input, que vous pouvez obtenir ici . Il vous permet de fournir des entrées arbitraires ainsi que d'exécuter des formulaires lisp arbitraires afin de simuler l'interaction de l'utilisateur.

Par exemple:

(with-simulated-input '("hello SPC" (insert "world") "RET")
  (read-string "Enter greeting: "))

retournerait "hello world", avec le "bonjour" inséré par la première chaîne, le "monde" inséré via le code lisp, et enfin "RET" pour terminer l'entrée.

Il est livré avec une suite de tests que vous pouvez consulter pour plus d'exemples d'utilisation.

Ryan C. Thompson
la source
0

Il semble que l'utilisation de run-with-timeravec insertfera le travail.

(run-with-timer .2 nil 'insert "filename.tex")
(run-with-timer .3 nil 'execute-kbd-macro (kbd "RET"))
(org-latex-export-to-pdf)

La commande, insertplacée après, arrive trop rapidement. Il essaie d'insérer la chaîne avant qu'il n'y ait un endroit pour l'insérer.

Seth Rothschild
la source
Je recommanderais de réviser votre question pour demander de l'aide en passant un nom de fichier par programme org-export-output-file-namelors de l'utilisation org-latex-export-to-pdfafin que l'utilisateur ne soit pas invité à entrer le nom de fichier. Vous pouvez mettre vos efforts dans la question - par exemple, run-with-timeretc. - mais ce n'est pas une bonne solution (à mon avis). La meilleure solution consiste à transmettre correctement un nom de fichier par programmation afin que le mini-tampon ne s'ouvre jamais en premier lieu. Je recommanderais de supprimer cette réponse afin que vous obteniez une meilleure solution par quelqu'un ayant plus d' elispexpérience.
Lawlist
@lawlist la question de savoir comment transmettre un nom de fichier org-latex-export-to-pdfn'est pas celle qui m'intéresse. C'est un exemple puisque vous sembliez déterminé à ce que j'en ajoute un. La question que j'ai posée est celle que je voulais dire: existe-t-il un moyen de répondre de manière fiable à une invite de mini-tampon via elisp. Une solution au cas par cas n'est pas du tout ce que je recherche. D'après votre commentaire, je peux déduire que ce n'est pas recommandé.
Seth Rothschild