crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.29k stars 280 forks source link

Provide a way to allow running crossterm based applications where stdin and stdout can be retargetted #941

Open mjgarton opened 1 week ago

mjgarton commented 1 week ago

I have a crossterm based application that I'd like to be able to run in scenarios other than directly running in a terminal. One example of this is running as a server based application that users can connect to via ssh.

I have used russh ( https://docs.rs/russh/latest/russh/ ) for ssh with other projects, but I find it hard to combine with crossterm with, because crossterm "hard codes" stdin as the way to get input.

Output is not really a problem, since most (perhaps all) crossterm write operations work with any std::io::Write impl. To make read work currently, I have to modify my application to ignore crossterm events and instead handle input directly from the ssh channel itself. I'm looking for a way to avoid this, so that my crossterm applications can be modified to run with russh much more easily.

If there were some way in crossterm to specify a replacement for stdin ( a user-defined std::io::Read instance) , that might work. Alternatively, a way to "fake" the crossterm events, would allow creating a general purpose russh-crossterm adapter that could easily be reused by various applications.

mjgarton commented 1 week ago

Looking at existing issues, there seems to be some conceptual overlap with https://github.com/crossterm-rs/crossterm/issues/728 and https://github.com/crossterm-rs/crossterm/issues/654 even though they have different goals.

joshka commented 1 week ago

Also see https://github.com/crossterm-rs/crossterm/issues/939 as somewhat related. It deals with piping into a process.

sshelll commented 4 days ago

@mjgarton @joshka Hi~ I've noticed that the issue #939 that opened by me was mentioned here. And I'd like to share some information for you and crossterm~

Recently I've built an lib/bin crate which is like fzf in rust with crossterm. The repo is here: termenu

And I've tried to use this app through ssh to test, it behaves like this:

  1. In my local terminal: image

  2. Through ssh: image

  3. Use ssh -t to run my app in a pseudo interactive env: image

  4. Use ssh directly(failed...): image

I guess the 3rd scenario is very close to what you want to achieve? @mjgarton

I have no experience with russh, but I think the -t flag is the key~