¿Es posible leer la entrada del usuario desde STDIN mientras enreda un bloque fuente con org-babel-tangle
?
Soy consciente de esto: Org Mode Babel - Evaluación de bloque de código interactivo .
Eso no ayuda a resolver este caso de uso en particular, ya que todavía no permite la entrada STDIN adecuada desde el shell, sino que solo simula una entrada limitada internamente a Emacs.
Antecedentes
Me gustaría usar Org's Babel para aprender nuevos lenguajes de programación (Perl y Bash) ejecutando algunos tutoriales desde un archivo de organización.
El problema es que muchos tutoriales dependen de STDIN. Por ejemplo, si uno ejecuta el siguiente tidbit de perl:
#+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 no esperará a que la interacción del usuario escriba correctamente un nombre en STDIN, e inmediatamente mostrará:
#+RESULTS:
: What is your name?
: Hello , how are you?
Lo mismo usando un ejemplo bash. Esta:
#+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
No esperará la entrada del usuario, y Emacs inmediatamente devolverá esto:
#+RESULTS:
: TEST_DIR was not set, please enter the path:
¿Hay una forma nativa para que Emacs espere la entrada en un bloque enredado en ejecución?
Si no es así, ¿podría dar algunos consejos sobre cómo escribir algo como una tangle-and-run-via-shell-buffer
función que:
- Enrede el bloque de código en el punto, guardando con el nombre de archivo dado,
- ejecutar el archivo correspondiente en un
shell
búfer visible , - posiblemente aceptando aportes del usuario,
- y finalmente informar
STDOUT
, si hay alguno, a#+RESULTS:
?
Si dicha característica no está implementada (todavía) en Org, ¿cómo podría implementarse con elisp?
Actualización: después de buscar y estudiar más los manuales de Emacs y elisp, parece que la forma de hacerlo sería aprovechar Comint , como tal vez make-comint-in-buffer
.
(make-comint-in-buffer "*cmd-buffer*" nil "perl" nil "hello-name.pl")
Desafortunadamente, eso está sobre mi cabeza en este momento 😣
tail file |
funciona pero notail -f file |
. Revisaré mis notas y agregaré mi ejemplo multilínea que funciona parcialmente como nueva respuesta. ¡Gracias por el recordatorio!