rustyline 如何为多行输入显示续行提示符?
数据阿明
结论
rustyline 没有专门设置只读续行提示符的参数。readline() 接收一个提示符。若用 Cmd::Insert 在换行后插入 > ,这段文本会进入输入缓冲区,用户可以编辑它,返回的字符串中也会包含它。当前 crate 的功能列表没有列出内置的续行提示符功能,Editor::readline 文档也说明,提示符通过该方法传入。
如果可以接受续行前缀属于缓冲区的一部分,可以将 ^J 绑定为插入换行和前缀,并在读取完成后移除每个后续行开头的前缀:
use rustyline::{
Cmd, DefaultEditor, Event::KeySeq, EventHandler::Simple, KeyEvent, Modifiers,
};
const CONTINUATION_PROMPT: &str = "> ";
fn main() -> rustyline::Result<()> {
let mut rl = DefaultEditor::new()?;
rl.bind_sequence(
KeySeq(vec![KeyEvent::new('j', Modifiers::CTRL)]),
Simple(Cmd::Insert(
0,
format!("\n{CONTINUATION_PROMPT}"),
)),
);
loop {
match rl.readline(">> ") {
Ok(input) => {
let input = input
.lines()
.enumerate()
.map(|(index, line)| {
if index == 0 {
line
} else {
line.strip_prefix(CONTINUATION_PROMPT).unwrap_or(line)
}
})
.collect::<Vec<_>>()
.join("\n");
dbg!(input);
// 处理多行输入
}
Err(_) => break,
}
}
Ok(())
}
Cmd::Insert 会把 \n> 插入当前编辑缓冲区。处理输入时,代码只尝试移除后续行开头的 > ,首行内容不会被删除。
需要注意的限制
插入的前缀不是只读的。用户移动光标或删除字符时,可能会改动提示符;如果用户在续行开头输入了相同的前缀,清理时也可能将其移除。这个方案适用于交互规则简单、能够接受这些限制的 REPL。
如果续行提示符必须保持只读,并且不受光标操作影响,单靠 Cmd::Insert 无法实现。此时需要自定义终端绘制和编辑行为,或使用提供独立续行提示符的输入组件。具体可行的 API 取决于所用的 rustyline 版本。
备注:内容仅供参考。
