Multiline prompt
This commit is contained in:
parent
c427646e75
commit
489819a28e
@ -27,6 +27,12 @@ pub struct Repl {
|
|||||||
options: ReplOptions,
|
options: ReplOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum PromptStyle {
|
||||||
|
Normal,
|
||||||
|
Multiline
|
||||||
|
}
|
||||||
|
|
||||||
impl Repl {
|
impl Repl {
|
||||||
pub fn new(initial_states: Vec<Box<dyn ProgrammingLanguageInterface>>) -> Repl {
|
pub fn new(initial_states: Vec<Box<dyn ProgrammingLanguageInterface>>) -> Repl {
|
||||||
use linefeed::Interface;
|
use linefeed::Interface;
|
||||||
@ -62,37 +68,73 @@ impl Repl {
|
|||||||
|
|
||||||
fn handle_repl_loop(&mut self) {
|
fn handle_repl_loop(&mut self) {
|
||||||
use linefeed::ReadResult::*;
|
use linefeed::ReadResult::*;
|
||||||
|
let sigil = self.interpreter_directive_sigil;
|
||||||
|
|
||||||
loop {
|
'main: loop {
|
||||||
self.update_line_reader();
|
macro_rules! match_or_break {
|
||||||
match self.line_reader.read_line() {
|
($line:expr) => {
|
||||||
Err(e) => {
|
match $line {
|
||||||
println!("readline IO Error: {}", e);
|
Err(e) => {
|
||||||
break;
|
println!("readline IO Error: {}", e);
|
||||||
},
|
break 'main;
|
||||||
Ok(Eof) | Ok(Signal(_)) => break,
|
|
||||||
Ok(Input(ref input)) => {
|
|
||||||
self.line_reader.add_history_unique(input.to_string());
|
|
||||||
match input.chars().nth(0) {
|
|
||||||
Some(ch) if ch == self.interpreter_directive_sigil => match self.handle_interpreter_directive(input) {
|
|
||||||
Some(directive_output) => println!("<> {}", directive_output),
|
|
||||||
None => (),
|
|
||||||
},
|
},
|
||||||
_ => {
|
Ok(Eof) | Ok(Signal(_)) => break 'main,
|
||||||
for repl_response in self.handle_input(input) {
|
Ok(Input(ref input)) => input,
|
||||||
println!("{}", repl_response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.update_line_reader();
|
||||||
|
let line = self.line_reader.read_line();
|
||||||
|
let input: &str = match_or_break!(line);
|
||||||
|
|
||||||
|
self.line_reader.add_history_unique(input.to_string());
|
||||||
|
let mut chars = input.chars().peekable();
|
||||||
|
let repl_responses = match chars.nth(0) {
|
||||||
|
Some(ch) if ch == sigil => {
|
||||||
|
if chars.peek() == Some(&'{') {
|
||||||
|
let mut buf = String::new();
|
||||||
|
buf.push_str(input.get(2..).unwrap());
|
||||||
|
'multiline: loop {
|
||||||
|
self.set_prompt(PromptStyle::Multiline);
|
||||||
|
let new_line = self.line_reader.read_line();
|
||||||
|
let new_input = match_or_break!(new_line);
|
||||||
|
if new_input.starts_with(":}") {
|
||||||
|
break 'multiline;
|
||||||
|
} else {
|
||||||
|
buf.push_str(new_input);
|
||||||
|
buf.push_str("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.handle_input(&buf)
|
||||||
|
} else {
|
||||||
|
match self.handle_interpreter_directive(input) {
|
||||||
|
Some(directive_output) => println!("<> {}", directive_output),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => self.handle_input(input)
|
||||||
|
};
|
||||||
|
|
||||||
|
for repl_response in repl_responses.iter() {
|
||||||
|
println!("{}", repl_response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_line_reader(&mut self) {
|
fn update_line_reader(&mut self) {
|
||||||
let tab_complete_handler = TabCompleteHandler::new(self.interpreter_directive_sigil, self.get_directives());
|
let tab_complete_handler = TabCompleteHandler::new(self.interpreter_directive_sigil, self.get_directives());
|
||||||
self.line_reader.set_completer(Arc::new(tab_complete_handler)); //TODO fix this here
|
self.line_reader.set_completer(Arc::new(tab_complete_handler)); //TODO fix this here
|
||||||
let prompt_str = format!(">> ");
|
self.set_prompt(PromptStyle::Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_prompt(&mut self, prompt_style: PromptStyle) {
|
||||||
|
let prompt_str = match prompt_style {
|
||||||
|
PromptStyle::Normal => ">> ".to_string(),
|
||||||
|
PromptStyle::Multiline => ">| ".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
self.line_reader.set_prompt(&prompt_str).unwrap();
|
self.line_reader.set_prompt(&prompt_str).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user