我正在尝试构建一个简单的 cli discord 克隆,并且有一个用户输入提示。
我的问题是,直到我在提示我输入的消息上按 Enter 键后,提示才会呈现:
pub fn prompt(msg: &str, clear_line: bool) -> String {
let mut input = String::new();
print!("{}", msg);
std::io::stdout().flush().unwrap();
std::io::stdin().read_line(&mut input).unwrap();
// if clear_line {
// print!("\033[F{}\r", " ".repeat(input.len() + msg.len() + 4));
// std::io::stdout().flush().unwrap();
// };
input.trim().to_string()
}
我知道在打印宏之后使用
stdout().flush()
应该将缓冲区刷新到终端并渲染文本,但在等待用户输入之后似乎不会这样做。
有谁知道这可能是什么原因造成的?
(我已经在 VS Code 终端中尝试过,使用 bash 和 Fish shell 来 alacritty,所以我很确定这不是我的终端很奇怪)
我设法解决了这个问题,但这有点令人头疼,几乎所有其他文本都在顶部呈现,该项目基本上有一个系统,每当服务器上的表更新时,它就会向服务器发送消息,它会触发客户端中的回调,该回调会中断程序并将某些内容打印到屏幕上(我假设这在单独的线程或其他线程中运行,但这不相关)。每次我的函数将输入发送回客户端并重写提示时,提示都会被响应覆盖,
解决方案:在提示之前添加一个小的延迟,以便在服务器响应之前很可能不会呈现提示(我的延迟为 50 毫秒,但可能会增加到 250 左右,以考虑到更高延迟的用户,或者可能制作自定义解决方案,idk)
pub fn prompt(msg: &str, clear_line: bool) -> String {
std::thread::sleep(core::time::Duration::from_millis(50));
let mut input = String::new();
print!("{}", msg);
std::io::stdout().flush().unwrap();
std::io::stdin().read_line(&mut input).unwrap();
if clear_line {
print!("\x1b[1A\x1b[2K");
std::io::stdout().flush().unwrap();
};
input.trim().to_string()
}
这是我正在使用的库在单独的线程中调用我的代码:
pub fn render_message(message: &Event) {
let username = username_from_identity(&message.sender);
let timestamp = render_timestamp(message.sent);
let Some(message) = &message.event else {
return
};
match message {
EventType::Message(text) => {
println!("{} {} :: {}", timestamp, username, text);
},
EventType::Namechange(change) => {
println!("{} {} => {} <changed name>", timestamp, change.old_name, change.new_name);
},
_ => return, // TODO: implement other event types
};
//let channel = render_channel(message.channel_id);
}
无论如何,谢谢你的建议,我没想到会在堆栈溢出上发表我的第一篇文章,并且没有得到任何有毒的反应 XD