2017-10-21 10:16:03 +02:00
|
|
|
// Copyright (c) 2017 fd developers
|
|
|
|
// Licensed under the Apache License, Version 2.0
|
|
|
|
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
|
|
|
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
|
|
|
// at your option. All files in the project carrying such
|
|
|
|
// notice may not be copied, modified, or distributed except
|
|
|
|
// according to those terms.
|
|
|
|
|
2017-10-05 05:14:01 +02:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2017-10-04 14:31:08 +02:00
|
|
|
use clap::{App, AppSettings, Arg};
|
|
|
|
|
2017-10-05 05:14:01 +02:00
|
|
|
struct Help {
|
|
|
|
short: &'static str,
|
|
|
|
long: &'static str,
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! doc {
|
|
|
|
($map:expr, $name:expr, $short:expr) => {
|
|
|
|
doc!($map, $name, $short, $short)
|
|
|
|
};
|
|
|
|
($map:expr, $name:expr, $short:expr, $long:expr) => {
|
|
|
|
$map.insert($name, Help {
|
|
|
|
short: $short,
|
|
|
|
long: concat!($long, "\n ")
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-10-04 14:31:08 +02:00
|
|
|
pub fn build_app() -> App<'static, 'static> {
|
2017-10-05 05:14:01 +02:00
|
|
|
let helps = usage();
|
|
|
|
let arg = |name| {
|
|
|
|
Arg::with_name(name).help(helps[name].short).long_help(
|
|
|
|
helps[name].long,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2017-10-04 14:31:08 +02:00
|
|
|
App::new("fd")
|
2017-10-05 21:29:29 +02:00
|
|
|
.version(crate_version!())
|
|
|
|
.usage("fd [FLAGS/OPTIONS] [<pattern>] [<path>]")
|
|
|
|
.setting(AppSettings::ColoredHelp)
|
|
|
|
.setting(AppSettings::DeriveDisplayOrder)
|
2017-10-05 05:14:01 +02:00
|
|
|
.arg(arg("hidden").long("hidden").short("H"))
|
|
|
|
.arg(arg("no-ignore").long("no-ignore").short("I"))
|
2017-10-12 08:01:51 +02:00
|
|
|
.arg(
|
|
|
|
arg("rg-alias-hidden-ignore")
|
|
|
|
.short("u")
|
|
|
|
.multiple(true)
|
|
|
|
.hidden(true),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
arg("case-sensitive")
|
|
|
|
.long("case-sensitive")
|
|
|
|
.short("s")
|
|
|
|
.overrides_with("ignore-case"),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
arg("ignore-case")
|
|
|
|
.long("ignore-case")
|
|
|
|
.short("i")
|
|
|
|
.overrides_with("case-sensitive"),
|
|
|
|
)
|
2017-10-05 05:14:01 +02:00
|
|
|
.arg(arg("absolute-path").long("absolute-path").short("a"))
|
|
|
|
.arg(arg("follow").long("follow").short("L").alias("dereference"))
|
|
|
|
.arg(arg("full-path").long("full-path").short("p"))
|
|
|
|
.arg(arg("null_separator").long("print0").short("0"))
|
|
|
|
.arg(arg("depth").long("max-depth").short("d").takes_value(true))
|
2017-10-05 21:29:29 +02:00
|
|
|
.arg(
|
2017-10-05 05:14:01 +02:00
|
|
|
arg("file-type")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("type")
|
|
|
|
.short("t")
|
|
|
|
.takes_value(true)
|
2017-10-05 21:35:22 +02:00
|
|
|
.value_name("filetype")
|
2017-10-09 21:25:30 +02:00
|
|
|
.possible_values(&["f", "file", "d", "directory", "l", "symlink"])
|
2017-10-05 05:14:01 +02:00
|
|
|
.hide_possible_values(true),
|
2017-10-05 21:29:29 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2017-10-05 05:14:01 +02:00
|
|
|
arg("extension")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("extension")
|
|
|
|
.short("e")
|
|
|
|
.takes_value(true)
|
2017-10-05 05:14:01 +02:00
|
|
|
.value_name("ext"),
|
2017-10-05 21:29:29 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2017-10-05 05:14:01 +02:00
|
|
|
arg("color")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("color")
|
|
|
|
.short("c")
|
|
|
|
.takes_value(true)
|
2017-10-05 21:35:22 +02:00
|
|
|
.value_name("when")
|
2017-10-04 14:31:08 +02:00
|
|
|
.possible_values(&["never", "auto", "always"])
|
2017-10-05 05:14:01 +02:00
|
|
|
.hide_possible_values(true),
|
2017-10-05 21:29:29 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2017-10-05 05:14:01 +02:00
|
|
|
arg("threads")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("threads")
|
|
|
|
.short("j")
|
|
|
|
.takes_value(true)
|
2017-10-05 05:14:01 +02:00
|
|
|
.value_name("num"),
|
2017-10-05 21:29:29 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2017-10-05 05:14:01 +02:00
|
|
|
arg("max-buffer-time")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("max-buffer-time")
|
|
|
|
.takes_value(true)
|
2017-10-05 05:14:01 +02:00
|
|
|
.hidden(true),
|
2017-10-05 21:29:29 +02:00
|
|
|
)
|
2017-10-14 20:04:04 +02:00
|
|
|
.arg(arg("exec").long("exec").short("x").takes_value(true))
|
2017-10-05 05:14:01 +02:00
|
|
|
.arg(arg("pattern"))
|
|
|
|
.arg(arg("path"))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
|
|
|
fn usage() -> HashMap<&'static str, Help> {
|
|
|
|
let mut h = HashMap::new();
|
|
|
|
doc!(h, "hidden"
|
|
|
|
, "Search hidden files and directories"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Include hidden directories and files in the search results (default: hidden files \
|
|
|
|
and directories are skipped).");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "no-ignore"
|
|
|
|
, "Do not respect .(git)ignore files"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Show search results from files and directories that would otherwise be ignored by \
|
2017-10-05 05:14:01 +02:00
|
|
|
'.*ignore' files.");
|
|
|
|
doc!(h, "case-sensitive"
|
|
|
|
, "Case-sensitive search (default: smart case)"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Perform a case-sensitive search. By default, fd uses case-insensitive searches, \
|
2017-10-14 12:09:34 +02:00
|
|
|
unless the pattern contains an uppercase character (smart case).");
|
2017-10-12 01:21:44 +02:00
|
|
|
doc!(h, "ignore-case"
|
|
|
|
, "Case-insensitive search (default: smart case)"
|
|
|
|
, "Perform a case-insensitive search. By default, fd uses case-insensitive searches, \
|
2017-10-14 12:09:34 +02:00
|
|
|
unless the pattern contains an uppercase character (smart case).");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "absolute-path"
|
|
|
|
, "Show absolute instead of relative paths"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Shows the full path starting from the root as opposed to relative paths.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "follow"
|
|
|
|
, "Follow symbolic links"
|
|
|
|
, "By default, fd does not descent into symlinked directories. Using this flag, symbolic \
|
2017-10-07 15:15:30 +02:00
|
|
|
links are also traversed.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "full-path"
|
|
|
|
, "Search full path (default: file-/dirname only)"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "By default, the search pattern is only matched against the filename (or directory \
|
|
|
|
name). Using this flag, the pattern is matched against the full path.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "null_separator"
|
|
|
|
, "Separate results by the null character"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Separate search results by the null character (instead of newlines). Useful for \
|
|
|
|
piping results to 'xargs'.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "depth"
|
|
|
|
, "Set maximum search depth (default: none)"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Limit the directory traversal to a given depth. By default, there is no limit \
|
|
|
|
on the search depth.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "file-type"
|
2017-10-09 21:25:30 +02:00
|
|
|
, "Filter by type: f(ile), d(irectory), (sym)l(ink)"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "Filter the search by type:\n \
|
|
|
|
'f' or 'file': regular files\n \
|
|
|
|
'd' or 'directory': directories\n \
|
2017-10-09 21:25:30 +02:00
|
|
|
'l' or 'symlink': symbolic links");
|
2017-10-14 18:04:11 +02:00
|
|
|
doc!(h, "exec"
|
|
|
|
, "Execute each discovered path using the argument that follows as the command expression."
|
2017-10-14 20:04:04 +02:00
|
|
|
, "Execute each discovered path using the argument that follows as the command \
|
|
|
|
expression.\n \
|
|
|
|
The following are valid tokens that can be used within the expression for generating \
|
|
|
|
commands:\n \
|
2017-10-14 18:04:11 +02:00
|
|
|
'{}': places the input in the location of this token\n \
|
|
|
|
'{.}': removes the extension from the input\n \
|
|
|
|
'{/}': places the basename of the input\n \
|
|
|
|
'{//}': places the parent of the input\n \
|
|
|
|
'{/.}': places the basename of the input, without the extension\n");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "extension"
|
|
|
|
, "Filter by file extension"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "(Additionally) filter search results by their file extension.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "color"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "When to use colors: never, *auto*, always"
|
|
|
|
, "Declare when to use color for the pattern match output:\n \
|
|
|
|
'auto': show colors if the output goes to an interactive console (default)\n \
|
|
|
|
'never': do not use colorized output\n \
|
|
|
|
'always': always use colorized output");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "threads"
|
2017-10-14 18:04:11 +02:00
|
|
|
, "Set number of threads to use for searching & executing"
|
2017-10-14 20:04:04 +02:00
|
|
|
, "Set number of threads to use for searching & executing (default: number of available \
|
|
|
|
CPU cores)");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "max-buffer-time"
|
|
|
|
, "the time (in ms) to buffer, before streaming to the console"
|
|
|
|
, "Amount of time in milliseconds to buffer, before streaming the search results to\
|
2017-10-07 15:15:30 +02:00
|
|
|
the console.");
|
2017-10-05 05:14:01 +02:00
|
|
|
doc!(h, "pattern"
|
|
|
|
, "the search pattern, a regular expression (optional)");
|
|
|
|
doc!(h, "path"
|
|
|
|
, "the root directory for the filesystem search (optional)"
|
2017-10-07 15:15:30 +02:00
|
|
|
, "The directory where the filesystem search is rooted (optional). \
|
|
|
|
If omitted, search the current working directory.");
|
2017-10-11 13:07:50 +02:00
|
|
|
doc!(h, "rg-alias-hidden-ignore"
|
|
|
|
, "Alias for no-ignore and/or hidden"
|
|
|
|
, "Alias for no-ignore ('u') and no-ignore and hidden ('uu')");
|
2017-10-05 05:14:01 +02:00
|
|
|
|
|
|
|
h
|
2017-10-05 21:29:29 +02:00
|
|
|
}
|