Is it possible to read user input from STDIN while tangling a source block with org-babel-tangle
?
I am aware of this: Org Mode Babel - Interactive code block evaluation.
That doesn't help solve this particular use-case, as it still doesn't allow proper STDIN input from shell, but only simulates a limited input internally to Emacs.
Background
I would like to use Org's Babel to learn new programming languages (Perl and Bash) by executing some tutorials from one org file.
The problem is that many tutorials rely on STDIN. For example, if one runs the following perl tidbit:
#+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 will not wait for the user's interaction to properly type a name on STDIN, and it will immediately output:
#+RESULTS:
: What is your name?
: Hello , how are you?
Same thing using a bash example. This:
#+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
Will not wait for user input, and Emacs will immediately return this:
#+RESULTS:
: TEST_DIR was not set, please enter the path:
Is there a native way for Emacs to wait for input on an executing tangled block?
If not, would you please give some pointers on how to write something like a tangle-and-run-via-shell-buffer
function that would:
- Tangle the code block at point, saving with given filename,
- execute the corresponding file in a visible
shell
buffer, - possibly accepting input from the user,
- and finally reporting
STDOUT
, if any, to#+RESULTS:
?
If such feature is not implemented (yet) in Org, how could one implement it with elisp?
Update: After searching and studying more the Emacs and elisp manuals, it seems the way to do it would be leveraging Comint, like perhaps make-comint-in-buffer
.
(make-comint-in-buffer "*cmd-buffer*" nil "perl" nil "hello-name.pl")
Unfortunately, that is over my head right now 😣