我正在用 Rust 编写一个带有经典的基于终端的 REPL 环境项目的最小 Lisp。
如何从箭头键读取用户输入,允许他们至少在按下 之前在当前输入行上来回移动enter?理想情况下,我将能够扩展功能,包括“返回”以检索旧输入,就像在任何终端或任何 REPL 中一样。为了清楚起见,下面是该行为的图像:
我已经使用了标准库的io模块和termion板条箱,但还没有弄清楚这个功能。
这是我当前的工作代码。它有效地获取输入并立即将其打印回给用户,此外还按预期退出quit()。
use std::io::prelude::*;
use std::io;
fn main() {
println!("Rispy Version 0.0.1");
println!("Enter `quit()` to Exit");
let mut input: String;
// continuous input til ctrl-c or quit()
loop {
print!("rispy>> ");
io::stdout().flush().unwrap();
input = String::new();
io::stdin().read_line(&mut input)
.expect("Error reading line");
print!("input: {}", input);
match input.as_ref() {
"quit()\n" => {
println!("\nGoodbye");
break;
},
_ => continue,
}
}
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,在其他地方没有更容易地建议一些基本/基本的板条箱来解决这样的问题,但值得庆幸的是@kazemakase通过建议一个我到目前为止还没有找到的板条箱来回答这个问题:rustyline
对自述文件中的示例代码进行轻微编辑即可产生我想要的结果,包括历史记录、使用箭头键向左/向右导航的能力,甚至可以使用 ctrl-d、ctrl-c、home 等按键。这是与所提出的问题相结合的:
extern crate rustyline;
use rustyline::Editor;
use rustyline::error::ReadlineError;
fn main() {
println!("Rispy Version 0.0.1");
println!("Enter `quit()` to Exit");
let mut reader = Editor::<()>::new();
if let Err(_) = reader.load_history("rispy_history.txt") {
println!("No previous history.");
}
// continuous input
loop {
let readline = reader.readline("rispy>> ");
match readline {
Ok(line) => {
reader.add_history_entry(&line);
println!("input: {}", line);
},
Err(ReadlineError::Interrupted) => {
println!("CTRL-C");
println!("Goodbye");
break
}
Err(ReadlineError::Eof) => {
println!("CTRL-D");
println!("Goodbye");
break
},
Err(err) => {
println!("Error: {:?}", err);
break
}
}
}
reader.save_history("rispy_history.txt").unwrap();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1620 次 |
| 最近记录: |