diff options
| author | Joel Martin <github@martintribe.org> | 2014-10-25 11:42:07 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2015-01-06 21:58:35 -0600 |
| commit | abdd56ebc0e01cd92f694ef2bcafcc394453d055 (patch) | |
| tree | d1ace96ac90e5d888e4d4d05dd4ca0c0445a856e /rust/src/readline.rs | |
| parent | f41866dbe99080f0916512261f0412c5bc65f190 (diff) | |
| download | mal-abdd56ebc0e01cd92f694ef2bcafcc394453d055.tar.gz mal-abdd56ebc0e01cd92f694ef2bcafcc394453d055.zip | |
Rust: step0_repl and step1_read_print
Diffstat (limited to 'rust/src/readline.rs')
| -rw-r--r-- | rust/src/readline.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/rust/src/readline.rs b/rust/src/readline.rs new file mode 100644 index 0000000..17d1ed9 --- /dev/null +++ b/rust/src/readline.rs @@ -0,0 +1,76 @@ +// Based on: https://github.com/shaleh/rust-readline (MIT) +extern crate libc; + +use std::c_str; + +use std::io::{File, Append, Write}; +use std::io::BufferedReader; + +mod ext_readline { + extern crate libc; + use self::libc::c_char; + #[link(name = "readline")] + extern { + pub fn add_history(line: *const c_char); + pub fn readline(p: *const c_char) -> *const c_char; + } +} + +pub fn add_history(line: &str) { + unsafe { + ext_readline::add_history(line.to_c_str().as_ptr()); + } +} + +pub fn readline(prompt: &str) -> Option<String> { + let cprmt = prompt.to_c_str(); + unsafe { + let ret = ext_readline::readline(cprmt.as_ptr()); + if ret.is_null() { // user pressed Ctrl-D + None + } + else { + c_str::CString::new(ret, true).as_str().map(|ret| ret.to_string()) + } + } +} + +// -------------------------------------------- + +static mut history_loaded : bool = false; +static HISTORY_FILE : &'static str = "/home/joelm/.mal-history"; + +fn load_history() { + unsafe { + if history_loaded { return; } + history_loaded = true; + } + + let path = Path::new(HISTORY_FILE); + let mut file = BufferedReader::new(File::open(&path)); + for line in file.lines() { + let rt: &[_] = &['\r', '\n']; + let line2 = line.unwrap(); + let line3 = line2.as_slice().trim_right_chars(rt); + add_history(line3); + } +} + +fn append_to_history(line: &str) { + let path = Path::new("/home/joelm/.mal-history"); + let mut file = File::open_mode(&path, Append, Write); + let _ = file.write_line(line); +} + +pub fn mal_readline (prompt: &str) -> Option<String> { + load_history(); + let line = readline(prompt); + match line { + None => None, + _ => { + add_history(line.clone().unwrap().as_slice()); + append_to_history(line.clone().unwrap().as_slice()); + line + } + } +} |
