aboutsummaryrefslogtreecommitdiff
path: root/rust/src/readline.rs
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-25 11:42:07 -0500
committerJoel Martin <github@martintribe.org>2015-01-06 21:58:35 -0600
commitabdd56ebc0e01cd92f694ef2bcafcc394453d055 (patch)
treed1ace96ac90e5d888e4d4d05dd4ca0c0445a856e /rust/src/readline.rs
parentf41866dbe99080f0916512261f0412c5bc65f190 (diff)
downloadmal-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.rs76
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
+ }
+ }
+}