I passed the test before, it fails after I do the builtin completion task, then it fails. I think the problem could be how i use crossterm library for the builtin completion. please someone help
remote: [compile] Moved ./.codecrafters/run.sh → ./your_program.sh
remote: [compile] Compilation successful.
remote:
remote: [tester::#QP2] Running tests for Stage #QP2 (Autocompletion - Builtin completion)
remote: [tester::#QP2] Running ./your_program.sh
remote: [tester::#QP2] ✓ Received prompt ($ )
remote: [tester::#QP2] Typed “ech”
remote: [tester::#QP2] ✓ Prompt line matches “$ ech”
remote: [tester::#QP2] Pressed “” (expecting autocomplete to “echo”)
remote: [tester::#QP2] ✓ Prompt line matches “echo”
remote: [your-program] $ echo
remote: [tester::#QP2] Tearing down shell
remote: [tester::#QP2] Running ./your_program.sh
remote: [tester::#QP2] ✓ Received prompt ($ )
remote: [tester::#QP2] Typed “exi”
remote: [tester::#QP2] ✓ Prompt line matches “$ exi”
remote: [tester::#QP2] Pressed “” (expecting autocomplete to “exit”)
remote: [tester::#QP2] ✓ Prompt line matches “exit”
remote: [your-program] $ exit
remote: [tester::#QP2] Tearing down shell
remote: [tester::#QP2] Test passed.
remote:
remote: [tester::#UN3] Running tests for Stage #UN3 (Redirection - Append stderr)
remote: [tester::#UN3] [setup] export PATH=/tmp/grape/banana/mango:$PATH
remote: [tester::#UN3] Running ./your_program.sh
remote: [your-program] $ ls -1 nonexistent >> /tmp/pig/fox.mdj
remote: [tester::#UN3] ^ Line does not match expected value.
remote: [tester::#UN3] Expected: “$ ls -1 nonexistent >> /tmp/pig/fox.md”
remote: [tester::#UN3] Received: “$ ls -1 nonexistent >> /tmp/pig/fox.mdj”
remote: [tester::#UN3] Assertion failed.
remote: [tester::#UN3] Test failed
remote:
and my code
use std::io::{self, Write};
use std::process;
use std::time::Duration;
mod commands;
mod parser;
use commands::{handle_command, Command};
use crossterm::event::{poll, read, Event, KeyCode, KeyEventKind, KeyModifiers};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use parser::parse_command;
pub struct Shell;
impl Shell {
pub fn new() -> Self {
Self
}
pub fn run(&mut self) {
let mut input = String::new();
let available_commands = \["help", "echo", "exit", "ls"\];
enable_raw_mode().unwrap();
loop {
print!("$ ");
io::stdout().flush().unwrap();
loop {
if poll(Duration::from_millis(100)).unwrap() {
if let Event::Key(key_event) = read().unwrap() {
match key_event.code {
KeyCode::Enter => {
if key_event.kind == KeyEventKind::Press {
println!();
break;
}
}
KeyCode::Char('c')
if key_event.modifiers.contains(KeyModifiers::CONTROL) =>
{
disable_raw_mode().unwrap();
process::exit(0);
}
KeyCode::Char(c) => {
if key_event.kind == KeyEventKind::Press {
input.push(c);
print!("{}", c);
io::stdout().flush().unwrap();
}
}
KeyCode::Backspace => {
if key_event.kind == KeyEventKind::Press {
if input.pop().is_some() {
print!("\\x08 \\x08");
io::stdout().flush().unwrap();
}
}
}
KeyCode::Tab => {
if key_event.kind == KeyEventKind::Press {
if let Some(matched) = available_commands
.iter()
.find(|cmd| cmd.starts_with(&input))
{
print!("\\r\\x1B\[2K");
input = matched.to_string();
print!("$ {} ", input);
io::stdout().flush().unwrap();
}
}
}
\_ => {}
}
}
}
}
let trimmed = input.trim();
if trimmed.is_empty() {
continue;
}
match parse_command(&trimmed) {
Some(Command::Exit(code)) => {
disable_raw_mode().unwrap();
process::exit(code);
}
Some(cmd) => handle_command(cmd),
None => println!("{}: command not found", input.trim()),
}
input.clear();
}
}
}