Executing vim from rust trashes terminal


I’m trying to execute vim (or any interactive commandline program/editor) from rust but that leaves the terminal trashed… I’m not sure how to do it properly (I’m sure it can be done).

My setup is a bit unusual, so I’ll explain it here:

  • User executes echo foo | imag edit -I
  • The imag binary finds “edit” as command and executes imag-edit, passing all parameters
  • imag-edit finds the -I parameter which means it should read the path of the file to edit from stdin
  • imag-edit reads from stdin. It reads some/path/foo, copies its content to a temporary file
  • imag-edit opens vim on that temporary file
  • after vim is closed, imag-edit reads the temp file and writes its contents back to the original file.

Somewhere in this process something works not as intended and vim leaves the terminal trashed.

  • The Command building in the imag binary is located here
  • The Command building for the editor is located here (if I change the stdin to be inherited, that does not help and the same trashing of terminal happens)
  • The imag-edit reading from commandline is located here
  • The calling of the editor command is located here

I’m not sure what the actual issue is. I inherit stdin everywhere (if I do it in libimagrt it does not work either, as stated above)… so either that is wrong or I’m missing something.

I’m a bit at loss and would appreciate some help.

Edit: Related issue here

When you do echo foo | some-prog, then some-prog’s stdin will be the stdout pipe from the echo command. Try pointing stdin (and stdout) to /dev/tty instead.

And how do you do that with ::std::process::Command?

This issue still exists, would be awesome if someone could help me here.

Apologies for being terse, as I am on my phone. (Note: haven’t tried it)


In short:

  • File can open special files
  • Stdio impls From<File>
  • Command::stdin takes anything that can convert into Stdio

Edit: thanks autocorrect

1 Like

Beware that /dev/tty is on #[cfg(unix)] platforms only. I’m not sure what Windows would use (edit: probably CON), but abstracting this could be the start of a new crate…

1 Like

Awesome, the File::open("/dev/tty") thing works!

I guess the “new crate”-idea would be a good thing for the CLI working group, right?