From da9bf5ea3e3c9d08a52ef32a8a8f52bbcd0c3da5 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 3 Apr 2026 13:59:09 +0300 Subject: [PATCH] treewide: make logging format more consistent; make clipboard persistence opt-in Signed-off-by: NotAShelf Change-Id: I9092f93c29fcbe99c90483875f4acd0c6a6a6964 --- src/clipboard/persist.rs | 8 ++++---- src/commands/decode.rs | 2 +- src/commands/delete.rs | 2 +- src/commands/import.rs | 4 ++-- src/commands/list.rs | 4 ++-- src/commands/store.rs | 4 ++-- src/commands/watch.rs | 38 ++++++++++++++++++++++---------------- src/commands/wipe.rs | 2 +- src/db/mod.rs | 2 +- src/main.rs | 8 +++++++- src/multicall/wl_paste.rs | 2 +- 11 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/clipboard/persist.rs b/src/clipboard/persist.rs index df73fc8..a677f50 100644 --- a/src/clipboard/persist.rs +++ b/src/clipboard/persist.rs @@ -175,7 +175,7 @@ unsafe fn fork_and_serve(prepared: PreparedCopy) -> PersistenceResult<()> { pid => { // Parent process, store child PID for loop detection - log::debug!("Forked clipboard persistence process (pid: {pid})"); + log::debug!("forked clipboard persistence process (pid: {pid})"); SERVING_PID.store(pid, Ordering::SeqCst); Ok(()) }, @@ -185,18 +185,18 @@ unsafe fn fork_and_serve(prepared: PreparedCopy) -> PersistenceResult<()> { /// Child process entry point for serving clipboard data. fn serve_clipboard_child(prepared: PreparedCopy) { let pid = std::process::id() as i32; - log::debug!("Clipboard persistence child process started (pid: {pid})"); + log::debug!("clipboard persistence child process started (pid: {pid})"); // Serve clipboard requests. The PreparedCopy::serve() method blocks and // handles all the Wayland protocol interactions internally via // wl-clipboard-rs match prepared.serve() { Ok(()) => { - log::debug!("Clipboard persistence: serve completed normally"); + log::debug!("clipboard persistence: serve completed normally"); }, Err(e) => { - log::error!("Clipboard persistence: serve failed: {e}"); + log::error!("clipboard persistence: serve failed: {e}"); exit(1); }, } diff --git a/src/commands/decode.rs b/src/commands/decode.rs index 8f414a1..f989a18 100644 --- a/src/commands/decode.rs +++ b/src/commands/decode.rs @@ -32,7 +32,7 @@ impl DecodeCommand for SqliteClipboardDb { // If input is empty or whitespace, treat as error and trigger fallback if input_str.trim().is_empty() { - log::debug!("No input provided to decode; relaying clipboard to stdout"); + log::debug!("no input provided to decode; relaying clipboard to stdout"); if let Ok((mut reader, _mime)) = get_contents(ClipboardType::Regular, Seat::Unspecified, MimeType::Any) { diff --git a/src/commands/delete.rs b/src/commands/delete.rs index dd84989..ba358ad 100644 --- a/src/commands/delete.rs +++ b/src/commands/delete.rs @@ -9,7 +9,7 @@ pub trait DeleteCommand { impl DeleteCommand for SqliteClipboardDb { fn delete(&self, input: impl Read) -> Result { let deleted = self.delete_entries(input)?; - log::info!("Deleted {deleted} entries"); + log::info!("deleted {deleted} entries"); Ok(deleted) } } diff --git a/src/commands/import.rs b/src/commands/import.rs index 933cf88..4a3a2a7 100644 --- a/src/commands/import.rs +++ b/src/commands/import.rs @@ -55,11 +55,11 @@ impl ImportCommand for SqliteClipboardDb { imported += 1; } - log::info!("Imported {imported} records from TSV into SQLite database."); + log::info!("imported {imported} records from TSV into SQLite database."); // Trim database to max_items after import self.trim_db(max_items)?; - log::info!("Trimmed clipboard database to max_items = {max_items}"); + log::info!("trimmed clipboard database to max_items = {max_items}"); Ok(()) } diff --git a/src/commands/list.rs b/src/commands/list.rs index 7d289ad..b3041e5 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -710,7 +710,7 @@ impl SqliteClipboardDb { .show(); }, Err(e) => { - log::error!("Failed to copy entry to clipboard: {e}"); + log::error!("failed to copy entry to clipboard: {e}"); let _ = Notification::new() .summary("Stash") .body(&format!("Failed to copy to clipboard: {e}")) @@ -719,7 +719,7 @@ impl SqliteClipboardDb { } }, Err(e) => { - log::error!("Failed to fetch entry {id}: {e}"); + log::error!("failed to fetch entry {id}: {e}"); let _ = Notification::new() .summary("Stash") .body(&format!("Failed to fetch entry: {e}")) diff --git a/src/commands/store.rs b/src/commands/store.rs index 0b7e23c..4495754 100644 --- a/src/commands/store.rs +++ b/src/commands/store.rs @@ -29,7 +29,7 @@ impl StoreCommand for SqliteClipboardDb { ) -> Result<(), crate::db::StashError> { if let Some("sensitive" | "clear") = state.as_deref() { self.delete_last()?; - log::info!("Entry deleted"); + log::info!("entry deleted"); } else { self.store_entry( input, @@ -41,7 +41,7 @@ impl StoreCommand for SqliteClipboardDb { None, // no pre-computed hash for CLI store None, // no mime types for CLI store )?; - log::info!("Entry stored"); + log::info!("entry stored"); } Ok(()) } diff --git a/src/commands/watch.rs b/src/commands/watch.rs index 542937d..71cdc17 100644 --- a/src/commands/watch.rs +++ b/src/commands/watch.rs @@ -204,6 +204,7 @@ pub trait WatchCommand { mime_type_preference: &str, min_size: Option, max_size: usize, + persist: bool, ); } @@ -217,6 +218,7 @@ impl WatchCommand for SqliteClipboardDb { mime_type_preference: &str, min_size: Option, max_size: usize, + persist: bool, ) { let async_db = AsyncClipboardDb::new(self.db_path.clone()); log::info!( @@ -224,6 +226,10 @@ impl WatchCommand for SqliteClipboardDb { {mime_type_preference}" ); + if persist { + log::info!("clipboard persistence enabled"); + } + // Build expiration queue from existing entries let mut exp_queue = ExpirationQueue::new(); @@ -234,11 +240,11 @@ impl WatchCommand for SqliteClipboardDb { exp_queue.push(expires_at, id); } if !exp_queue.is_empty() { - log::info!("Loaded {} expirations from database", exp_queue.len()); + log::info!("loaded {} expirations from database", exp_queue.len()); } }, Err(e) => { - log::warn!("Failed to load expirations: {e}"); + log::warn!("failed to load expirations: {e}"); }, } @@ -277,7 +283,7 @@ impl WatchCommand for SqliteClipboardDb { match async_db.get_content_hash(id).await { Ok(hash) => hash, Err(e) => { - log::warn!("Failed to get content hash for entry {id}: {e}"); + log::warn!("failed to get content hash for entry {id}: {e}"); None }, }; @@ -285,9 +291,9 @@ impl WatchCommand for SqliteClipboardDb { if let Some(stored_hash) = expired_hash { // Mark as expired if let Err(e) = async_db.mark_expired(id).await { - log::warn!("Failed to mark entry {id} as expired: {e}"); + log::warn!("failed to mark entry {id} as expired: {e}"); } else { - log::info!("Entry {id} marked as expired"); + log::info!("entry {id} marked as expired"); } // Check if this expired entry is currently in the clipboard @@ -315,12 +321,12 @@ impl WatchCommand for SqliteClipboardDb { .is_ok() { log::info!( - "Cleared clipboard containing expired entry {id}" + "cleared clipboard containing expired entry {id}" ); last_hash = None; // reset tracked hash } else { log::warn!( - "Failed to clear clipboard for expired entry {id}" + "failed to clear clipboard for expired entry {id}" ); } } @@ -337,7 +343,7 @@ impl WatchCommand for SqliteClipboardDb { Ok((mut reader, _mime_type, _all_mimes)) => { buf.clear(); if let Err(e) = reader.read_to_end(&mut buf) { - log::error!("Failed to read clipboard contents: {e}"); + log::error!("failed to read clipboard contents: {e}"); Timer::after(Duration::from_millis(500)).await; continue; } @@ -370,13 +376,13 @@ impl WatchCommand for SqliteClipboardDb { .await { Ok(id) => { - log::info!("Stored new clipboard entry (id: {id})"); + log::info!("stored new clipboard entry (id: {id})"); last_hash = Some(current_hash); // Persist clipboard: fork child to serve data // This keeps the clipboard alive when source app closes // Check if we're already serving to avoid duplicate processes - if get_serving_pid().is_none() { + if persist && get_serving_pid().is_none() { let clipboard_data = ClipboardData::new( buf_for_persist, mime_types_for_persist, @@ -393,12 +399,12 @@ impl WatchCommand for SqliteClipboardDb { .await; if let Err(e) = result { - log::debug!("Clipboard persistence failed: {e}"); + log::debug!("clipboard persistence failed: {e}"); } }) .detach(); } - } else { + } else if persist { log::trace!( "Already serving clipboard, skipping persistence fork" ); @@ -420,17 +426,17 @@ impl WatchCommand for SqliteClipboardDb { } }, Err(crate::db::StashError::ExcludedByApp(_)) => { - log::info!("Clipboard entry excluded by app filter"); + log::info!("clipboard entry excluded by app filter"); last_hash = Some(current_hash); }, Err(crate::db::StashError::Store(ref msg)) if msg.contains("Excluded by app filter") => { - log::info!("Clipboard entry excluded by app filter"); + log::info!("clipboard entry excluded by app filter"); last_hash = Some(current_hash); }, Err(e) => { - log::error!("Failed to store clipboard entry: {e}"); + log::error!("failed to store clipboard entry: {e}"); last_hash = Some(current_hash); }, } @@ -440,7 +446,7 @@ impl WatchCommand for SqliteClipboardDb { Err(e) => { let error_msg = e.to_string(); if !error_msg.contains("empty") { - log::error!("Failed to get clipboard contents: {e}"); + log::error!("failed to get clipboard contents: {e}"); } }, } diff --git a/src/commands/wipe.rs b/src/commands/wipe.rs index c0bb9ee..2126347 100644 --- a/src/commands/wipe.rs +++ b/src/commands/wipe.rs @@ -7,7 +7,7 @@ pub trait WipeCommand { impl WipeCommand for SqliteClipboardDb { fn wipe(&self) -> Result<(), StashError> { self.wipe_db()?; - log::info!("Database wiped"); + log::info!("database wiped"); Ok(()) } } diff --git a/src/db/mod.rs b/src/db/mod.rs index f907b3b..65eb097 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -875,7 +875,7 @@ impl ClipboardDb for SqliteClipboardDb { out .write_all(&contents) .map_err(|e| StashError::DecodeWrite(e.to_string().into()))?; - log::info!("Decoded entry with id {id}"); + log::info!("decoded entry with id {id}"); Ok(()) } diff --git a/src/main.rs b/src/main.rs index 32c271d..3075e20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -160,6 +160,10 @@ enum Command { /// MIME type preference for clipboard reading. #[arg(short = 't', long, default_value = "any")] mime_type: String, + + /// Persist clipboard contents after the source application closes. + #[arg(long)] + persist: bool, }, } @@ -201,7 +205,7 @@ fn confirm(prompt: &str) -> bool { .with_default(false) .prompt() .unwrap_or_else(|e| { - log::error!("Confirmation prompt failed: {e}"); + log::error!("confirmation prompt failed: {e}"); false }) } @@ -477,6 +481,7 @@ fn main() -> eyre::Result<()> { Some(Command::Watch { expire_after, mime_type, + persist, }) => { db.watch( cli.max_dedupe_search, @@ -489,6 +494,7 @@ fn main() -> eyre::Result<()> { &mime_type, cli.min_size, cli.max_size, + persist, ) .await; }, diff --git a/src/multicall/wl_paste.rs b/src/multicall/wl_paste.rs index 4b828b5..5daa1fd 100644 --- a/src/multicall/wl_paste.rs +++ b/src/multicall/wl_paste.rs @@ -421,7 +421,7 @@ fn handle_regular_paste( let selected_type = available_types.as_ref().and_then(select_best_mime_type); let mime_type = if let Some(ref best) = selected_type { - log::debug!("Auto-selecting MIME type: {best}"); + log::debug!("auto-selecting MIME type: {best}"); PasteMimeType::Specific(best) } else { get_paste_mime_type(args.mime_type.as_deref())