Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse std::process::Child stdout #354

Open
AustinScola opened this issue Oct 9, 2022 · 0 comments
Open

Parse std::process::Child stdout #354

AustinScola opened this issue Oct 9, 2022 · 0 comments

Comments

@AustinScola
Copy link

Hi,

I am developing a TUI program and one of the features is that I can open vim for any file. The problem is that vim outputs some ANSI escape codes that I would like to strip out (the enable and disable alternative screen codes). I'm trying to use combine to do so but am running into some difficulty and was wondering if I could get some guidance.

Here is what I current have:

  • I spawn vim as a std::process::Child
  • I wrap the child's stdout in a std::io::BufReader
  • I read from the buffer one byte at a time and create a ParitalStream with it
    • Reading one byte at a time probably isn't the best way to do this?
  • I then use parse_with_state on my parser

I can't seem to get this approach to compile b/c of some lifetime errors. Is this the right approach or is there a better way to do this w/ combine?

Here is a snippet of the code I described above:

let command_stdout: ChildStdout = child.stdout.take().unwrap();
let mut reader: BufReader<ChildStdout> = BufReader::new(command_stdout);
let mut buffer: [u8; 1] = [0; 1];

let mut stdout = io::stdout().lock();
let mut parser = any_partial_state(ansi_escaped_text::parser());
let mut parser_state = AnyPartialState::default();
let mut length: usize;
loop {
    length = {
        reader.read(&mut buffer).unwrap()
    };
    if length == 0 {
        break;
    }

    #[cfg(feature = "logging")]
    debug!("Got output {:?} from vim.", &buffer[..length]);

    // Parse the text so that we can strip out the ANSI escape codes for enabling and
    // disabling the alternative screen.
    let mut stream = PartialStream(&buffer[..]);
    let parsed_text = parser.parse_with_state(&mut stream, &mut parser_state);
    match parsed_text {
        Ok(ansi_escaped_text) => {
            match ansi_escaped_text {
                ANSIEscapedText::ANSIEscapeCode(ansi_escape_code) => {
                    match ansi_escape_code {
                        ANSIEscapeCode::EnableAlternativeScreen => {
                            #[cfg(feature = "logging")]
                            debug!("Stripping enable alternative screen ANSI escape code from vim's output.");
                        },
                        ANSIEscapeCode::DisableAlternativeScreen => {
                            #[cfg(feature = "logging")]
                            debug!("Stripping disable alternative screen ANSI escape code from vim's output.");
                        }
                    }
                },
                ANSIEscapedText::Character(character) => {
                    stdout.write(&[character]).unwrap();
                    stdout.flush().unwrap();
                }
            };
        },
        #[cfg(feature = "logging")]
        Err(error) => {
            error!("Failed to parse ANSI escaped text: {:?}", error);
        },
        #[cfg(not(feature = "logging"))]
        Err(_) => {},
    };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant