diff --git a/Cargo.lock b/Cargo.lock index d4642a2..200a645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1107,6 +1107,7 @@ dependencies = [ "ansi-to-tui", "anyhow", "assert_cmd", + "atty", "chrono", "criterion", "crossterm 0.22.1", diff --git a/Cargo.toml b/Cargo.toml index 613a87d..eca7810 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ humansize = "1.1.1" mlua = { version = "0.6.6", features = ["luajit", "vendored", "serialize", "send"] } ansi-to-tui = "0.4.1" libc = "0.2.105" +atty = "0.2.14" [dev-dependencies] criterion = "0.3.5" diff --git a/src/bin/xplr.rs b/src/bin/xplr.rs index f2fc08b..4d24213 100644 --- a/src/bin/xplr.rs +++ b/src/bin/xplr.rs @@ -26,7 +26,8 @@ fn main() { -c, --config Specifies a custom config file (default is "$HOME/.config/xplr/init.lua") -C, --extra-config ... Specifies extra config files to load - --on-load ... Sends messages when xplr loads"###; + --on-load ... Sends messages when xplr loads + --select Selects all entries in a given file."###; let args = r###" Path to focus on, or enter if directory"###; diff --git a/src/cli.rs b/src/cli.rs index 87ea444..586bf10 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -15,6 +15,7 @@ pub struct Cli { pub config: Option, pub extra_config: Vec, pub on_load: Vec, + pub select_file: Option, } impl Cli { @@ -75,6 +76,11 @@ impl Cli { } } } + "--select" => { + if cli.select_file.is_none() { + cli.select_file = args.pop_front().map(PathBuf::from); + } + } // path path => { diff --git a/src/runner.rs b/src/runner.rs index d3d5c2c..ed278c7 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -14,7 +14,10 @@ use crossterm::execute; use crossterm::terminal as term; use mlua::LuaSerdeExt; use std::fs; +use std::fs::File; use std::io; +use std::io::BufRead; +use std::io::BufReader; use std::io::Write; use std::path::PathBuf; use std::process::{Command, ExitStatus, Stdio}; @@ -102,6 +105,20 @@ fn start_fifo(path: &str, focus_path: &str) -> Result { } } +fn process_lines( + lines: BufReader, + tx_msg_in: &mpsc::Sender, +) -> Result<()> { + for line in lines.lines() { + let line = line?; + tx_msg_in.send(app::Task::new( + app::MsgIn::External(app::ExternalMsg::SelectPath(line)), + None, + ))?; + } + Ok(()) +} + pub struct Runner { pwd: PathBuf, focused_path: Option, @@ -109,6 +126,7 @@ pub struct Runner { extra_config_files: Vec, on_load: Vec, read_only: bool, + select_file: Option, } impl Runner { @@ -138,6 +156,7 @@ impl Runner { extra_config_files: cli.extra_config, on_load: cli.on_load, read_only: cli.read_only, + select_file: cli.select_file, }) } @@ -222,6 +241,26 @@ impl Runner { tx_msg_in.send(app::Task::new(app::MsgIn::External(msg), None))?; } + // Select all files in the select file + if let Some(f) = self.select_file { + let is_stdin = f.as_os_str() == "-"; + if !f.is_file() && !is_stdin { + app = app.log_error(format!( + "Could not find your select file: {}", + f.to_string_lossy() + ))?; + } + if is_stdin { + if atty::isnt(atty::Stream::Stdin) { + let lines = BufReader::new(std::io::stdin()); + process_lines(lines, &tx_msg_in)?; + } + } else { + let lines = BufReader::new(File::open(f)?); + process_lines(lines, &tx_msg_in)?; + }; + } + 'outer: for task in rx_msg_in { match app.handle_task(task) { Ok(a) => {