use crossterm::{
ExecutableCommand, cursor,
terminal::{self, ClearType},
};
use std::io::{self, Write};
pub fn strip_reprex_output(input: &str) -> String {
input
.lines()
.filter(|line| !line.starts_with("#>"))
.collect::<Vec<_>>()
.join("\n")
}
pub fn clear_input_lines(original: &str, display: &str) {
let mut stdout = io::stdout();
let line_count = original.lines().count().max(1);
let _ = stdout.execute(cursor::MoveUp(line_count as u16));
for _ in 0..line_count {
let _ = stdout.execute(terminal::Clear(ClearType::CurrentLine));
let _ = stdout.execute(cursor::MoveDown(1));
}
let _ = stdout.execute(cursor::MoveUp(line_count as u16));
println!("{}", display);
let _ = stdout.flush();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strip_single_output_line() {
let input = "x <- 1 + 1\nx\n#> [1] 2";
let result = strip_reprex_output(input);
assert_eq!(result, "x <- 1 + 1\nx");
}
#[test]
fn test_strip_multiple_output_lines() {
let input = "1:3\n#> [1] 1 2 3\nmean(1:3)\n#> [1] 2";
let result = strip_reprex_output(input);
assert_eq!(result, "1:3\nmean(1:3)");
}
#[test]
fn test_no_output_lines() {
let input = "x <- 1\ny <- 2\nz <- x + y";
let result = strip_reprex_output(input);
assert_eq!(result, input);
}
#[test]
fn test_only_output_lines() {
let input = "#> [1] 1\n#> [1] 2";
let result = strip_reprex_output(input);
assert_eq!(result, "");
}
#[test]
fn test_empty_input() {
let result = strip_reprex_output("");
assert_eq!(result, "");
}
#[test]
fn test_preserves_regular_comments() {
let input = "# This is a comment\nx <- 1\n#> [1] 1";
let result = strip_reprex_output(input);
assert_eq!(result, "# This is a comment\nx <- 1");
}
#[test]
fn test_output_with_spaces_after_prefix() {
let input = "x\n#> [1] 1";
let result = strip_reprex_output(input);
assert_eq!(result, "x");
}
#[test]
fn test_multiline_output() {
let input = "1:10\n#> [1] 1 2 3 4 5 6 7 8 9 10";
let result = strip_reprex_output(input);
assert_eq!(result, "1:10");
}
#[test]
fn test_preserves_hash_in_strings() {
let input = "\"#> not output\"\n#> [1] \"#> not output\"";
let result = strip_reprex_output(input);
assert_eq!(result, "\"#> not output\"");
}
}