remove T for Terminal, add W for Shell

This commit is contained in:
Mark 2024-10-06 20:14:36 +02:00
parent b7264ddd13
commit 3b09ac9e13
3 changed files with 85 additions and 30 deletions

View File

@ -42,13 +42,13 @@ fn main() -> io::Result<()> {
total_instances: 1, total_instances: 1,
stdout: io::stdout().lock(), stdout: io::stdout().lock(),
size: terminal::size()?, 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()), editor_command: std::env::var("EDITOR").unwrap_or("nano".to_string()),
live_search: !args.no_live_search, live_search: !args.no_live_search,
info_what: vec![0, 1], info_what: vec![0, 1],
}; };
if args.check { if args.check {
eprintln!("Terminal: {}", share.terminal_command); eprintln!("Shell: {}", share.shell_command);
eprintln!("Editor: {}", share.editor_command); eprintln!("Editor: {}", share.editor_command);
return Ok(()); return Ok(());
} }
@ -122,7 +122,7 @@ fn main() -> io::Result<()> {
tasks::task_copy(src, destination, &mut share); tasks::task_copy(src, destination, &mut share);
false false
} }
AppCmd::TaskFinished => { AppCmd::RescanFiles => {
for i in &mut instances { for i in &mut instances {
i.updates.request_rescan_files(); i.updates.request_rescan_files();
} }
@ -148,7 +148,7 @@ fn main() -> io::Result<()> {
/// - A => Alternate selection (toggle All) /// - A => Alternate selection (toggle All)
/// - S => Select or toggle current /// - S => Select or toggle current
/// - D => Deselect all /// - 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]) /// - M => set Mode based on Find/Filter bar ((t/b)[seconds])
/// - N => New directory from search text /// - N => New directory from search text
/// - C => Copy selected files to this directory. /// - 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) /// - P -> set Permissions (mode taken as base-8 number from find/filter bar text)
/// - O -> set Owner (and group - TODO!) /// - O -> set Owner (and group - TODO!)
/// - 1-9 or 0 => set recursive depth limit (0 = infinite) /// - 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 <file/dir>) /// - E => open in editor ($EDITOR <file/dir>)
/// Find/Filter Bar: /// Find/Filter Bar:
/// - Esc: back and discard /// - Esc: back and discard
@ -190,7 +191,7 @@ struct Share {
stdout: StdoutLock<'static>, stdout: StdoutLock<'static>,
// //
live_search: bool, live_search: bool,
terminal_command: String, shell_command: String,
editor_command: String, editor_command: String,
/// 0: size /// 0: size
/// 1: mode (permissions) /// 1: mode (permissions)
@ -201,13 +202,26 @@ impl Share {
/// returns Some(true) if at least one of these tasks may have altered files. /// returns Some(true) if at least one of these tasks may have altered files.
/// (this should trigger a rescan) /// (this should trigger a rescan)
fn check_bgtasks(&mut self) -> Option<bool> { fn check_bgtasks(&mut self) -> Option<bool> {
for (i, task) in self.tasks.iter_mut().enumerate() { let mut finished = false;
if task.thread.is_finished() { let mut rescan = false;
return Some(self.tasks.remove(i).rescan_after); for i in self
} .tasks
.iter()
.enumerate()
.filter(|v| v.1.thread.is_finished())
.map(|v| v.0)
.collect::<Vec<_>>()
{
let task = self.tasks.remove(i);
finished = true;
rescan |= task.rescan_after;
} }
if finished {
Some(rescan)
} else {
None None
} }
}
} }
struct BackgroundTask { struct BackgroundTask {
status: Arc<Mutex<String>>, status: Arc<Mutex<String>>,
@ -308,7 +322,7 @@ enum AppCmd {
PrevInstance, PrevInstance,
AddInstance(TuiFile), AddInstance(TuiFile),
CopyTo(PathBuf), CopyTo(PathBuf),
TaskFinished, RescanFiles,
} }
impl TuiFile { impl TuiFile {
pub fn clone(&self) -> Self { pub fn clone(&self) -> Self {

View File

@ -10,7 +10,7 @@ use crate::{
use std::io::Write; use std::io::Write;
use std::os::unix::prelude::PermissionsExt; use std::os::unix::prelude::PermissionsExt;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{Command, Stdio}; use std::process::Command;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use std::{fs, io}; use std::{fs, io};
@ -47,7 +47,7 @@ impl TuiFile {
} }
} }
if rescan { if rescan {
return Ok(AppCmd::TaskFinished); return Ok(AppCmd::RescanFiles);
} }
} }
// rescan files if necessary // rescan files if necessary
@ -259,6 +259,7 @@ impl TuiFile {
} }
} }
if depth < max_depth { if depth < max_depth {
// should (almost?) never return an error
get_files( get_files(
dir_content, dir_content,
p, p,
@ -266,7 +267,7 @@ impl TuiFile {
max_depth, max_depth,
info_what, info_what,
time_limit, time_limit,
); )?;
} }
} }
} }
@ -696,7 +697,8 @@ impl TuiFile {
} }
} }
} }
(Focus::Files, KeyCode::Char('f')) => { // Search
(Focus::Files, KeyCode::Char('f' | '/')) => {
self.focus = Focus::SearchBar; self.focus = Focus::SearchBar;
self.updates.request_move_cursor(); 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')) => { (Focus::Files, KeyCode::Char('n')) => {
let dir = self.current_dir.join(&self.search_text); let dir = self.current_dir.join(&self.search_text);
if fs::create_dir_all(&dir).is_ok() { if fs::create_dir_all(&dir).is_ok() {
@ -765,23 +767,63 @@ impl TuiFile {
self.updates.request_reset_search(); self.updates.request_reset_search();
// TODO! // TODO!
} }
// T -> Open Terminal // Query files (Edit doesn't do this automatically, but running a shell does)
(Focus::Files, KeyCode::Char('t')) => 'term: { (Focus::Files, KeyCode::Char('q')) => {
Command::new(&share.terminal_command) 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) .current_dir(&self.current_dir)
.stdout(Stdio::null()) .status()
.stderr(Stdio::null()) {
.spawn(); 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 // E -> Edit
(Focus::Files, KeyCode::Char('e')) => { (Focus::Files, KeyCode::Char('e')) => {
Self::term_reset(share)?; Self::term_reset(share)?;
if let Some(entry) = self.dir_content.get(self.current_index) { let entry_path = self
let entry_path = entry.path.clone(); .dir_content
Command::new(&share.editor_command) .get(self.current_index)
.map(|v| &v.path)
.unwrap_or(&self.current_dir);
match Command::new(&share.editor_command)
.arg(&entry_path) .arg(&entry_path)
.current_dir(&self.current_dir) .current_dir(&self.current_dir)
.status(); .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)?; self.term_setup(share)?;
} }

View File

@ -3,7 +3,6 @@ use std::{
fs, io, fs, io,
os::unix::prelude::PermissionsExt, os::unix::prelude::PermissionsExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
time::Duration,
}; };
use crate::{BackgroundTask, Share}; use crate::{BackgroundTask, Share};