diff --git a/src/main.rs b/src/main.rs index 6868d7c..1d8f351 100755 --- a/src/main.rs +++ b/src/main.rs @@ -42,13 +42,13 @@ fn main() -> io::Result<()> { total_instances: 1, stdout: io::stdout().lock(), size: terminal::size()?, - terminal_command: std::env::var("TERM").unwrap_or("alacritty".to_string()), + shell_command: std::env::var("SHELL").unwrap_or("sh".to_string()), editor_command: std::env::var("EDITOR").unwrap_or("nano".to_string()), live_search: !args.no_live_search, info_what: vec![0, 1], }; if args.check { - eprintln!("Terminal: {}", share.terminal_command); + eprintln!("Shell: {}", share.shell_command); eprintln!("Editor: {}", share.editor_command); return Ok(()); } @@ -122,7 +122,7 @@ fn main() -> io::Result<()> { tasks::task_copy(src, destination, &mut share); false } - AppCmd::TaskFinished => { + AppCmd::RescanFiles => { for i in &mut instances { i.updates.request_rescan_files(); } @@ -148,7 +148,7 @@ fn main() -> io::Result<()> { /// - A => Alternate selection (toggle All) /// - S => Select or toggle current /// - D => Deselect all -/// - F => focus Find/Filter bar +/// - F or / => focus Find/Filter bar /// - M => set Mode based on Find/Filter bar ((t/b)[seconds]) /// - N => New directory from search text /// - C => Copy selected files to this directory. @@ -156,7 +156,8 @@ fn main() -> io::Result<()> { /// - P -> set Permissions (mode taken as base-8 number from find/filter bar text) /// - O -> set Owner (and group - TODO!) /// - 1-9 or 0 => set recursive depth limit (0 = infinite) -/// - T => open terminal here ($TERM) +/// - Q => query files again if they have changes +/// - W => open terminal here ($SHELL) /// - E => open in editor ($EDITOR ) /// Find/Filter Bar: /// - Esc: back and discard @@ -190,7 +191,7 @@ struct Share { stdout: StdoutLock<'static>, // live_search: bool, - terminal_command: String, + shell_command: String, editor_command: String, /// 0: size /// 1: mode (permissions) @@ -201,12 +202,25 @@ impl Share { /// returns Some(true) if at least one of these tasks may have altered files. /// (this should trigger a rescan) fn check_bgtasks(&mut self) -> Option { - for (i, task) in self.tasks.iter_mut().enumerate() { - if task.thread.is_finished() { - return Some(self.tasks.remove(i).rescan_after); - } + let mut finished = false; + let mut rescan = false; + for i in self + .tasks + .iter() + .enumerate() + .filter(|v| v.1.thread.is_finished()) + .map(|v| v.0) + .collect::>() + { + let task = self.tasks.remove(i); + finished = true; + rescan |= task.rescan_after; + } + if finished { + Some(rescan) + } else { + None } - None } } struct BackgroundTask { @@ -308,7 +322,7 @@ enum AppCmd { PrevInstance, AddInstance(TuiFile), CopyTo(PathBuf), - TaskFinished, + RescanFiles, } impl TuiFile { pub fn clone(&self) -> Self { diff --git a/src/run.rs b/src/run.rs index f12d66c..7217e6f 100755 --- a/src/run.rs +++ b/src/run.rs @@ -10,7 +10,7 @@ use crate::{ use std::io::Write; use std::os::unix::prelude::PermissionsExt; use std::path::PathBuf; -use std::process::{Command, Stdio}; +use std::process::Command; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use std::{fs, io}; @@ -47,7 +47,7 @@ impl TuiFile { } } if rescan { - return Ok(AppCmd::TaskFinished); + return Ok(AppCmd::RescanFiles); } } // rescan files if necessary @@ -259,6 +259,7 @@ impl TuiFile { } } if depth < max_depth { + // should (almost?) never return an error get_files( dir_content, p, @@ -266,7 +267,7 @@ impl TuiFile { max_depth, info_what, time_limit, - ); + )?; } } } @@ -696,7 +697,8 @@ impl TuiFile { } } } - (Focus::Files, KeyCode::Char('f')) => { + // Search + (Focus::Files, KeyCode::Char('f' | '/')) => { self.focus = Focus::SearchBar; self.updates.request_move_cursor(); } @@ -719,7 +721,7 @@ impl TuiFile { } } } - // N -> New Directory + // N -> New Directory based on search bar (Focus::Files, KeyCode::Char('n')) => { let dir = self.current_dir.join(&self.search_text); if fs::create_dir_all(&dir).is_ok() { @@ -765,23 +767,63 @@ impl TuiFile { self.updates.request_reset_search(); // TODO! } - // T -> Open Terminal - (Focus::Files, KeyCode::Char('t')) => 'term: { - Command::new(&share.terminal_command) + // Query files (Edit doesn't do this automatically, but running a shell does) + (Focus::Files, KeyCode::Char('q')) => { + return Ok(AppCmd::RescanFiles); + } + // W -> Shell (write a command, also it's they key above S for shell, and it's near E for Edit) + (Focus::Files, KeyCode::Char('w')) => { + Self::term_reset(share)?; + if let Some(file) = self.dir_content.get(self.current_index) { + eprintln!( + "Exit shell to return to TUIFILE. Selected file: {}", + file.path.to_string_lossy() + ); + } else { + eprintln!("Exit shell to return to TUIFILE."); + } + match Command::new(&share.shell_command) .current_dir(&self.current_dir) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn(); + .status() + { + Ok(s) => { + if !s.success() { + std::thread::sleep(Duration::from_secs(2)); + } + } + Err(e) => { + eprintln!("Error running command {}: {e}", share.shell_command); + std::thread::sleep(Duration::from_secs(2)); + } + } + self.term_setup(share)?; + return Ok(AppCmd::RescanFiles); } // E -> Edit (Focus::Files, KeyCode::Char('e')) => { Self::term_reset(share)?; - if let Some(entry) = self.dir_content.get(self.current_index) { - let entry_path = entry.path.clone(); - Command::new(&share.editor_command) - .arg(&entry_path) - .current_dir(&self.current_dir) - .status(); + let entry_path = self + .dir_content + .get(self.current_index) + .map(|v| &v.path) + .unwrap_or(&self.current_dir); + match Command::new(&share.editor_command) + .arg(&entry_path) + .current_dir(&self.current_dir) + .status() + { + Ok(s) => { + if !s.success() { + std::thread::sleep(Duration::from_secs(2)); + } + } + Err(e) => { + eprintln!( + "Error running command {}: {e}", + share.editor_command + ); + std::thread::sleep(Duration::from_secs(2)); + } } self.term_setup(share)?; } diff --git a/src/tasks.rs b/src/tasks.rs index 81aca4c..fe17c3b 100755 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -3,7 +3,6 @@ use std::{ fs, io, os::unix::prelude::PermissionsExt, path::{Path, PathBuf}, - time::Duration, }; use crate::{BackgroundTask, Share};