| extern crate log; |
| extern crate rustyline; |
| |
| use std::io::{self, Write}; |
| use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError}; |
| |
| use rustyline::completion::FilenameCompleter; |
| use rustyline::error::ReadlineError; |
| use rustyline::{Config, CompletionType, Editor, EditMode}; |
| |
| // On unix platforms you can use ANSI escape sequences |
| #[cfg(unix)] |
| static PROMPT: &'static str = "\x1b[1;32m>>\x1b[0m "; |
| |
| // Windows consoles typically don't support ANSI escape sequences out |
| // of the box |
| #[cfg(windows)] |
| static PROMPT: &'static str = ">> "; |
| |
| fn main() { |
| init_logger().is_ok(); |
| let config = Config::builder() |
| .history_ignore_space(true) |
| .completion_type(CompletionType::List) |
| .edit_mode(EditMode::Emacs) |
| .build(); |
| let c = FilenameCompleter::new(); |
| let mut rl = Editor::with_config(config); |
| rl.set_completer(Some(c)); |
| if rl.load_history("history.txt").is_err() { |
| println!("No previous history."); |
| } |
| loop { |
| let readline = rl.readline(PROMPT); |
| match readline { |
| Ok(line) => { |
| rl.add_history_entry(line.as_ref()); |
| println!("Line: {}", line); |
| } |
| Err(ReadlineError::Interrupted) => { |
| println!("CTRL-C"); |
| break; |
| } |
| Err(ReadlineError::Eof) => { |
| println!("CTRL-D"); |
| break; |
| } |
| Err(err) => { |
| println!("Error: {:?}", err); |
| break; |
| } |
| } |
| } |
| rl.save_history("history.txt").unwrap(); |
| } |
| |
| struct Logger; |
| |
| impl log::Log for Logger { |
| fn enabled(&self, metadata: &LogMetadata) -> bool { |
| metadata.level() <= LogLevel::Debug |
| } |
| |
| fn log(&self, record: &LogRecord) { |
| if self.enabled(record.metadata()) { |
| writeln!(io::stderr(), "{} - {}", record.level(), record.args()).unwrap(); |
| } |
| } |
| } |
| |
| fn init_logger() -> Result<(), SetLoggerError> { |
| log::set_logger(|max_log_level| { |
| max_log_level.set(LogLevelFilter::Info); |
| Box::new(Logger) |
| }) |
| } |