diff options
| author | Jonas Maier <> | 2026-03-08 11:58:38 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-08 11:58:38 +0100 |
| commit | 36b934d543f8cfedb0a74c52de0620be7d5fb106 (patch) | |
| tree | 2082d908f0cbc80b2c83070142c7da15a29e1907 | |
| parent | f005472ded09dc910598f0ce03d6318722ed2c5a (diff) | |
| download | pish-36b934d543f8cfedb0a74c52de0620be7d5fb106.tar.gz | |
persistent history
| -rw-r--r-- | src/date.rs | 2 | ||||
| -rw-r--r-- | src/history.rs | 77 | ||||
| -rw-r--r-- | src/main.rs | 29 | ||||
| -rw-r--r-- | src/parse/mod.rs | 2 |
4 files changed, 85 insertions, 25 deletions
diff --git a/src/date.rs b/src/date.rs index dc6121c..8083da8 100644 --- a/src/date.rs +++ b/src/date.rs @@ -42,7 +42,7 @@ impl DateTime { Ok(out) } - fn unix(&self) -> u64 { + pub fn unix(&self) -> u64 { self.sys .duration_since(SystemTime::UNIX_EPOCH) .unwrap() diff --git a/src/history.rs b/src/history.rs index e69de29..2e06133 100644 --- a/src/history.rs +++ b/src/history.rs @@ -0,0 +1,77 @@ +use sqlite::Connection; + +use crate::BString; +use crate::date::DateTime; +use std::env::current_dir; +use std::path::PathBuf; + +fn db_file() -> PathBuf { + crate::basedir::data_dir().join("history.db") +} + +#[derive(Clone)] +pub struct HistoryEntry { + /// time of execution + pub time: DateTime, + + /// absolute path where the command was executed + pub loc: BString, + + /// the command + pub cmd: BString, +} + +impl HistoryEntry { + pub fn new(cmd: BString) -> Self { + Self { + time: DateTime::now(), + loc: current_dir() + .unwrap() + .as_os_str() + .as_encoded_bytes() + .to_vec(), + cmd, + } + } +} + +fn try_db() -> sqlite::Result<Connection> { + sqlite::open(db_file()) +} + +fn db() -> Connection { + try_db().unwrap() +} + +pub fn setup() { + let db = db(); + + db.execute( + " + CREATE TABLE IF NOT EXISTS history ( + ts INTEGER NOT NULL, + loc BLOB NOT NULL, + cmd BLOB NOT NULL + ) + ", + ) + .unwrap(); + + db.execute("CREATE INDEX IF NOT EXISTS idx_history_ts ON history(ts)") + .unwrap(); +} + +fn try_persist(entry: &HistoryEntry) -> sqlite::Result<()> { + let db = try_db()?; + let mut s = db.prepare("INSERT INTO history (ts, loc, cmd) VALUES (?, ?, ?)")?; + s.bind((1, entry.time.unix() as i64))?; + s.bind((2, entry.loc.as_slice()))?; + s.bind((3, entry.cmd.as_slice()))?; + s.next()?; + Ok(()) +} + +pub fn persist(entry: &HistoryEntry) { + // keep quiet in case db fails + let _ = try_persist(entry); +} diff --git a/src/main.rs b/src/main.rs index 3687cd0..c2cf375 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use linebuf::LineBuf; use raw::*; use crate::cursor::{Direction, move_cursor}; +use crate::history::HistoryEntry; use crate::parse::{Ast, PreExpansion}; macro_rules! print { @@ -59,28 +60,6 @@ type BString = Vec<u8>; #[allow(non_camel_case_types)] type bstr = [u8]; -#[derive(Clone)] -struct HistoryEntry { - /// time of execution - pub time: date::DateTime, - - /// absolute path where the command was executed - pub loc: BString, - - /// the command - pub cmd: BString, -} - -impl HistoryEntry { - pub fn new(cmd: BString) -> Self { - Self { - time: date::DateTime::now(), - loc: current_dir().unwrap().as_os_str().as_encoded_bytes().to_vec(), - cmd, - } - } -} - pub struct Session { raw: ScopedRawMode, line: LineBuf, @@ -259,6 +238,8 @@ fn read1() -> u8 { } fn event_loop() { + history::setup(); + let stdin = io::stdin(); let stdout = io::stdout(); @@ -335,7 +316,9 @@ fn event_loop() { let line = se.line.dump(); if !line.is_empty() { print!("\r\n"); - se.history.push(HistoryEntry::new(line.clone())); + let entry = HistoryEntry::new(line.clone()); + history::persist(&entry); + se.history.push(entry); se.history_visit = 0; drop(se); run::run(session.clone(), line); diff --git a/src/parse/mod.rs b/src/parse/mod.rs index ab693ab..8fa2e23 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -353,7 +353,7 @@ impl ExpString { fn is_symbol(x: u8) -> bool { match x { - b'|' | b'{' | b'}' | b'$' | b'(' | b')' | b'\'' | b'"' => true, + b';' | b'|' | b'{' | b'}' | b'$' | b'(' | b')' | b'\'' | b'"' => true, _ => false, } } |
