Browse Source

Add immediate saving of every line of input to history file

By writing history after each input line, we avoid losing history if numbat fails to exit gracefully.
Robert Bennett 9 months ago
parent
commit
7aa1155037
2 changed files with 12 additions and 3 deletions
  1. 7 3
      numbat-cli/src/main.rs
  2. 5 0
      numbat/src/interpreter/mod.rs

+ 7 - 3
numbat-cli/src/main.rs

@@ -13,11 +13,11 @@ use itertools::Itertools;
 use numbat::command::{CommandControlFlow, CommandRunner};
 use numbat::compact_str::CompactString;
 use numbat::diagnostic::ErrorDiagnostic;
-use numbat::markup as m;
 use numbat::module_importer::{BuiltinModuleImporter, ChainedImporter, FileSystemImporter};
 use numbat::pretty_print::PrettyPrint;
 use numbat::resolver::CodeSource;
 use numbat::session_history::{ParseEvaluationResult, SessionHistory};
+use numbat::{markup as m, RuntimeError};
 use numbat::{Context, NumbatError};
 use numbat::{InterpreterSettings, NameResolutionError};
 
@@ -30,7 +30,7 @@ use rustyline::{
 use rustyline::{EventHandler, Highlighter, KeyCode, KeyEvent, Modifiers};
 
 use std::io::IsTerminal;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::sync::{Arc, Mutex};
 use std::{fs, thread};
 
@@ -343,7 +343,7 @@ impl Cli {
             }
         }
 
-        let result = self.repl_loop(&mut rl, interactive);
+        let result = self.repl_loop(&mut rl, interactive, &history_path);
 
         if interactive {
             rl.save_history(&history_path).context(format!(
@@ -359,6 +359,7 @@ impl Cli {
         &mut self,
         rl: &mut Editor<NumbatHelper, DefaultHistory>,
         interactive: bool,
+        history_path: &Path,
     ) -> Result<()> {
         let mut cmd_runner = CommandRunner::<Editor<NumbatHelper, DefaultHistory>>::new()
             .print_with(|m| println!("{}", ansi_format(m, true)))
@@ -379,6 +380,9 @@ impl Cli {
                     }
 
                     rl.add_history_entry(&line)?;
+                    if interactive && rl.append_history(history_path).is_err() {
+                        self.print_diagnostic(RuntimeError::HistoryWrite(history_path.to_owned()));
+                    }
 
                     let mut ctx = self.context.lock().unwrap();
                     match cmd_runner.try_run_command(&line, &mut ctx, rl) {

+ 5 - 0
numbat/src/interpreter/mod.rs

@@ -65,6 +65,11 @@ pub enum RuntimeError {
 
     #[error("Could not write to file: {0:?}")]
     FileWrite(std::path::PathBuf),
+
+    #[error(
+        "Could not write to history file {0:?}. History will not be saved until this is fixed."
+    )]
+    HistoryWrite(std::path::PathBuf),
 }
 
 #[derive(Debug, PartialEq)]