Czy możliwe jest odczytanie danych wejściowych użytkownika ze STDIN podczas splątania bloku źródłowego org-babel-tangle
?
Mam tego świadomość: Babel Mode Org - Interaktywna ocena bloku kodu .
To nie pomaga rozwiązać tego konkretnego przypadku użycia, ponieważ nadal nie pozwala na prawidłowe wejście STDIN z powłoki, ale tylko symuluje ograniczone wejście wewnętrznie do Emacsa.
tło
Chciałbym użyć Babel Orga do nauki nowych języków programowania (Perl i Bash), wykonując niektóre samouczki z jednego pliku org.
Problem polega na tym, że wiele samouczków opiera się na STDIN. Na przykład, jeśli uruchomimy następujący perl smakołyk:
#+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 nie będzie czekać na interakcję użytkownika, aby poprawnie wpisać nazwę na STDIN i natychmiast wyświetli:
#+RESULTS:
: What is your name?
: Hello , how are you?
To samo na przykładzie bash. To:
#+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
Nie będzie czekać na dane wprowadzone przez użytkownika, a Emacs natychmiast zwróci to:
#+RESULTS:
: TEST_DIR was not set, please enter the path:
Czy istnieje natywny sposób, aby Emacs czekał na dane wejściowe w wykonywanym splątanym bloku?
Jeśli nie, proszę podać kilka wskazówek, jak napisać coś w rodzaju tangle-and-run-via-shell-buffer
funkcji, która:
- Zaplątaj blok kodu w punkcie, zapisując podaną nazwę pliku,
- uruchom odpowiedni plik w widocznym
shell
buforze, - ewentualnie przyjmowanie danych wejściowych od użytkownika,
- i wreszcie
STDOUT
, jeśli w ogóle, zgłaszanie się do#+RESULTS:
?
Jeśli taka funkcja nie jest (jeszcze) zaimplementowana w organizacji, jak można ją zaimplementować za pomocą elisp?
Aktualizacja: po przeszukaniu i przestudiowaniu podręczników Emacsa i elisp wydaje się, że można to zrobić, wykorzystując Comint , na przykład make-comint-in-buffer
.
(make-comint-in-buffer "*cmd-buffer*" nil "perl" nil "hello-name.pl")
Niestety, to jest teraz nad moją głową 😣