diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | development.md | 2 | ||||
-rw-r--r-- | src/bulkrename.rs | 28 | ||||
-rw-r--r-- | src/cli_info.rs | 4 | ||||
-rw-r--r-- | src/compress.rs | 4 | ||||
-rw-r--r-- | src/copy_move.rs | 8 | ||||
-rw-r--r-- | src/event_exec.rs | 26 | ||||
-rw-r--r-- | src/log.rs | 33 | ||||
-rw-r--r-- | src/marks.rs | 10 | ||||
-rw-r--r-- | src/opener.rs | 4 | ||||
-rw-r--r-- | src/password.rs | 10 | ||||
-rw-r--r-- | src/shell_menu.rs | 4 | ||||
-rw-r--r-- | src/status.rs | 12 | ||||
-rw-r--r-- | src/term_manager.rs | 8 | ||||
-rw-r--r-- | src/trash.rs | 18 |
16 files changed, 123 insertions, 50 deletions
@@ -861,6 +861,7 @@ dependencies = [ "futures 0.3.27", "gag", "indicatif", + "lazy_static", "log", "log4rs", "nvim-rs", @@ -39,6 +39,7 @@ fs_extra = "1.2.0" futures = "0.3" gag = "1.0.0" indicatif = { version = "0.17.1", features= ["in_memory"] } +lazy_static = "1.4.0" log = { version = "0.4.0", features = ["std"] } log4rs = {version = "1.2.0", features = ["rolling_file_appender", "compound_policy", "size_trigger", "fixed_window_roller"] } nvim-rs = { version = "0.3", features = ["use_tokio"] } diff --git a/development.md b/development.md index 6d54e7e..30e79d6 100644 --- a/development.md +++ b/development.md @@ -515,7 +515,7 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. - execute `sshfs remote_user@hostname:remote_path current_path` which will mount the remote path in current path - [x] FIX: search keybindings don't work. Need to trim a string. - [x] FIX: archive depends on CWD and will crash if it's not set properly (ie. change tab, move, change tab, compress) -- [ ] use memory and not disk to read logs. Write action logs before saving. Remove most useless logs, only save commands +- [x] use memory and not disk to read last line of logs. ## TODO diff --git a/src/bulkrename.rs b/src/bulkrename.rs index aedaaec..1bbc678 100644 --- a/src/bulkrename.rs +++ b/src/bulkrename.rs @@ -8,6 +8,7 @@ use std::time::{Duration, SystemTime}; use crate::constant_strings_paths::TMP_FOLDER_PATH; use crate::impl_selectable_content; +use crate::log::write_log_line; use crate::opener::Opener; use crate::status::Status; @@ -115,8 +116,12 @@ impl<'a> Bulkrename<'a> { let mut file = std::fs::File::create(&self.temp_file)?; for path in self.original_filepath.clone().unwrap().iter() { - let Some(os_filename) = path.file_name() else { return Ok(()) }; - let Some(filename) = os_filename.to_str() else {return Ok(()) }; + let Some(os_filename) = path.file_name() else { + return Ok(()); + }; + let Some(filename) = os_filename.to_str() else { + return Ok(()); + }; let b = filename.as_bytes(); file.write_all(b)?; file.write_all(&[b'\n'])?; @@ -169,9 +174,11 @@ impl<'a> Bulkrename<'a> { let new_name = sanitize_filename::sanitize(filename); self.rename_file(path, &new_name)?; counter += 1; - info!(target: "special", "Bulk renamed {path} to {new_name}", path=path.display()) + let log_line = format!("Bulk renamed {path} to {new_name}", path = path.display()); + write_log_line(log_line); } - info!(target: "special", "Bulk renamed {counter} files"); + let log_line = format!("Bulk renamed {counter} files"); + write_log_line(log_line); Ok(()) } @@ -181,24 +188,29 @@ impl<'a> Bulkrename<'a> { let mut new_path = std::path::PathBuf::from(self.parent_dir.unwrap()); if !filename.ends_with('/') { new_path.push(filename); - let Some(parent) = new_path.parent() else { return Ok(()); }; + let Some(parent) = new_path.parent() else { + return Ok(()); + }; info!("Bulk new files. Creating parent: {}", parent.display()); if std::fs::create_dir_all(parent).is_err() { continue; }; info!("creating: {new_path:?}"); std::fs::File::create(&new_path)?; - info!(target:"special", "Bulk created {new_path}", new_path=new_path.display()); + let log_line = format!("Bulk created {new_path}", new_path = new_path.display()); + write_log_line(log_line); counter += 1; } else { new_path.push(filename); info!("Bulk creating dir: {}", new_path.display()); std::fs::create_dir_all(&new_path)?; - info!(target:"special", "Bulk created {new_path}", new_path=new_path.display()); + let log_line = format!("Bulk created {new_path}", new_path = new_path.display()); + write_log_line(log_line); counter += 1; } } - info!(target: "special", "Bulk created {counter} files"); + let log_line = format!("Bulk created {counter} files"); + write_log_line(log_line); Ok(()) } diff --git a/src/cli_info.rs b/src/cli_info.rs index 7357288..aa29b50 100644 --- a/src/cli_info.rs +++ b/src/cli_info.rs @@ -5,6 +5,7 @@ use log::info; use crate::constant_strings_paths::CLI_INFO_COMMANDS; use crate::impl_selectable_content; +use crate::log::write_log_line; use crate::utils::is_program_in_path; /// Holds the command line commands we can run and display @@ -44,7 +45,8 @@ impl CliInfo { pub fn execute(&self) -> Result<String> { let args = self.commands[self.index].clone(); info!("execute. {args:?}"); - info!(target:"special", "Executed {args:?}"); + let log_line = format!("Executed {args:?}"); + write_log_line(log_line); let child = Command::new(args[0]) .args(&args[1..]) .env("CLICOLOR_FORCE", "1") diff --git a/src/compress.rs b/src/compress.rs index 420480b..d1bb6fb 100644 --- a/src/compress.rs +++ b/src/compress.rs @@ -5,6 +5,7 @@ use std::io::Write; use anyhow::Result; use crate::impl_selectable_content; +use crate::log::write_log_line; use flate2::write::{DeflateEncoder, GzEncoder, ZlibEncoder}; use flate2::Compression; use lzma::LzmaWriter; @@ -70,7 +71,8 @@ impl Compresser { CompressionMethod::ZIP => Self::zip(Self::archive(here, "archive.zip")?, files)?, CompressionMethod::LZMA => Self::lzma(Self::archive(here, "archive.tar.xz")?, files)?, } - log::info!(target:"special", "Compressed with {selected}"); + let log_line = format!("Compressed with {selected}"); + write_log_line(log_line); Ok(()) } diff --git a/src/copy_move.rs b/src/copy_move.rs index 172eec1..022af6d 100644 --- a/src/copy_move.rs +++ b/src/copy_move.rs @@ -11,6 +11,7 @@ use tuikit::prelude::{Attr, Color, Effect, Event, Term}; use crate::constant_strings_paths::NOTIFY_EXECUTABLE; use crate::fileinfo::human_size; +use crate::log::write_log_line; use crate::opener::execute_in_child; fn setup_progress_bar( @@ -154,11 +155,8 @@ where fn inform_of_copy(verb: &str, hs_bytes: String, preterit: &str) { let _ = notify(&format!("fm: {} finished {}B {}", verb, hs_bytes, preterit)); info!("{} finished {}B", verb, hs_bytes,); - info!(target: "special", - "{} finished {}B", - verb, - hs_bytes, - ) + let log_line = format!("{} finished {}B", verb, hs_bytes,); + write_log_line(log_line); } /// Send a notification to the desktop. diff --git a/src/event_exec.rs b/src/event_exec.rs index c2d89c0..57ba23f 100644 --- a/src/event_exec.rs +++ b/src/event_exec.rs @@ -17,6 +17,7 @@ use crate::cryptsetup::BlockDeviceAction; use crate::fileinfo::FileKind; use crate::filter::FilterKind; use crate::log::read_log; +use crate::log::write_log_line; use crate::mocp::Mocp; use crate::mode::{InputSimple, MarkAction, Mode, Navigate, NeedConfirmation}; use crate::opener::{ @@ -145,7 +146,12 @@ impl EventAction { .directory_of_selected()? .join(filename); std::os::unix::fs::symlink(original_file, &link)?; - info!(target: "special", "Symlink {link} links to {original_file}", original_file=original_file.display(), link=link.display()); + let log_line = format!( + "Symlink {link} links to {original_file}", + original_file = original_file.display(), + link = link.display() + ); + write_log_line(log_line); } status.clear_flags_and_reset_view() } @@ -1079,7 +1085,8 @@ impl LeaveMode { if let Some(path_str) = status.selected_non_mut().path_content_str() { let p = path::PathBuf::from(path_str); status.marks.new_mark(*ch, &p)?; - log::info!(target : "special", "Saved mark {ch} -> {p}", p=p.display()); + let log_line = format!("Saved mark {ch} -> {p}", p = p.display()); + write_log_line(log_line); } status.selected().window.reset(len); status.selected().input.reset(); @@ -1120,7 +1127,8 @@ impl LeaveMode { Status::set_permissions(path, permissions)? } status.flagged.clear(); - log::info!(target:"special", "Changed permissions to {input_permission}") + let log_line = format!("Changed permissions to {input_permission}"); + write_log_line(log_line); } status.selected().refresh_view()?; status.reset_tabs_view() @@ -1214,11 +1222,13 @@ impl LeaveMode { original_path.display(), new_path.display() ); - info!(target: "special", + let log_line = format!( "renaming: original: {} - new: {}", original_path.display(), new_path.display() ); + write_log_line(log_line); + fs::rename(original_path, new_path)?; } @@ -1235,7 +1245,8 @@ impl LeaveMode { .join(sanitize_filename::sanitize(tab.input.string())); if !path.exists() { fs::File::create(&path)?; - info!(target: "special", "New file: {path}", path=path.display()); + let log_line = format!("New file: {path}", path = path.display()); + write_log_line(log_line); } tab.refresh_view() } @@ -1252,7 +1263,8 @@ impl LeaveMode { .join(sanitize_filename::sanitize(tab.input.string())); if !path.exists() { fs::create_dir_all(&path)?; - info!(target: "special", "New directory: {path}", path=path.display()); + let log_line = format!("New directory: {path}", path = path.display()); + write_log_line(log_line); } tab.refresh_view() } @@ -1471,7 +1483,7 @@ impl LeaveMode { execute_and_capture_output(SSHFS_EXECUTABLE, &[first_arg, current_path]); let log_line = format!("{SSHFS_EXECUTABLE} output {command_output:?}"); info!("{log_line}"); - info!(target: "special", "{log_line}"); + write_log_line(log_line); Ok(()) } } @@ -1,5 +1,8 @@ +use std::sync::RwLock; + use anyhow::Result; use chrono::{offset, LocalResult, NaiveDateTime, Utc}; +use lazy_static::lazy_static; use log4rs; use crate::constant_strings_paths::{ACTION_LOG_PATH, LOG_CONFIG_PATH}; @@ -82,3 +85,33 @@ fn is_recent_enough(dt_naive: NaiveDateTime) -> bool { false } } + +lazy_static! { + static ref LAST_LOG_LINE: RwLock<String> = RwLock::new("".to_string()); +} + +/// Read the last value of the "log line". +/// It's a global string created with `lazy_static!(...)` +pub fn read_last_log_line() -> String { + let Ok(r) = LAST_LOG_LINE.read() else { + return "".to_owned(); + }; + r.to_string() +} + +/// Write a new log line to the global variable `LAST_LOG_LINE`. +/// It uses `lazy_static` to manipulate the global variable. +/// Fail silently if the global variable can't be written. +fn write_last_log_line(log: &str) { + let Ok(mut new_log_string) = LAST_LOG_LINE.write() else { + return; + }; + *new_log_string = log.to_owned(); +} + +/// Write a line to both the global variable `LAST_LOG_LINE` and the special log +/// which can be displayed with Alt+l +pub fn write_log_line(log_line: String) { + log::info!(target: "special", "{log_line}"); + write_last_log_line(&log_line); +} diff --git a/src/marks.rs b/src/marks.rs index dad5749..53d063c 100644 --- a/src/marks.rs +++ b/src/marks.rs @@ -7,6 +7,7 @@ use log::info; use crate::constant_strings_paths::MARKS_FILEPATH; use crate::impl_selectable_content; +use crate::log::write_log_line; use crate::utils::read_lines; /// Holds the marks created by the user. @@ -99,8 +100,9 @@ impl Marks { /// If an update is done, the marks are saved again. pub fn new_mark(&mut self, ch: char, path: &Path) -> Result<()> { if ch == ':' { - log::info!(target: "special", "':' can't be used as a mark"); - return Err(anyhow!("new_mark ':' can't be used as a mark")); + let log_line = "new mark - ':' can't be used as a mark"; + write_log_line(log_line.to_owned()); + return Err(anyhow!(log_line)); } if self.used_chars.contains(&ch) { let mut found_index = None; @@ -117,7 +119,9 @@ impl Marks { } else { self.content.push((ch, path.to_path_buf())) } - log::info!(target: "special", "Saved mark {ch} -> {p}", p=path.display()); + + let log_line = format!("Saved mark {ch} -> {p}", p = path.display()); + write_log_line(log_line); self.save_marks() } diff --git a/src/opener.rs b/src/opener.rs index f91e0fc..fe02fba 100644 --- a/src/opener.rs +++ b/src/opener.rs @@ -16,6 +16,7 @@ use crate::constant_strings_paths::{ }; use crate::decompress::{decompress_gz, decompress_xz, decompress_zip}; use crate::fileinfo::extract_extension; +use crate::log::write_log_line; fn find_it<P>(exe_name: P) -> Option<PathBuf> where @@ -393,7 +394,8 @@ pub fn execute_in_child<S: AsRef<std::ffi::OsStr> + fmt::Debug>( args: &[&str], ) -> Result<std::process::Child> { info!("execute_in_child. executable: {exe:?}, arguments: {args:?}"); - info!(target: "special", "Execute: {exe:?}, arguments: {args:?}"); + let log_line = format!("Execute: {exe:?}, arguments: {args:?}"); + write_log_line(log_line); Ok(Command::new(exe).args(args).spawn()?) } diff --git a/src/password.rs b/src/password.rs index 9e34e11..c1b16d1 100644 --- a/src/password.rs +++ b/src/password.rs @@ -4,6 +4,7 @@ use std::process::{Command, Stdio}; use anyhow::{Context, Result}; use log::info; +use crate::log::write_log_line; use crate::utils::current_username; /// Different kind of password @@ -97,10 +98,8 @@ where P: AsRef<std::path::Path> + std::fmt::Debug, { info!("sudo_with_password {args:?} CWD {path:?}"); - info!( - target: "special", - "running sudo command with password. args: {args:?}, CWD: {path:?}" - ); + let log_line = format!("running sudo command with password. args: {args:?}, CWD: {path:?}"); + write_log_line(log_line); let mut child = Command::new("sudo") .arg("-S") .args(args) @@ -131,7 +130,8 @@ where S: AsRef<std::ffi::OsStr> + std::fmt::Debug, { info!("running sudo {:?}", args); - info!(target: "special", "running sudo command. {args:?}"); + let log_line = format!("running sudo command. {args:?}"); + write_log_line(log_line); let child = Command::new("sudo") .args(args) .stdin(Stdio::null()) diff --git a/src/shell_menu.rs b/src/shell_menu.rs index b618d5c..fb54abd 100644 --- a/src/shell_menu.rs +++ b/src/shell_menu.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Result}; use crate::impl_selectable_content; +use crate::log::write_log_line; use crate::opener::{execute_in_child_without_output, execute_in_child_without_output_with_path}; use crate::status::Status; use crate::utils::is_program_in_path; @@ -49,7 +50,8 @@ impl ShellMenu { } else { Self::simple(status, name.as_str())? }; - log::info!(target: "special", "Executed {name}"); + let log_line = format!("Executed {name}"); + write_log_line(log_line); Ok(()) } diff --git a/src/status.rs b/src/status.rs index 1b49223..aadfb82 100644 --- a/src/status.rs +++ b/src/status.rs @@ -23,6 +23,7 @@ use crate::copy_move::{copy_move, CopyMove}; use crate::cryptsetup::{BlockDeviceAction, CryptoDeviceOpener}; use crate::flagged::Flagged; use crate::iso::IsoDevice; +use crate::log::write_log_line; use crate::marks::Marks; use crate::mode::{InputSimple, Mode, NeedConfirmation}; use crate::mount_help::MountHelper; @@ -487,11 +488,9 @@ impl Status { } else { if iso_device.mount(¤t_username()?, &mut self.password_holder)? { info!("iso mounter mounted {iso_device:?}"); - info!( - target: "special", - "iso : {}", - iso_device.as_string()?, - ); + + let log_line = format!("iso : {}", iso_device.as_string()?,); + write_log_line(log_line); let path = iso_device.mountpoints.clone().context("no mount point")?; self.selected().set_pathcontent(&path)?; }; @@ -640,6 +639,7 @@ impl Status { /// Recursively delete all flagged files. pub fn confirm_delete_files(&mut self, colors: &Colors) -> Result<()> { + let nb = self.flagged.len(); for pathbuf in self.flagged.content.iter() { if pathbuf.is_dir() { std::fs::remove_dir_all(pathbuf)?; @@ -647,6 +647,8 @@ impl Status { std::fs::remove_file(pathbuf)?; } } + let log_line = format!("Deleted {nb} flagged files"); + write_log_line(log_line); self.selected().reset_mode(); self.clear_flags_and_reset_view()?; self.refresh_status(colors) diff --git a/src/term_manager.rs b/src/term_manager.rs index 8b7ee43..08d6710 100644 --- a/src/term_manager.rs +++ b/src/term_manager.rs @@ -19,7 +19,7 @@ use crate::constant_strings_paths::{ }; use crate::content_window::ContentWindow; use crate::fileinfo::{fileinfo_attr, shorten_path, FileInfo}; -use crate::log::{is_log_recent_engough, read_log}; +use crate::log::read_last_log_line; use crate::mode::{InputSimple, MarkAction, Mode, Navigate, NeedConfirmation}; use crate::mount_help::MountHelper; use crate::preview::{Preview, TextKind, Window}; @@ -343,11 +343,7 @@ impl<'a> WinMain<'a> { fn log_line(&self, canvas: &mut dyn Canvas) -> Result<()> { let (_, height) = canvas.size()?; - if let Some(log) = read_log()?.last() { - if is_log_recent_engough(log)? { - canvas.print_with_attr(height - 1, 4, log, ATTR_YELLOW_BOLD)?; - } - } + canvas.print_with_attr(height - 1, 4, &read_last_log_line(), ATTR_YELLOW_BOLD)?; Ok(()) } diff --git a/src/trash.rs b/src/trash.rs index 1bdf392..75aa28d 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -10,6 +10,7 @@ use rand::{thread_rng, Rng}; use crate::constant_strings_paths::{TRASH_FOLDER_FILES, TRASH_FOLDER_INFO}; use crate::impl_selectable_content; +use crate::log::write_log_line; use crate::utils::read_lines; static TRASHINFO_DATETIME_FORMAT: &str = "%Y-%m-%dT%H:%M:%S"; @@ -87,7 +88,9 @@ DeletionDate={} let dest_name = Self::remove_extension(dest_name.to_str().unwrap().to_owned())?; if let Ok(lines) = read_lines(trash_info_file) { for (index, line_result) in lines.enumerate() { - let Ok(line) = line_result.as_ref() else { continue }; + let Ok(line) = line_result.as_ref() else { + continue; + }; if line.starts_with("[Trash Info]") { if index == 0 { found_trash_info_line = true; @@ -254,7 +257,8 @@ impl Trash { std::fs::rename(origin, &trashfile_filename)?; info!("moved to trash {:?} -> {:?}", origin, dest_file_name); - info!(target:"special", "moved to trash {:?} -> {:?}", origin, dest_file_name); + let log_line = format!("moved to trash {:?} -> {:?}", origin, dest_file_name); + write_log_line(log_line); Ok(()) } @@ -271,10 +275,11 @@ impl Trash { self.content = vec![]; - info!(target: "special", + let log_line = format!( "Emptied the trash: {} files permanently deleted", number_of_elements ); + write_log_line(log_line); info!( "Emptied the trash: {} files permanently deleted", number_of_elements @@ -331,7 +336,8 @@ impl Trash { std::fs::create_dir_all(&parent)? } std::fs::rename(trashed_file_content, &origin)?; - info!(target: "special", "Trash restored: {origin}", origin=origin.display()); + let log_line = format!("Trash restored: {origin}", origin = origin.display()); + write_log_line(log_line); Ok(()) } @@ -347,11 +353,11 @@ impl Trash { if self.index > 0 { self.index -= 1 } - info!( - target: "special", + let log_line = format!( "Trash removed {trashed_file_content}", trashed_file_content = trashed_file_content.display() ); + write_log_line(log_line); Ok(()) } } |