diff --git a/crates/hyperlog-tui/src/app.rs b/crates/hyperlog-tui/src/app.rs index f6556a6..b0a4791 100644 --- a/crates/hyperlog-tui/src/app.rs +++ b/crates/hyperlog-tui/src/app.rs @@ -221,6 +221,7 @@ impl<'a> App<'a> { } fn open_editor(&self, item: &GraphItem) -> Option { + tracing::info!("entering editor for session"); match editor::EditorSession::new(item).execute() { Ok(None) => { tracing::info!("editor returned without changes, skipping"); diff --git a/crates/hyperlog-tui/src/core_state.rs b/crates/hyperlog-tui/src/core_state.rs index 536c3b1..ef50f0e 100644 --- a/crates/hyperlog-tui/src/core_state.rs +++ b/crates/hyperlog-tui/src/core_state.rs @@ -7,12 +7,10 @@ use crate::{ #[allow(dead_code)] pub struct State { - engine: SharedEngine, - pub storage: Storage, - events: Events, - pub commander: Commander, pub querier: Querier, + + backend: Backend, } pub enum Backend { @@ -22,19 +20,21 @@ pub enum Backend { impl State { pub async fn new(backend: Backend) -> anyhow::Result { - let storage = Storage::new(); - let engine = storage.load()?; - let events = Events::default(); - let engine = SharedEngine::from(engine); - - let (querier, commander) = match backend { - Backend::Local => ( - Querier::local(&engine), - Commander::local(engine.clone(), storage.clone(), events.clone())?, - ), + let (querier, commander) = match &backend { + Backend::Local => { + let storage = Storage::new(); + let engine = storage.load()?; + let events = Events::default(); + let engine = SharedEngine::from(engine); + ( + Querier::local(&engine), + Commander::local(engine.clone(), storage.clone(), events.clone())?, + ) + } Backend::Remote { url } => { - let channel = Channel::from_shared(url)? - .tls_config(ClientTlsConfig::new())? + let tls = ClientTlsConfig::new(); + let channel = Channel::from_shared(url.clone())? + .tls_config(tls.with_native_roots())? .connect() .await?; @@ -46,12 +46,25 @@ impl State { }; Ok(Self { - engine: engine.clone(), - storage: storage.clone(), - events: events.clone(), - commander, querier, + backend, }) } + + pub fn unlock(&self) { + if let Backend::Local = &self.backend { + let storage = Storage::new(); + storage.clear_lock_file(); + } + } + + pub fn info(&self) -> Option> { + if let Backend::Local = &self.backend { + let storage = Storage::new(); + return Some(storage.info()); + } + + None + } } diff --git a/crates/hyperlog-tui/src/editor.rs b/crates/hyperlog-tui/src/editor.rs index b96b420..f76f62c 100644 --- a/crates/hyperlog-tui/src/editor.rs +++ b/crates/hyperlog-tui/src/editor.rs @@ -5,6 +5,10 @@ use std::{ }; use anyhow::{anyhow, Context}; +use crossterm::{ + terminal::{disable_raw_mode, enable_raw_mode}, + ExecutableCommand, +}; use hyperlog_core::log::{GraphItem, ItemState}; use itertools::Itertools; use serde::{Deserialize, Serialize}; @@ -127,6 +131,11 @@ impl SessionFile { impl Drop for SessionFile { fn drop(&mut self) { + // std::io::stdout() + // .execute(crossterm::terminal::EnterAlternateScreen) + // .expect("to be able to restore alternative mode"); + // enable_raw_mode().expect("to be able to restore raw mode"); + if self.path.exists() { tracing::debug!("cleaning up file: {}", self.path.display()); @@ -180,6 +189,7 @@ impl<'a> EditorSession<'a> { .as_bytes(), ) .context("failed to write to file")?; + file.flush().context("failed to flush to disk")?; let modified_time = file.metadata()?.modified()?; @@ -209,7 +219,26 @@ impl<'a> EditorSession<'a> { editor, session_file.get_path().display() ); - if let Err(e) = std::process::Command::new(editor) + + std::io::stdout().flush()?; + + // disable_raw_mode()?; + // std::io::stdout().execute(crossterm::terminal::LeaveAlternateScreen)?; + + let path = session_file.get_path(); + if let Some(parent) = path.parent() { + if let Err(e) = std::process::Command::new(editor) + .arg( + path.file_name() + .ok_or(anyhow::anyhow!("failed to find file in the given path"))?, + ) + .current_dir(parent) + .status() + { + tracing::error!("failed command with: {}", e); + return Ok(None); + } + } else if let Err(e) = std::process::Command::new(editor) .arg(session_file.get_path()) .status() { @@ -238,7 +267,7 @@ trait ItemExt { fn get_digest(&self) -> Option; } -impl<'a> ItemExt for &'a GraphItem { +impl ItemExt for &GraphItem { fn get_digest(&self) -> Option { if let GraphItem::Item { title, .. } = self { let digest = sha2::Sha256::digest(title.as_bytes()); diff --git a/crates/hyperlog-tui/src/lib.rs b/crates/hyperlog-tui/src/lib.rs index 2717cbb..81e8185 100644 --- a/crates/hyperlog-tui/src/lib.rs +++ b/crates/hyperlog-tui/src/lib.rs @@ -31,7 +31,7 @@ pub mod state; mod engine; mod events; mod querier; -mod storage; +pub mod storage; mod editor; mod logging; diff --git a/crates/hyperlog-tui/src/storage.rs b/crates/hyperlog-tui/src/storage.rs index d33bd2c..1665c37 100644 --- a/crates/hyperlog-tui/src/storage.rs +++ b/crates/hyperlog-tui/src/storage.rs @@ -80,6 +80,13 @@ impl Storage { pub fn clear_lock_file(self) { let mut lock_file = self.lock_file.lock().unwrap(); + if let Ok(lock) = self.state_lock() { + if lock.exists() { + tracing::info!("clearing lock file"); + std::fs::remove_file(&lock).expect("to be able to remove lockfile"); + } + } + if lock_file.is_some() { *lock_file = None; } diff --git a/crates/hyperlog/src/cli.rs b/crates/hyperlog/src/cli.rs index 603ab17..9915e11 100644 --- a/crates/hyperlog/src/cli.rs +++ b/crates/hyperlog/src/cli.rs @@ -164,11 +164,13 @@ pub async fn execute() -> anyhow::Result<()> { } Some(Commands::Info {}) => { let state = State::new(backend).await?; - println!("graph stored at: {}", state.storage.info()?) + if let Some(info) = state.info() { + println!("graph stored at: {}", info?); + } } Some(Commands::ClearLock {}) => { let state = State::new(backend).await?; - state.storage.clear_lock_file(); + state.unlock(); println!("cleared lock file"); } None => {