How to robustly interact with the REPL from outside a Julia process?

I want to make automated recordings of REPL activity with asciinema. Normally one would start julia via asciinema, interact with the REPL and then exit. But I want to write out all pressed keys programmatically. My first problem is that if I had an open julia process, I could maybe write to its stdin to simulate interaction but I don’t really know when one REPL command is done. I don’t want to send all input at once as it’s supposed to look like a human does it. I don’t want to resort to hacks like checking the stdout for strings like julia> to determine if the REPL is ready for input. Can I set up a fake REPL that I can use in a worker process, for example with Malt.jl, that I can send input to and check when it returns so I can send the next command? The visual outputs of this setup should be the same as if equivalent keystrokes were sent in a normal Julia REPL session.

2 Likes

This is only a partial solution to your request, but I once did a similar thing, using GNU Screen to programmatically send keystrokes to the process I wanted to record (Emacs, in my case) within asciinema.

In your case, the gist of it would be to start the Julia REPL in a named screen session:

shell$ screen -S my_julia_session julia

and then from anywhere else, you can send keystrokes to it via a screen’s stuff command:

shell$ screen -S my_julia_session -p 0 -X stuff "1+1\n"
shell$ sleep 1
shell$ screen -S my_julia_session -p 0 -X stuff "^D"

With such a technique, you can do fancier things like reading key presses from a file and sending them one by one (with as many screen -X stuff commands), possibly with a small delay between them to simulate human interaction.

However, this technique doesn’t give you any feedback from the julia process, so you can’t know when the REPL is ready. I don’t know of any way to get that information, but hopefully someone will chime in with a more elegant and complete solution.

2 Likes

You could try my GitHub - ericphanson/Asciicast.jl: Easy REPL animations in READMEs, Documenter docs, and more!

(it does not write the input letter-by-letter though…)

4 Likes

The linux utility expect (tcl based, from 1990 or so) is made for this kind of programmatic interactions.

2 Likes

Huh interesting that I didn’t find that when I googled around a bit first! I guess this wouldn’t handle REPL modes like ; or ] though right? For docs it would sometimes be nice to show those as well. But this is already 90% of what I wanted to do I think, even the html output with inline data that I was thinking about… :smiley:

1 Like

No, I don’t think pkg mode works:

julia> using Asciicast

julia> cast"""
       pkg> st
       """
ERROR: LoadError: CastExecutionException: Failed to run `cast` block:
```
pkg> st

```
ERROR: UndefVarError: `pkg` not defined in `Main.____230`

It works the same way as Documenter’s @repl blocks (using their tech to do so), maybe support could be added there. Though I have my own copy of the @repl implementation in order to add the right timing info.