Async stdin Lines gets interrupted by concurrent stdout

I have a program that reads from an async_std::io::stdin wrapped in a async_std::io::BufReader line-by-line (via Lines). When a user typed input into the console, a parallel println! may print out to the console. When this happens, any input already placed into the terminal gets chopped-off, and the only thing that gets read as a line is everything after the last stdout. How can I ensure that a concurrent call to stdout won't chop-off console input?

I'd recommend looking into either "readline-like" crates, or TUIs. Both solve this problem, in slightly different ways.

Readline (and readline-like things, like rustyline or copperline) solve this by maintaining an advanced prompt under all output, and implement extra features like command history. I wasn't able to get rustyline nor copperline to actually solve this problem well, but it's something to look at. I know at least, generally, "readline-like" libraries in other languages have solved this well, and it should be similarly possible in Rust.

The other option would be to go full-on TUI, which would mean using a crate like cursive to control the way the entire terminal is displayed. It... might be able to do less than that and properly only edit the bottom line, but the regular mode of operation is replacing the terminal's regular line-based output with manually controlling where every pixel goes. It's possible to make really nice apps using this, and it should also be possible to use for simultaneous input/output, since you'd be controlling everything.

I don't have a good single solution here, but hopefully this info is helpful! And maybe someone else here has a fuller solution?

1 Like

Generally I do not recommend using async IO for interactive terminal IO. Spawn a thread and use blocking IO through a library like those @daboross suggested. Then use message passing to communicate with the terminal IO thread.

The places where async terminal IO makes more sense is for IPC and piping and such.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.