Est-il possible de lire les entrées utilisateur de STDIN tout en emmêlant un bloc source avec org-babel-tangle
?
J'en suis conscient: Org Mode Babel - Évaluation interactive des blocs de code .
Cela n'aide pas à résoudre ce cas d'utilisation particulier, car il ne permet toujours pas une entrée STDIN appropriée à partir du shell, mais simule uniquement une entrée limitée en interne pour Emacs.
Contexte
Je voudrais utiliser Babel d'Org pour apprendre de nouveaux langages de programmation (Perl et Bash) en exécutant quelques tutoriels à partir d'un seul fichier org.
Le problème est que de nombreux didacticiels reposent sur STDIN. Par exemple, si l'on exécute le tlbit perl suivant:
#+BEGIN_SRC perl :tangle hello-name.pl :results output :export code
use 5.010;
use strict;
use warnings;
say "What is your name?";
my $name=<STDIN>;
say "Hello $name, how are you?";
#+END_SRC
Emacs n'attendra pas l'interaction de l'utilisateur pour taper correctement un nom sur STDIN, et il affichera immédiatement:
#+RESULTS:
: What is your name?
: Hello , how are you?
Même chose en utilisant un exemple bash. Ce:
#+BEGIN_SRC sh :results output :export code :tangle dir-input.sh
#!/bin/bash
if [ -z "$TEST_DIR" ]
then
echo "TEST_DIR was not set, please enter the path: "
read input_variable
export TEST_DIR=$input_variable
fi
#+END_SRC
N'attendra pas la saisie de l'utilisateur et Emacs retournera immédiatement ceci:
#+RESULTS:
: TEST_DIR was not set, please enter the path:
Existe-t-il un moyen natif pour Emacs d'attendre l'entrée sur un bloc enchevêtré en cours d'exécution?
Sinon, pourriez-vous donner quelques conseils sur la façon d'écrire quelque chose comme une tangle-and-run-via-shell-buffer
fonction qui:
- Enchevêtrer le bloc de code au point, en enregistrant avec le nom de fichier donné,
- exécuter le fichier correspondant dans un
shell
tampon visible , - acceptant éventuellement une entrée de l'utilisateur,
- et enfin de signaler
STDOUT
, le cas échéant, à#+RESULTS:
?
Si une telle fonctionnalité n'est pas (encore) implémentée dans Org, comment pourrait-on l'implémenter avec elisp?
Mise à jour: Après avoir recherché et étudié davantage les manuels Emacs et elisp, il semble que la façon de le faire serait de tirer parti de Comint , comme peut-être make-comint-in-buffer
.
(make-comint-in-buffer "*cmd-buffer*" nil "perl" nil "hello-name.pl")
Malheureusement, c'est au-dessus de ma tête en ce moment 😣
tail file |
fonctionne mais pastail -f file |
. Je vais parcourir mes notes et ajouter mon exemple multiligne partiellement fonctionnel comme nouvelle réponse. Merci pour rappel!