From 4ea9c78c50984786a7683675926b342ec88a4095 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Fri, 22 Jun 2018 11:26:52 -0700 Subject: [PATCH] [cli] Part 3: {load,save}_history as appropriate. It's possible that we should be saving more aggressively -- perhaps after each entered command -- but we can add that later. --- tools/cli/src/mentat_cli/input.rs | 15 +++++++++++++++ tools/cli/src/mentat_cli/lib.rs | 15 +++++++++++++++ tools/cli/src/mentat_cli/repl.rs | 2 ++ 3 files changed, 32 insertions(+) diff --git a/tools/cli/src/mentat_cli/input.rs b/tools/cli/src/mentat_cli/input.rs index c190aaab..27139af8 100644 --- a/tools/cli/src/mentat_cli/input.rs +++ b/tools/cli/src/mentat_cli/input.rs @@ -77,6 +77,11 @@ impl InputReader { /// Constructs a new `InputReader` reading from `stdin`. pub fn new(interface: Option>) -> InputReader { if let Some(ref interface) = interface { + // It's fine to fail to load history. + let p = ::history_file_path(); + let loaded = interface.load_history(&p); + debug!("history read from {}: {}", p.display(), loaded.is_ok()); + let mut r = interface.lock_reader(); // Handle SIGINT (Ctrl-C) r.set_report_signal(Signal::Interrupt, true); @@ -221,5 +226,15 @@ impl InputReader { if let Some(ref interface) = self.interface { interface.add_history(line); } + self.save_history(); + } + + pub fn save_history(&self) -> () { + if let Some(ref interface) = self.interface { + let p = ::history_file_path(); + // It's okay to fail to save history. + let saved = interface.save_history(&p); + debug!("history saved to {}: {}", p.display(), saved.is_ok()); + } } } diff --git a/tools/cli/src/mentat_cli/lib.rs b/tools/cli/src/mentat_cli/lib.rs index b8df8caf..0a47272b 100644 --- a/tools/cli/src/mentat_cli/lib.rs +++ b/tools/cli/src/mentat_cli/lib.rs @@ -10,6 +10,10 @@ #![crate_name = "mentat_cli"] +use std::path::{ + PathBuf, +}; + #[macro_use] extern crate failure_derive; #[macro_use] extern crate log; #[macro_use] extern crate lazy_static; @@ -36,6 +40,17 @@ use termion::{ color, }; +static HISTORY_FILE_PATH: &str = ".mentat_history"; + +/// The Mentat CLI stores input history in a readline-compatible file like "~/.mentat_history". +/// This accords with main other tools which prefix with "." and suffix with "_history": lein, +/// node_repl, python, and sqlite, at least. +pub(crate) fn history_file_path() -> PathBuf { + let mut p = ::std::env::home_dir().unwrap_or_default(); + p.push(::HISTORY_FILE_PATH); + p +} + static BLUE: color::Rgb = color::Rgb(0x99, 0xaa, 0xFF); static GREEN: color::Rgb = color::Rgb(0x77, 0xFF, 0x99); diff --git a/tools/cli/src/mentat_cli/repl.rs b/tools/cli/src/mentat_cli/repl.rs index 266e0c30..ce08286a 100644 --- a/tools/cli/src/mentat_cli/repl.rs +++ b/tools/cli/src/mentat_cli/repl.rs @@ -252,6 +252,8 @@ impl Repl { Err(e) => eprintln!("{}", e.to_string()), } } + + self.input_reader.save_history(); } fn cache(&mut self, attr: String, direction: CacheDirection) {