summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2022-06-15 07:47:48 +0200
committerCanop <cano.petrole@gmail.com>2022-06-15 07:47:48 +0200
commit282fbc584554bc7db4d06e603cd05961ee2f060f (patch)
treeaee4509c5dc976cfbb48b52232a2a7ff538f9820
parent37201de6954d751451d010b8a97977c6da76d08f (diff)
use clap derive for arguments
-rw-r--r--CHANGELOG.md6
-rw-r--r--Cargo.lock55
-rw-r--r--Cargo.toml6
-rw-r--r--build.rs7
-rw-r--r--resources/default-conf.hjson15
-rw-r--r--src/app/app.rs9
-rw-r--r--src/app/app_context.rs80
-rw-r--r--src/cli/app_launch_args.rs22
-rw-r--r--src/cli/args.rs200
-rw-r--r--src/cli/clap_args.rs235
-rw-r--r--src/cli/install_launch_args.rs19
-rw-r--r--src/cli/mod.rs110
-rw-r--r--src/print.rs83
-rw-r--r--src/shell_install/mod.rs82
-rw-r--r--src/tree/tree_options.rs55
-rw-r--r--src/verb/external_execution.rs11
16 files changed, 455 insertions, 540 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a5517f..70ba8a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,9 @@
-### next
+### v1.13.2 - ???
+<a name="v1.13.2"></a>
- advice to hit alt-i and|or alt-h when no file is visible - Fix #556
-- update many dependencies
- examples on search modes in help screen - Fix #559
+- list of syntactic themes in default conf
+- the --file-export-path launch argument which was deprecated since broot 1.6 has been removed (redirect the output of broot instead)
### v1.13.1 - 2022-05-30
<a name="v1.13.1"></a>
diff --git a/Cargo.lock b/Cargo.lock
index c19b8c0..290c657 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -255,14 +255,16 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.1.18"
+version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
+checksum = "a836566fa5f52f7ddf909a8a2f9029b9f78ca584cd95cf7e87f8073110f4c5c9"
dependencies = [
"atty",
"bitflags",
+ "clap_derive",
"clap_lex",
"indexmap",
+ "lazy_static",
"strsim",
"termcolor",
"textwrap",
@@ -270,18 +272,31 @@ dependencies = [
[[package]]
name = "clap_complete"
-version = "3.1.4"
+version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da92e6facd8d73c22745a5d3cbb59bdf8e46e3235c923e516527d8e81eec14a4"
+checksum = "0f6ebaab5f25e4f0312dfa07cb30a755204b96e6531457c2cfdecfdf5f2adf40"
dependencies = [
"clap",
]
[[package]]
+name = "clap_derive"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "986fd75d1dfd2c34eb8c9275ae38ad87ea9478c9b79e87f1801f7d866dfb1e37"
+dependencies = [
+ "heck 0.4.0",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "clap_lex"
-version = "0.2.0"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
+checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
dependencies = [
"os_str_bytes",
]
@@ -645,9 +660,9 @@ dependencies = [
[[package]]
name = "flume"
-version = "0.10.12"
+version = "0.10.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
+checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da"
dependencies = [
"futures-core",
"futures-sink",
@@ -1371,6 +1386,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 281408a..8609489 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,7 @@ base64 = "0.13"
bet = "1.0"
char_reader = "0.1"
chrono = "0.4"
-clap = "3.1"
+clap = { version = "3.2.1", features = ["derive"] }
cli-log = "2.0"
crokey = "0.4.1"
crossbeam = "0.8"
@@ -74,8 +74,8 @@ users = "0.11"
is_executable = "1.0.1"
[build-dependencies]
-clap = "3.1"
-clap_complete = "3.1"
+clap = { version = "3.2.1", features = ["derive"] }
+clap_complete = "3.2.1"
[profile.dev]
debug = false
diff --git a/build.rs b/build.rs
index 173302e..5ea3386 100644
--- a/build.rs
+++ b/build.rs
@@ -2,6 +2,7 @@
// It builds shell completion scripts.
use {
+ clap::CommandFactory,
clap_complete::{Generator, Shell},
std::{
env,
@@ -9,14 +10,14 @@ use {
},
};
-include!("src/cli/clap_args.rs");
+include!("src/cli/args.rs");
fn write_completions_file<G: Generator + Copy, P: AsRef<OsStr>>(generator: G, out_dir: P) {
- let mut app = clap_app();
+ let mut args = Args::command();
for name in &["broot", "br"] {
clap_complete::generate_to(
generator,
- &mut app,
+ &mut args,
name.to_string(),
&out_dir,
).expect("clap complete generation failed");
diff --git a/resources/default-conf.hjson b/resources/default-conf.hjson
index dc5bb6f..33fe8ed 100644
--- a/resources/default-conf.hjson
+++ b/resources/default-conf.hjson
@@ -356,4 +356,19 @@
# Change this if you sometimes want to have more than 2 panels
# open
# max_panels_count: 2
+
+
+ ###############################################################
+ # Syntax Theme
+ #
+ # If you want to choose the them used for preview, uncomment
+ # one of the following lines:
+ #
+ # syntax_theme: base16-ocean.light
+ # syntax_theme: base16-ocean.dark
+ # syntax_theme: base16-mocha.dark
+ # syntax_theme: base16-mocha.light
+ # syntax_theme: InspiredGitHub
+ # syntax_theme: "Solarized (dark)"
+ # syntax_theme: "Solarized (light)"
}
diff --git a/src/app/app.rs b/src/app/app.rs
index 73bbc6d..7f75c11 100644
--- a/src/app/app.rs
+++ b/src/app/app.rs
@@ -2,6 +2,7 @@ use {
super::*,
crate::{
browser::BrowserState,
+ cli::TriBool,
command::{Command, Sequence},
conf::Conf,
display::{Areas, Screen, W},
@@ -80,8 +81,8 @@ impl App {
PanelId::from(0),
Box::new(
BrowserState::new(
- con.launch_args.root.clone(),
- con.launch_args.tree_options.clone(),
+ con.initial_root.clone(),
+ con.initial_tree_options.clone(),
screen,
con,
&Dam::unlimited(),
@@ -663,10 +664,10 @@ impl App {
let event_source = EventSource::new()?;
let rx_events = event_source.receiver();
let mut dam = Dam::from(rx_events);
- let skin = AppSkin::new(conf, con.launch_args.color == Some(false));
+ let skin = AppSkin::new(conf, con.launch_args.color == TriBool::No);
let mut app_state = AppState {
stage: Stage::default(),
- root: con.launch_args.root.clone(),
+ root: con.initial_root.clone(),
other_panel_path: None,
};
diff --git a/src/app/app_context.rs b/src/app/app_context.rs
index 518bafa..d3424e3 100644
--- a/src/app/app_context.rs
+++ b/src/app/app_context.rs
@@ -1,19 +1,21 @@
use {
super::*,
crate::{
- cli::AppLaunchArgs,
+ cli::{Args, TriBool},
conf::Conf,
- errors::ConfError,
+ errors::*,
file_sum,
icon::*,
pattern::SearchModeMap,
path::SpecialPath,
skin::ExtColorMap,
+ tree::TreeOptions,
verb::VerbStore,
},
std::{
convert::{TryFrom, TryInto},
- path::PathBuf,
+ io,
+ path::{Path, PathBuf},
},
};
@@ -22,12 +24,18 @@ use {
/// life of the App
pub struct AppContext {
+ /// The initial tree root
+ pub initial_root: PathBuf,
+
+ /// Initial tree options
+ pub initial_tree_options: TreeOptions,
+
/// where's the config file we're using
/// This vec can't be empty
pub config_paths: Vec<PathBuf>,
/// all the arguments specified at launch
- pub launch_args: AppLaunchArgs,
+ pub launch_args: Args,
/// the verbs in use (builtins and configured ones)
pub verb_store: VerbStore,
@@ -82,10 +90,10 @@ pub struct AppContext {
impl AppContext {
pub fn from(
- launch_args: AppLaunchArgs,
+ launch_args: Args,
verb_store: VerbStore,
config: &Conf,
- ) -> Result<Self, ConfError> {
+ ) -> Result<Self, ProgramError> {
let config_paths = config.files.clone();
let standard_status = StandardStatus::new(&verb_store);
let true_colors = if let Some(value) = config.true_colors {
@@ -105,11 +113,12 @@ impl AppContext {
.map(|map| map.try_into())
.transpose()?
.unwrap_or_default();
- let ext_colors = ExtColorMap::try_from(&config.ext_colors)?;
+ let ext_colors = ExtColorMap::try_from(&config.ext_colors)
+ .map_err(ConfError::from)?;
let file_sum_threads_count = config.file_sum_threads_count
.unwrap_or(file_sum::DEFAULT_THREAD_COUNT);
if file_sum_threads_count < 1 || file_sum_threads_count > 50 {
- return Err(ConfError::InvalidThreadsCount{ count: file_sum_threads_count });
+ return Err(ConfError::InvalidThreadsCount{ count: file_sum_threads_count }.into());
}
let max_panels_count = config.max_panels_count
.unwrap_or(2)
@@ -122,7 +131,21 @@ impl AppContext {
let max_staged_count = config.max_staged_count
.unwrap_or(10_000)
.clamp(10, 100_000);
+ let initial_root = get_root_path(&launch_args)?;
+
+ // tree options are built from the default_flags
+ // found in the config file(s) (if any) then overriden
+ // by the cli args
+ let mut initial_tree_options = TreeOptions::default();
+ initial_tree_options.apply_config(config)?;
+ initial_tree_options.apply_launch_args(&launch_args);
+ if launch_args.color == TriBool::No {
+ initial_tree_options.show_selection_mark = true;
+ }
+
Ok(Self {
+ initial_root,
+ initial_tree_options,
config_paths,
launch_args,
verb_store,
@@ -165,3 +188,44 @@ fn are_true_colors_available() -> bool {
true
}
}
+
+fn get_root_path(cli_args: &Args) -> Result<PathBuf, ProgramError> {
+ let mut root = cli_args
+ .root
+ .as_ref()
+ .map_or(std::env::current_dir()?, PathBuf::from);
+ if !root.exists() {
+ return Err(TreeBuildError::FileNotFound {
+ path: format!("{:?}", &root),
+ }.into());
+ }
+ if !root.is_dir() {
+ // we try to open the parent directory if the passed file isn't one
+ if let Some(parent) = root.parent() {
+ info!("Passed path isn't a directory => opening parent instead");
+ root = parent.to_path_buf();
+ } else {
+ // let's give up
+ return Err(TreeBuildError::NotADirectory {
+ path: format!("{:?}", &root),
+ }.into());
+ }
+ }
+ Ok(canonicalize_root(&root)?)
+}
+
+#[cfg(not(windows))]
+fn canonicalize_root(root: &Path) -> io::Result<PathBuf> {
+ root.canonicalize()
+}
+
+#[cfg(windows)]
+fn canonicalize_root(root: &Path) -> io::Result<PathBuf> {
+ Ok(if root.is_relative() {
+ env::current_dir()?.join(root)
+ } else {
+ root.to_path_buf()
+ })
+}
+
+
diff --git a/src/cli/app_launch_args.rs b/src/cli/app_launch_args.rs
deleted file mode 100644
index 03b25ae..0000000
--- a/src/cli/app_launch_args.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use {
- crate::{
- tree::TreeOptions,
- },
- std::{
- path::PathBuf,
- },
-};
-
-
-/// the parsed program launch arguments which are kept for the
-/// life of the program
-pub struct AppLaunchArgs {
- pub root: PathBuf, // what should be the initial root
- pub file_export_path: Option<String>, // where to write the produced path (if required with --out) - deprecated
- pub cmd_export_path: Option<String>, // where to write the produced command (if required with --outcmd)
- pub tree_options: TreeOptions, // initial tree options
- pub commands: Option<String>, // commands passed as cli argument, still unparsed
- pub height: Option<u16>, // an optional height to replace the screen's one
- pub color: Option<bool>, // whether to display colors and styles
- pub listen: Option<String>, // if some, broot will start in serve mode on this socket
-}
diff --git a/src/cli/args.rs b/src/cli/args.rs
new file mode 100644
index 0000000..9ad810e
--- /dev/null
+++ b/src/cli/args.rs
@@ -0,0 +1,200 @@
+use {
+ std::{
+ path::PathBuf,
+ str::FromStr,
+ },
+};
+
+#[derive(Debug, clap::Parser)]
+/// A tree explorer and a customizable launcher
+///
+/// Complete documentation lives at https://dystroy.org/broot"
+#[clap(author, version, about)]
+pub struct Args {
+
+ /// Show the last modified date of files and directories"
+ #[clap(short, long, action)]
+ pub dates: bool,
+
+ /// Don't show the last modified date"
+ #[clap(short='D', long, action)]
+ pub no_dates: bool,
+
+ #[clap(short='f', long, action)]
+ /// Only show folders
+ pub only_folders: bool,
+
+ /// Show folders and files alike
+ #[clap(short='F', long, action)]
+ pub no_only_folders: bool,
+
+ /// Show filesystem info on top
+ #[clap(long, action)]
+ pub show_root_fs: bool,
+
+ /// Show git statuses on files and stats on repo
+ #[clap(short='g', long, action)]
+ pub show_git_info: bool,
+
+ /// Don't show git statuses on files and stats on repo
+ #[clap(short='G', long, action)]
+ pub no_show_git_info: bool,
+
+ #[clap(long, action)]
+ /// Only show files having an interesting git status, including hidden ones
+ pub git_status: bool,
+
+ #[clap(short='h', long, action)]
+ /// Show hidden files
+ pub hidden: bool,
+
+ #[clap(short='H', long, action)]
+ /// Don't show hidden files
+ pub no_hidden: bool,
+
+ #[clap(short='i', long, action)]
+ /// Show git ignored files
+ pub git_ignored: bool,
+
+ #[clap(short='I', long, action)]
+ /// Don't show git ignored files
+ pub no_git_ignored: bool,
+
+ #[clap(short='p', long, action)]
+ /// Show permissions
+ pub permissions: bool,
+
+ #[clap(short='P', long, action)]
+ /// Don't show permissions
+ pub no_permissions: bool,
+
+ #[clap(short='s', long, action)]
+ /// Show the size of files and directories
+ pub sizes: bool,
+
+ #[clap(short='S', long, action)]
+ /// Don't show sizes
+ pub no_sizes: bool,
+
+ #[clap(long, action)]
+ /// Sort by count (only show one level of the tree)
+ pub sort_by_count: bool,
+
+ #[clap(long, action)]
+ /// Sort by date (only show one level of the tree)
+ pub sort_by_date: bool,
+
+ #[clap(long, action)]
+ /// Sort by size (only show one level of the tree)
+ pub sort_by_size: bool,
+
+ /// Sort by size, show ignored and hidden files
+ #[clap(short, long, action)]
+ pub whale_spotting: bool,
+
+ /// Don't sort
+ #[clap(long, action)]
+ pub no_sort: bool,
+
+ /// Trim the root too and don't show a scrollbar
+ #[clap(short='t', long, action)]
+ pub trim_root: bool,
+
+ /// Don't trim the root level, show a scrollbar
+ #[clap(short='T', long, action)]
+ pub no_trim_root: bool,
+
+ /// Where to write the produced cmd (if any)
+ #[clap(long, value_parser)]
+ pub cmd_export_path: Option<PathBuf>,
+
+ /// Semicolon separated commands to execute
+ #[clap(short, long, value_parser)]
+ pub commands: Option<String>,
+
+ /// Whether to have styles and colors (auto is default and usually OK)
+ #[clap(long, arg_enum, value_parser, default_value="auto")]
+ pub color: TriBool,
+
+ /// Semicolon separated paths to specific config files"),
+ #[clap(long, value_parser)]
+ pub conf: Option<String>,
+
+ /// Height (if you don't want to fill the screen or for file export)
+ #[clap(long, value_parser)]
+ pub height: Option<u16>,
+
+ /// Install or reinstall the br shell function
+ #[clap(long, action)]
+ pub install: bool,
+
+ /// Where to write the produced cmd (if any)
+ #[clap(long, value_parser)]
+ pub set_install_state: Option<ShellInstallState>,
+
+ /// Print to stdout the br function for a given shell
+ #[clap(long, value_parser)]
+ pub print_shell_function: Option<String>,
+
+ /// A socket to listen to for commands
+ #[cfg(unix)]
+ #[clap(long, value_parser)]
+ pub listen: Option<String>,
+
+ /// Ask for the current root of the remote broot
+ #[cfg(unix)]
+ #[clap(long, action)]
+ pub get_root: bool,
+
+ /// A socket that broot sends commands to before quitting
+ #[cfg(unix)]
+ #[clap(long, value_parser)]
+ pub send: Option<String>,
+
+ /// Root Directory
+ #[clap(value_parser, value_name="FILE")]
+ pub root: Option<PathBuf>,
+}
+
+/// This is an Option<bool> but I didn't find any way to configure
+/// clap to parse an Option<T> as I want
+#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ArgEnum)]
+pub enum TriBool {
+ Auto,
+ Yes,
+ No,
+}
+impl TriBool {
+ pub fn unwrap_or_else<F>(self, f: F) -> bool
+ where
+ F: FnOnce() -> bool
+ {
+ match self {
+ Self::Auto => f(),
+ Self::Yes => true,
+ Self::No => false,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, clap::ValueEnum)]
+pub enum ShellInstallState {
+ Undefined, // before any install, this is the initial state
+ Refused,
+ Installed,
+}
+impl FromStr for ShellInstallState {
+ type Err = String;
+ fn from_str(state: &str) -> Result<Self, Self::Err> {
+ match state {
+ "undefined" => Ok(Self::Undefined),
+ "refused" => Ok(Self::Refused),
+ "installed" => Ok(Self::Installed),
+ _ => Err(
+ // not supposed to happen because claps check the values
+ format!("unexpected install state: {:?}", state)
+ ),
+ }
+ }
+}
+
diff --git a/src/cli/clap_args.rs b/src/cli/clap_args.rs
deleted file mode 100644
index 0ac9524..0000000
--- a/src/cli/clap_args.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-/// this module generate the clap App, which defines
-/// launch arguments
-
-/// Declare the possible CLI arguments
-pub fn clap_app() -> clap::Command<'static> {
- let app = clap::Command::new("broot")
- .version(env!("CARGO_PKG_VERSION"))
- .author("dystroy <denys.seguret@gmail.com>")
- .about(
- "A tree explorer and a customizable launcher\n\
- Complete documentation lives at https://dystroy.org/broot"
- )
- .arg(clap::Arg::new("ROOT").help("sets the root directory"))
- // tree flags
- .arg(
- clap::Arg::new("dates")
- .short('d')
- .long("dates")
- .help("Show the last modified date of files and directories"),
- )
- .arg(
- clap::Arg::new("no-dates")
- .short('D')
- .long("no-dates")
- .help("Don't show last modified date"),
- )
- .arg(
- clap::Arg::new("only-folders")
- .short('f')
- .long("only-folders")
- .help("Only show folders"),
- )
- .arg(
- clap::Arg::new("no-only-folders")
- .short('F')
- .long("no-only-folders")
- .help("Show folders and files alike"),
- )
- .arg(
- clap::Arg::new("show-root-fs")
- .long("show-root-fs")
- .help("Show filesystem info on top"),
- )
- .arg(
- clap::Arg::new("show-git-info")
- .short('g')
- .long("show-git-info")
- .help("Show git statuses on files and stats on repo"),
- )
- .arg(
- clap::Arg::new("no-show-git-info")
- .short('G')
- .long("no-show-git-info")
- .help("Don't show git statuses on files"),
- )
- .arg(
- clap::Arg::new("git-status")
- .long("git-status")
- .help("Only show files having an interesting git status, including hidden ones"),
- )
- .arg(
- clap::Arg::new("hidden")
- .short('h')
- .long("hidden")
- .help("Show hidden files"),
- )
- .arg(
- clap::Arg::new("no-hidden")
- .short('H')
- .long("no-hidden")
- .help("Don't show hidden files"),
- )
- .arg(
- clap::Arg::new("show-gitignored")
- .short('i')
- .long("show-gitignored")
- .help("Show files which should be ignored according to git"),
- )
- .arg(
- clap::Arg::new("no-show-gitignored")
- .short('I')
- .long("no-show-gitignored")
- .help("Don't show gitignored files"),
- )
- .arg(
- clap::Arg::new("permissions")
- .short('p')
- .long("permissions")
- .help("Show permissions, with owner and group"),
- )
- .arg(
- clap::Arg::new("no-permissions")
- .short('P')
- .long("no-permissions")
- .help("Don't show permissions"),
- )
- .arg(
- clap::Arg::new("sizes")
- .short('s')
- .long("sizes")
- .help("Show the size of files and directories"),
- )
- .arg(
- clap::Arg::new("no-sizes")
- .short('S')
- .long("no-sizes")
- .help("Don't show sizes"),
- )
- .arg(
- clap::Arg::new("sort-by-count")
- .long("sort-by-count")
- .help("Sort by count (only show one level of the tree)"),
- )
- .arg(
- clap::Arg::new("sort-by-date")
- .long("sort-by-date")
- .help("Sort by date (only show one level of the tree)"),
- )
- .arg(
- clap::Arg::new("sort-by-size")
- .long("sort-by-size")
- .help("Sort by size (only show one level of the tree)"),
- )
- .arg(
- clap::Arg::new("whale-spotting")
- .short('w')
- .long("whale-spotting")
- .help("Sort by size, show ignored and hidden files"),
- )
- .arg(
- clap::Arg::new("no-sort")
- .long("no-sort")
- .help("Don't sort"),
- )
- .arg(
- clap::Arg::new("trim-root")
- .short('t')
- .long("trim-root")
- .help("Trim the root too and don't show a scrollbar"),
- )
- .arg(
- clap::Arg::new("no-trim-root")
- .short('T')
- .long("no-trim-root")
- .help("Don't trim the root level, show a scrollbar"),
- )
- // other options
- .arg(
- clap::Arg::new("cmd-export-path")
- .long("outcmd")
- .takes_value(true)
- .help("Where to write the produced cmd (if any)"),
- )
- .arg(
- clap::Arg::new("commands")
- .short('c')
- .long("cmd")
- .takes_value(true)
- .help("Semicolon separated commands to execute"),
- )
- .arg(
- clap::Arg::new("color")
- .long("color")
- .takes_value(true)
- .possible_values(&["yes", "no", "auto"])
- .default_value("auto")
- .help("Whether to have styles and colors (auto is default and usually OK)"),
- )
- .arg(
- clap::Arg::new("conf")
- .long("conf")
- .takes_value(true)
- .help("Semicolon separated paths to specific config files"),
- )
- .arg(
- clap::Arg::new("height")
- .long("height")
- .help("Height (if you don't want to fill the screen or for file export)")
- .takes_value(true),
- )
- .arg(
- clap::Arg::new("file-export-path") // deprecated since broot 1.6
- .short('o')
- .long("out")
- .takes_value(true)
- .hide(true)
- .help("Where to write the produced path (if any)"),
- )
- .arg(
- clap::Arg::new("install")
- .long("install")
- .help("Install or reinstall the br shell function"),
- )
- .arg(
- clap::Arg::new("set-install-state")
- .long("set-install-state")
- .takes_value(true)
- .value_name("state")
- .possible_values(&["undefined", "refused", "installed"])
- .help("Set the installation state (for use in install script)"),
- )
- .arg(
- clap::Arg::new("print-shell-function")
- .long("print-shell-function")
- .takes_value(true)
- .value_name("shell")
- .help("Print to stdout the br function for a given shell"),
- )
- .setting(clap::AppSettings::DeriveDisplayOrder);
- #[cfg(unix)]
- let app = app
- .arg(
- clap::Arg::new("listen")
- .long("listen")
- .takes_value(true)
- .help("Listen for commands")
- )
- .arg(
- clap::Arg::new("get-root")
- .long("get-root")
- .help("Ask for the current root of the remote broot")
- )
- .arg(
- clap::Arg::new("send")
- .long("send")
- .takes_value(true)
- .help("send commands to a remote broot then quits")
- );
- app
-}
-
-#[test]
-fn verify_app() {
- clap_app().debug_assert();
-}
diff --git a/src/cli/install_launch_args.rs b/src/cli/install_launch_args.rs
index c688e12..e5b1d01 100644
--- a/src/cli/install_launch_args.rs
+++ b/src/cli/install_launch_args.rs
@@ -3,12 +3,10 @@
use {
crate::{
errors::ProgramError,
- shell_install::ShellInstallState,
+ cli::{Args, ShellInstallState},
},
- clap::{self, ArgMatches},
std::{
env,
- str::FromStr,
},
};
@@ -21,7 +19,7 @@ pub struct InstallLaunchArgs {
pub print_shell_function: Option<String>, // shell function to print on stdout
}
impl InstallLaunchArgs {
- pub fn from(cli_args: &ArgMatches) -> Result<Self, ProgramError> {
+ pub fn from(args: &Args) -> Result<Self, ProgramError> {
let mut install = None;
if let Ok(s) = env::var("BR_INSTALL") {
if s == "yes" {
@@ -33,18 +31,13 @@ impl InstallLaunchArgs {
}
}
// the cli arguments may override the env var value
- if cli_args.is_present("install") {
+ if args.install {
install = Some(true);
- } else if cli_args.value_of("cmd-export-path").is_some() {
+ } else if args.cmd_export_path.is_some() {
install = Some(false);
}
- let print_shell_function = cli_args
- .value_of("print-shell-function")
- .map(str::to_string);
- let set_install_state = cli_args
- .value_of("set-install-state")
- .map(ShellInstallState::from_str)
- .transpose()?;
+ let print_shell_function = args.print_shell_function.clone();
+ let set_install_state = args.set_install_state;
Ok(Self {
install,
set_install_state,
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 29c5152..310a7ed 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -1,12 +1,13 @@
//! this module manages reading and translating
//! the arguments passed on launch of the application.
-pub mod clap_args;
-mod app_launch_args;
+//mod app_launch_args;
+mod args;
mod install_launch_args;
pub use {
- app_launch_args::*,
+ //app_launch_args::*,
+ args::*,
install_launch_args::*,
};
@@ -15,13 +16,12 @@ use {
app::{App, AppContext},
conf::Conf,
display,
- errors::{ProgramError, TreeBuildError},
+ errors::ProgramError,
launchable::Launchable,
- shell_install::ShellInstall,
- tree::TreeOptions,
+ shell_install::{ShellInstall, write_state},
verb::VerbStore,
},
- clap::{self, ArgMatches},
+ clap::Parser,
crossterm::{
self,
cursor,
@@ -30,65 +30,25 @@ use {
QueueableCommand,
},
std::{
- env,
io::{self, Write},
- path::{Path, PathBuf},
+ path::PathBuf,
},
};
-#[cfg(not(windows))]
-fn canonicalize_root(root: &Path) -> io::Result<PathBuf> {
- root.canonicalize()
-}
-
-#[cfg(windows)]
-fn canonicalize_root(root: &Path) -> io::Result<PathBuf> {
- Ok(if root.is_relative() {
- env::current_dir()?.join(root)
- } else {
- root.to_path_buf()
- })
-}
-
-fn get_root_path(cli_args: &ArgMatches) -> Result<PathBuf, ProgramError> {
- let mut root = cli_args
- .value_of("ROOT")
- .map_or(env::current_dir()?, PathBuf::from);
- if !root.exists() {
- return Err(TreeBuildError::FileNotFound {
- path: format!("{:?}", &root),
- }.into());
- }
- if !root.is_dir() {
- // we try to open the parent directory if the passed file isn't one
- if let Some(parent) = root.parent() {
- info!("Passed path isn't a directory => opening paren