2019-01-05 18:24:33 +01:00
|
|
|
use clap::{crate_version, App, AppSettings, Arg};
|
2017-10-04 14:31:08 +02:00
|
|
|
|
|
|
|
pub fn build_app() -> App<'static, 'static> {
|
2020-12-06 12:02:22 +01:00
|
|
|
let clap_color_setting = if std::env::var_os("NO_COLOR").is_none() {
|
|
|
|
AppSettings::ColoredHelp
|
|
|
|
} else {
|
|
|
|
AppSettings::ColorNever
|
|
|
|
};
|
2020-10-16 16:11:21 +02:00
|
|
|
|
2020-01-01 11:17:16 +01:00
|
|
|
let mut app = App::new("fd")
|
2017-10-05 21:29:29 +02:00
|
|
|
.version(crate_version!())
|
2017-12-10 06:40:13 +01:00
|
|
|
.usage("fd [FLAGS/OPTIONS] [<pattern>] [<path>...]")
|
2020-10-16 16:11:21 +02:00
|
|
|
.setting(clap_color_setting)
|
2017-10-05 21:29:29 +02:00
|
|
|
.setting(AppSettings::DeriveDisplayOrder)
|
2019-01-01 17:40:53 +01:00
|
|
|
.after_help(
|
2020-04-03 11:24:47 +02:00
|
|
|
"Note: `fd -h` prints a short and concise overview while `fd --help` gives all \
|
|
|
|
details.",
|
2019-01-01 17:40:53 +01:00
|
|
|
)
|
2019-10-08 14:40:16 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("hidden")
|
2019-10-08 14:40:16 +02:00
|
|
|
.long("hidden")
|
|
|
|
.short("H")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("hidden")
|
|
|
|
.help("Search hidden files and directories")
|
|
|
|
.long_help(
|
|
|
|
"Include hidden directories and files in the search results (default: \
|
|
|
|
hidden files and directories are skipped). Files and directories are \
|
2021-08-09 15:49:48 +02:00
|
|
|
considered to be hidden if their name starts with a `.` sign (dot). \
|
|
|
|
Flag can be overridden with --no-hidden.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("no-hidden")
|
|
|
|
.long("no-hidden")
|
|
|
|
.overrides_with("no-hidden")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Overrides --hidden.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("no-ignore")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("no-ignore")
|
|
|
|
.short("I")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("no-ignore")
|
|
|
|
.help("Do not respect .(git|fd)ignore files")
|
|
|
|
.long_help(
|
|
|
|
"Show search results from files and directories that would otherwise be \
|
2021-08-09 15:49:48 +02:00
|
|
|
ignored by '.gitignore', '.ignore', '.fdignore', or the global ignore file. \
|
|
|
|
Flag can be overridden with --ignore.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("ignore")
|
|
|
|
.long("ignore")
|
|
|
|
.overrides_with("ignore")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Overrides --no-ignore.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("no-ignore-vcs")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("no-ignore-vcs")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("no-ignore-vcs")
|
2020-04-16 09:58:15 +02:00
|
|
|
.hidden_short_help(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.long_help(
|
|
|
|
"Show search results from files and directories that would otherwise be \
|
2021-08-09 15:49:48 +02:00
|
|
|
ignored by '.gitignore' files. Flag can be overridden with --ignore-vcs.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("ignore-vcs")
|
|
|
|
.long("ignore-vcs")
|
|
|
|
.overrides_with("ignore-vcs")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Overrides --no-ignore-vcs.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2019-10-08 14:40:16 +02:00
|
|
|
)
|
2020-04-25 21:32:17 +02:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("no-global-ignore-file")
|
|
|
|
.long("no-global-ignore-file")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help("Do not respect the global ignore file."),
|
|
|
|
)
|
2017-10-12 08:01:51 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("rg-alias-hidden-ignore")
|
2017-10-12 08:01:51 +02:00
|
|
|
.short("u")
|
2019-09-17 21:57:10 +02:00
|
|
|
.long("unrestricted")
|
2017-10-12 08:01:51 +02:00
|
|
|
.multiple(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Alias for '--no-ignore'. Can be repeated. '-uu' is an alias for \
|
|
|
|
'--no-ignore --hidden'.",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("case-sensitive")
|
2017-10-12 08:01:51 +02:00
|
|
|
.long("case-sensitive")
|
|
|
|
.short("s")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with_all(&["ignore-case", "case-sensitive"])
|
|
|
|
.help("Case-sensitive search (default: smart case)")
|
|
|
|
.long_help(
|
|
|
|
"Perform a case-sensitive search. By default, fd uses case-insensitive \
|
|
|
|
searches, unless the pattern contains an uppercase character (smart \
|
|
|
|
case).",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("ignore-case")
|
2017-10-12 08:01:51 +02:00
|
|
|
.long("ignore-case")
|
|
|
|
.short("i")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with_all(&["case-sensitive", "ignore-case"])
|
|
|
|
.help("Case-insensitive search (default: smart case)")
|
|
|
|
.long_help(
|
|
|
|
"Perform a case-insensitive search. By default, fd uses case-insensitive \
|
|
|
|
searches, unless the pattern contains an uppercase character (smart \
|
|
|
|
case).",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
2019-09-15 15:37:08 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("glob")
|
2019-09-15 15:37:08 +02:00
|
|
|
.long("glob")
|
|
|
|
.short("g")
|
2019-10-08 14:40:16 +02:00
|
|
|
.conflicts_with("fixed-strings")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("glob")
|
|
|
|
.help("Glob-based search (default: regular expression)")
|
|
|
|
.long_help("Perform a glob-based search instead of a regular expression search."),
|
2019-09-15 15:37:08 +02:00
|
|
|
)
|
2019-09-15 15:48:34 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("regex")
|
2019-09-15 15:48:34 +02:00
|
|
|
.long("regex")
|
2019-10-08 14:40:16 +02:00
|
|
|
.overrides_with_all(&["glob", "regex"])
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Perform a regular-expression based search (default). This can be used to \
|
|
|
|
override --glob.",
|
|
|
|
),
|
2019-09-15 15:48:34 +02:00
|
|
|
)
|
2018-09-27 23:01:38 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("fixed-strings")
|
2018-02-10 15:19:53 +01:00
|
|
|
.long("fixed-strings")
|
|
|
|
.short("F")
|
2019-10-08 14:40:16 +02:00
|
|
|
.alias("literal")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("fixed-strings")
|
2020-04-16 09:58:15 +02:00
|
|
|
.hidden_short_help(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.long_help(
|
2020-12-06 14:57:47 +01:00
|
|
|
"Treat the pattern as a literal string instead of a regular expression. Note \
|
|
|
|
that this also performs substring comparison. If you want to match on an \
|
|
|
|
exact filename, consider using '--glob'.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
2019-10-09 12:33:27 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("absolute-path")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("absolute-path")
|
|
|
|
.short("a")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("absolute-path")
|
|
|
|
.help("Show absolute instead of relative paths")
|
|
|
|
.long_help(
|
2021-08-09 15:49:48 +02:00
|
|
|
"Shows the full path starting from the root as opposed to relative paths. \
|
|
|
|
Flag can be overridden with --relative-path.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("relative-path")
|
|
|
|
.long("relative-path")
|
|
|
|
.overrides_with("relative-path")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Overrides --absolute-path.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
2020-04-02 21:40:57 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("list-details")
|
2020-04-03 09:39:33 +02:00
|
|
|
.long("list-details")
|
2020-04-02 21:40:57 +02:00
|
|
|
.short("l")
|
2020-04-03 11:24:47 +02:00
|
|
|
.conflicts_with("absolute-path")
|
2020-04-03 11:28:01 +02:00
|
|
|
.help("Use a long listing format with file metadata")
|
2020-04-03 11:24:47 +02:00
|
|
|
.long_help(
|
|
|
|
"Use a detailed listing format like 'ls -l'. This is basically an alias \
|
|
|
|
for '--exec-batch ls -l' with some additional 'ls' options. This can be \
|
|
|
|
used to see more metadata, to show symlink targets and to achieve a \
|
|
|
|
deterministic sort order.",
|
|
|
|
),
|
2020-04-02 21:40:57 +02:00
|
|
|
)
|
2019-10-09 12:33:27 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("follow")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("follow")
|
|
|
|
.short("L")
|
|
|
|
.alias("dereference")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("follow")
|
|
|
|
.help("Follow symbolic links")
|
|
|
|
.long_help(
|
|
|
|
"By default, fd does not descend into symlinked directories. Using this \
|
2021-08-09 15:49:48 +02:00
|
|
|
flag, symbolic links are also traversed. \
|
|
|
|
Flag can be overriden with --no-follow.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("no-follow")
|
|
|
|
.long("no-follow")
|
|
|
|
.overrides_with("no-follow")
|
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Overrides --follow.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("full-path")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("full-path")
|
|
|
|
.short("p")
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("full-path")
|
|
|
|
.help("Search full path (default: file-/dirname only)")
|
|
|
|
.long_help(
|
|
|
|
"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.",
|
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("null_separator")
|
2019-10-09 12:33:27 +02:00
|
|
|
.long("print0")
|
|
|
|
.short("0")
|
2020-04-02 21:40:57 +02:00
|
|
|
.overrides_with("print0")
|
2020-04-03 11:24:47 +02:00
|
|
|
.conflicts_with("list-details")
|
2021-02-14 20:02:37 +01:00
|
|
|
.hidden_short_help(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.help("Separate results by the null character")
|
|
|
|
.long_help(
|
|
|
|
"Separate search results by the null character (instead of newlines). \
|
|
|
|
Useful for piping results to 'xargs'.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
2020-04-15 16:17:01 +02:00
|
|
|
Arg::with_name("max-depth")
|
2020-04-03 11:24:47 +02:00
|
|
|
.long("max-depth")
|
|
|
|
.short("d")
|
|
|
|
.takes_value(true)
|
2020-04-15 16:17:01 +02:00
|
|
|
.value_name("depth")
|
2020-04-03 11:24:47 +02:00
|
|
|
.help("Set maximum search depth (default: none)")
|
|
|
|
.long_help(
|
|
|
|
"Limit the directory traversal to a given depth. By default, there is no \
|
|
|
|
limit on the search depth.",
|
|
|
|
),
|
2019-10-09 12:33:27 +02:00
|
|
|
)
|
2018-09-13 18:19:17 +02:00
|
|
|
// support --maxdepth as well, for compatibility with rg
|
2017-10-05 21:29:29 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("rg-depth")
|
2018-09-13 18:19:17 +02:00
|
|
|
.long("maxdepth")
|
|
|
|
.hidden(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.takes_value(true)
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
2020-04-15 16:17:01 +02:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("min-depth")
|
|
|
|
.long("min-depth")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("depth")
|
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Only show search results starting at the given depth. \
|
|
|
|
See also: '--max-depth' and '--exact-depth'",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("exact-depth")
|
|
|
|
.long("exact-depth")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("depth")
|
|
|
|
.hidden_short_help(true)
|
|
|
|
.conflicts_with_all(&["max-depth", "min-depth"])
|
|
|
|
.long_help(
|
|
|
|
"Only show search results at the exact given depth. This is an alias for \
|
|
|
|
'--min-depth <depth> --max-depth <depth>'.",
|
|
|
|
),
|
|
|
|
)
|
2020-10-25 08:16:01 +01:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("prune")
|
|
|
|
.long("prune")
|
|
|
|
.conflicts_with_all(&["size", "exact-depth"])
|
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help("Do not traverse into matching directories.")
|
|
|
|
)
|
2018-09-27 23:01:38 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("file-type")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("type")
|
|
|
|
.short("t")
|
2018-01-01 12:09:33 +01:00
|
|
|
.multiple(true)
|
|
|
|
.number_of_values(1)
|
2017-10-04 14:31:08 +02:00
|
|
|
.takes_value(true)
|
2017-10-05 21:35:22 +02:00
|
|
|
.value_name("filetype")
|
2018-03-25 16:36:37 +02:00
|
|
|
.possible_values(&[
|
|
|
|
"f",
|
|
|
|
"file",
|
|
|
|
"d",
|
|
|
|
"directory",
|
|
|
|
"l",
|
|
|
|
"symlink",
|
|
|
|
"x",
|
|
|
|
"executable",
|
2018-08-19 17:05:04 +02:00
|
|
|
"e",
|
|
|
|
"empty",
|
2020-04-16 09:41:24 +02:00
|
|
|
"s",
|
|
|
|
"socket",
|
|
|
|
"p",
|
|
|
|
"pipe",
|
2018-09-27 23:01:38 +02:00
|
|
|
])
|
2020-04-03 11:24:47 +02:00
|
|
|
.hide_possible_values(true)
|
|
|
|
.help(
|
|
|
|
"Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \
|
2020-04-16 09:41:24 +02:00
|
|
|
empty (e), socket (s), pipe (p)",
|
2020-04-03 11:24:47 +02:00
|
|
|
)
|
|
|
|
.long_help(
|
|
|
|
"Filter the search by type (multiple allowable filetypes can be specified):\n \
|
|
|
|
'f' or 'file': regular files\n \
|
|
|
|
'd' or 'directory': directories\n \
|
|
|
|
'l' or 'symlink': symbolic links\n \
|
|
|
|
'x' or 'executable': executables\n \
|
2020-04-16 09:41:24 +02:00
|
|
|
'e' or 'empty': empty files or directories\n \
|
|
|
|
's' or 'socket': socket\n \
|
|
|
|
'p' or 'pipe': named pipe (FIFO)",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("extension")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("extension")
|
|
|
|
.short("e")
|
2018-01-01 12:09:33 +01:00
|
|
|
.multiple(true)
|
|
|
|
.number_of_values(1)
|
2017-10-04 14:31:08 +02:00
|
|
|
.takes_value(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.value_name("ext")
|
|
|
|
.help("Filter by file extension")
|
|
|
|
.long_help(
|
|
|
|
"(Additionally) filter search results by their file extension. Multiple \
|
2020-12-06 12:20:50 +01:00
|
|
|
allowable file extensions can be specified.\n\
|
|
|
|
If you want to search for files without extension, \
|
|
|
|
you can use the regex '^[^.]+$' as a normal search pattern.",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("exec")
|
2017-10-22 23:00:19 +02:00
|
|
|
.long("exec")
|
|
|
|
.short("x")
|
2017-11-15 03:19:28 +01:00
|
|
|
.min_values(1)
|
2017-11-03 01:39:03 +01:00
|
|
|
.allow_hyphen_values(true)
|
|
|
|
.value_terminator(";")
|
2020-04-02 21:40:57 +02:00
|
|
|
.value_name("cmd")
|
2020-04-03 11:24:47 +02:00
|
|
|
.conflicts_with("list-details")
|
2021-02-13 21:25:50 +01:00
|
|
|
.help("Execute a command for each search result")
|
2020-04-03 11:24:47 +02:00
|
|
|
.long_help(
|
2021-08-08 22:49:32 +02:00
|
|
|
"Execute a command for each search result in parallel (use --threads=1 for sequential command execution). \
|
|
|
|
All positional arguments following --exec are considered to be arguments to the command - not to fd. \
|
|
|
|
It is therefore recommended to place the '-x'/'--exec' option last.\n\
|
|
|
|
The following placeholders are substituted before the command is executed:\n \
|
|
|
|
'{}': path (of the current search result)\n \
|
2020-04-03 11:24:47 +02:00
|
|
|
'{/}': basename\n \
|
|
|
|
'{//}': parent directory\n \
|
|
|
|
'{.}': path without file extension\n \
|
2021-08-08 22:49:32 +02:00
|
|
|
'{/.}': basename without file extension\n\n\
|
|
|
|
If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\
|
|
|
|
Examples:\n\n \
|
|
|
|
- find all *.zip files and unzip them:\n\n \
|
|
|
|
fd -e zip -x unzip\n\n \
|
|
|
|
- find *.h and *.cpp files and run \"clang-format -i ..\" for each of them:\n\n \
|
|
|
|
fd -e h -e cpp -x clang-format -i\n\n \
|
|
|
|
- Convert all *.jpg files to *.png files:\n\n \
|
|
|
|
fd -e jpg -x convert {} {.}.png\
|
|
|
|
",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("exec-batch")
|
2018-11-11 18:00:01 +01:00
|
|
|
.long("exec-batch")
|
|
|
|
.short("X")
|
|
|
|
.min_values(1)
|
|
|
|
.allow_hyphen_values(true)
|
|
|
|
.value_terminator(";")
|
|
|
|
.value_name("cmd")
|
2020-04-03 11:24:47 +02:00
|
|
|
.conflicts_with_all(&["exec", "list-details"])
|
|
|
|
.help("Execute a command with all search results at once")
|
|
|
|
.long_help(
|
2021-08-08 22:49:32 +02:00
|
|
|
"Execute the given command once, with all search results as arguments.\n\
|
|
|
|
One of the following placeholders is substituted before the command is executed:\n \
|
|
|
|
'{}': path (of all search results)\n \
|
2020-04-03 11:24:47 +02:00
|
|
|
'{/}': basename\n \
|
|
|
|
'{//}': parent directory\n \
|
|
|
|
'{.}': path without file extension\n \
|
2021-08-08 22:49:32 +02:00
|
|
|
'{/.}': basename without file extension\n\n\
|
|
|
|
If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\
|
|
|
|
Examples:\n\n \
|
|
|
|
- Find all test_*.py files and open them in your favorite editor:\n\n \
|
|
|
|
fd -g 'test_*.py' -X vim\n\n \
|
|
|
|
- Find all *.rs files and count the lines with \"wc -l ...\":\n\n \
|
|
|
|
fd -e rs -X wc -l\
|
|
|
|
"
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("exclude")
|
2017-10-22 23:00:19 +02:00
|
|
|
.long("exclude")
|
|
|
|
.short("E")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("pattern")
|
|
|
|
.number_of_values(1)
|
2020-04-03 11:24:47 +02:00
|
|
|
.multiple(true)
|
|
|
|
.help("Exclude entries that match the given glob pattern")
|
|
|
|
.long_help(
|
|
|
|
"Exclude files/directories that match the given glob pattern. This \
|
|
|
|
overrides any other ignore logic. Multiple exclude patterns can be \
|
2020-12-06 12:15:01 +01:00
|
|
|
specified.\n\n\
|
|
|
|
Examples:\n \
|
|
|
|
--exclude '*.pyc'\n \
|
|
|
|
--exclude node_modules",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("ignore-file")
|
2018-03-26 00:15:01 +02:00
|
|
|
.long("ignore-file")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("path")
|
|
|
|
.number_of_values(1)
|
2018-10-27 15:38:26 +02:00
|
|
|
.multiple(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Add a custom ignore-file in '.gitignore' format. These files have a low \
|
|
|
|
precedence.",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("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"])
|
2020-04-03 11:24:47 +02:00
|
|
|
.hide_possible_values(true)
|
|
|
|
.help("When to use colors: never, *auto*, always")
|
|
|
|
.long_help(
|
|
|
|
"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",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("threads")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("threads")
|
|
|
|
.short("j")
|
|
|
|
.takes_value(true)
|
2018-10-27 15:38:26 +02:00
|
|
|
.value_name("num")
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Set number of threads to use for searching & executing (default: number \
|
|
|
|
of available CPU cores)",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("size")
|
2018-04-23 01:38:10 +02:00
|
|
|
.long("size")
|
|
|
|
.short("S")
|
|
|
|
.takes_value(true)
|
|
|
|
.number_of_values(1)
|
|
|
|
.allow_hyphen_values(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.multiple(true)
|
|
|
|
.help("Limit results based on the size of files.")
|
|
|
|
.long_help(
|
|
|
|
"Limit results based on the size of files using the format <+-><NUM><UNIT>.\n \
|
|
|
|
'+': file size must be greater than or equal to this\n \
|
2020-12-02 16:04:00 +01:00
|
|
|
'-': file size must be less than or equal to this\n\
|
|
|
|
If neither '+' nor '-' is specified, file size must be exactly equal to this.\n \
|
2020-04-03 11:24:47 +02:00
|
|
|
'NUM': The numeric size (e.g. 500)\n \
|
|
|
|
'UNIT': The units for NUM. They are not case-sensitive.\n\
|
2020-05-19 17:06:32 +02:00
|
|
|
Allowed unit values:\n \
|
|
|
|
'b': bytes\n \
|
|
|
|
'k': kilobytes (base ten, 10^3 = 1000 bytes)\n \
|
|
|
|
'm': megabytes\n \
|
|
|
|
'g': gigabytes\n \
|
|
|
|
't': terabytes\n \
|
|
|
|
'ki': kibibytes (base two, 2^10 = 1024 bytes)\n \
|
|
|
|
'mi': mebibytes\n \
|
|
|
|
'gi': gibibytes\n \
|
2020-04-03 11:24:47 +02:00
|
|
|
'ti': tebibytes",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("max-buffer-time")
|
2017-10-04 14:31:08 +02:00
|
|
|
.long("max-buffer-time")
|
|
|
|
.takes_value(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden(true)
|
|
|
|
.long_help(
|
|
|
|
"Amount of time in milliseconds to buffer, before streaming the search \
|
|
|
|
results to the console.",
|
|
|
|
),
|
2018-09-27 23:01:38 +02:00
|
|
|
)
|
2018-10-09 13:47:42 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("changed-within")
|
2018-10-09 13:47:42 +02:00
|
|
|
.long("changed-within")
|
2018-10-27 15:34:10 +02:00
|
|
|
.alias("change-newer-than")
|
2020-09-10 08:34:27 +02:00
|
|
|
.alias("newer")
|
2018-10-09 13:47:42 +02:00
|
|
|
.takes_value(true)
|
2018-10-27 15:34:10 +02:00
|
|
|
.value_name("date|dur")
|
2020-04-03 11:24:47 +02:00
|
|
|
.number_of_values(1)
|
|
|
|
.help("Filter by file modification time (newer than)")
|
|
|
|
.long_help(
|
|
|
|
"Filter results based on the file modification time. The argument can be provided \
|
|
|
|
as a specific point in time (YYYY-MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). \
|
2021-02-25 07:39:44 +01:00
|
|
|
If the time is not specified, it defaults to 00:00:00. \
|
|
|
|
'--change-newer-than' or '--newer' can be used as aliases.\n\
|
2020-04-03 11:24:47 +02:00
|
|
|
Examples:\n \
|
|
|
|
--changed-within 2weeks\n \
|
2021-02-25 07:39:44 +01:00
|
|
|
--change-newer-than '2018-10-27 10:00:00'\n \
|
|
|
|
--newer 2018-10-27",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("changed-before")
|
2018-10-09 13:47:42 +02:00
|
|
|
.long("changed-before")
|
2018-10-27 15:34:10 +02:00
|
|
|
.alias("change-older-than")
|
2020-09-10 08:34:27 +02:00
|
|
|
.alias("older")
|
2018-10-09 13:47:42 +02:00
|
|
|
.takes_value(true)
|
2018-10-27 15:34:10 +02:00
|
|
|
.value_name("date|dur")
|
2020-04-03 11:24:47 +02:00
|
|
|
.number_of_values(1)
|
|
|
|
.help("Filter by file modification time (older than)")
|
|
|
|
.long_help(
|
|
|
|
"Filter results based on the file modification time. The argument can be provided \
|
|
|
|
as a specific point in time (YYYY-MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). \
|
2021-02-25 07:39:44 +01:00
|
|
|
'--change-older-than' or '--older' can be used as aliases.\n\
|
2020-04-03 11:24:47 +02:00
|
|
|
Examples:\n \
|
|
|
|
--changed-before '2018-10-27 10:00:00'\n \
|
2021-02-25 07:39:44 +01:00
|
|
|
--change-older-than 2weeks\n \
|
|
|
|
--older 2018-10-27",
|
2020-04-03 11:24:47 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("max-results")
|
2020-04-02 17:52:44 +02:00
|
|
|
.long("max-results")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("count")
|
2020-04-16 10:11:05 +02:00
|
|
|
// We currently do not support --max-results in combination with
|
|
|
|
// program execution because the results that come up in a --max-results
|
|
|
|
// search are non-deterministic. Users might think that they can run the
|
|
|
|
// same search with `--exec rm` attached and get a reliable removal of
|
|
|
|
// the files they saw in the previous search.
|
|
|
|
.conflicts_with_all(&["exec", "exec-batch", "list-details"])
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help("Limit the number of search results to 'count' and quit immediately."),
|
2020-04-02 17:52:44 +02:00
|
|
|
)
|
2020-04-09 17:21:40 +02:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("max-one-result")
|
|
|
|
.short("1")
|
|
|
|
.hidden_short_help(true)
|
|
|
|
.overrides_with("max-results")
|
2020-04-16 10:11:05 +02:00
|
|
|
.conflicts_with_all(&["exec", "exec-batch", "list-details"])
|
2020-04-09 17:21:40 +02:00
|
|
|
.long_help("Limit the search to a single result and quit immediately. \
|
|
|
|
This is an alias for '--max-results=1'.")
|
|
|
|
)
|
2018-10-27 15:38:26 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("show-errors")
|
2018-10-27 15:38:26 +02:00
|
|
|
.long("show-errors")
|
2019-10-08 14:40:16 +02:00
|
|
|
.hidden_short_help(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.overrides_with("show-errors")
|
|
|
|
.long_help(
|
|
|
|
"Enable the display of filesystem errors for situations such as \
|
|
|
|
insufficient permissions or dead symlinks.",
|
|
|
|
),
|
2018-10-27 15:38:26 +02:00
|
|
|
)
|
2019-11-20 10:53:51 +01:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("base-directory")
|
2019-11-20 10:53:51 +01:00
|
|
|
.long("base-directory")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("path")
|
|
|
|
.number_of_values(1)
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
2020-10-10 22:13:07 +02:00
|
|
|
"Change the current working directory of fd to the provided path. This \
|
2020-04-03 11:24:47 +02:00
|
|
|
means that search results will be shown with respect to the given base \
|
|
|
|
path. Note that relative paths which are passed to fd via the positional \
|
|
|
|
<path> argument or the '--search-path' option will also be resolved \
|
|
|
|
relative to this directory.",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("pattern").help(
|
2020-12-06 12:31:31 +01:00
|
|
|
"the search pattern (a regular expression, unless '--glob' is used; optional)",
|
|
|
|
).long_help(
|
|
|
|
"the search pattern which is either a regular expression (default) or a glob \
|
|
|
|
pattern (if --glob is used). If no pattern has been specified, every entry \
|
|
|
|
is considered a match. If your pattern starts with a dash (-), make sure to \
|
|
|
|
pass '--' first, or it will be considered as a flag (fd -- '-foo').")
|
2019-11-20 10:53:51 +01:00
|
|
|
)
|
2019-04-11 00:30:56 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("path-separator")
|
2019-04-11 00:30:56 +02:00
|
|
|
.takes_value(true)
|
2019-04-12 00:46:07 +02:00
|
|
|
.value_name("separator")
|
2019-04-11 00:30:56 +02:00
|
|
|
.long("path-separator")
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"Set the path separator to use when printing file paths. The default is \
|
|
|
|
the OS-specific separator ('/' on Unix, '\\' on Windows).",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("path")
|
|
|
|
.multiple(true)
|
|
|
|
.help("the root directory for the filesystem search (optional)")
|
|
|
|
.long_help(
|
|
|
|
"The directory where the filesystem search is rooted (optional). If \
|
|
|
|
omitted, search the current working directory.",
|
|
|
|
),
|
2019-04-11 00:30:56 +02:00
|
|
|
)
|
2018-10-20 20:24:53 +02:00
|
|
|
.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("search-path")
|
2018-10-20 20:24:53 +02:00
|
|
|
.long("search-path")
|
|
|
|
.takes_value(true)
|
|
|
|
.conflicts_with("path")
|
|
|
|
.multiple(true)
|
2018-10-27 15:38:26 +02:00
|
|
|
.hidden_short_help(true)
|
2020-04-03 11:24:47 +02:00
|
|
|
.number_of_values(1)
|
|
|
|
.long_help(
|
|
|
|
"Provide paths to search as an alternative to the positional <path> \
|
|
|
|
argument. Changes the usage to `fd [FLAGS/OPTIONS] --search-path <path> \
|
|
|
|
--search-path <path2> [<pattern>]`",
|
|
|
|
),
|
2019-12-30 22:05:42 +01:00
|
|
|
);
|
|
|
|
|
2020-05-01 14:50:12 +02:00
|
|
|
if cfg!(unix) {
|
|
|
|
app = app.arg(
|
|
|
|
Arg::with_name("owner")
|
|
|
|
.long("owner")
|
|
|
|
.short("o")
|
2018-07-07 14:44:26 +02:00
|
|
|
.takes_value(true)
|
|
|
|
.value_name("user:group")
|
|
|
|
.help("Filter by owning user and/or group")
|
|
|
|
.long_help(
|
|
|
|
"Filter files by their user and/or group. \
|
|
|
|
Format: [(user|uid)][:(group|gid)]. Either side is optional. \
|
|
|
|
Precede either side with a '!' to exclude files instead.\n\
|
|
|
|
Examples:\n \
|
|
|
|
--owner john\n \
|
|
|
|
--owner :students\n \
|
|
|
|
--owner '!john:students'",
|
|
|
|
),
|
2020-05-01 14:50:12 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-30 22:05:42 +01:00
|
|
|
// Make `--one-file-system` available only on Unix and Windows platforms, as per the
|
|
|
|
// restrictions on the corresponding option in the `ignore` crate.
|
2019-12-30 22:10:18 +01:00
|
|
|
// Provide aliases `mount` and `xdev` for people coming from `find`.
|
2019-12-30 22:27:45 +01:00
|
|
|
if cfg!(any(unix, windows)) {
|
2020-01-01 11:17:16 +01:00
|
|
|
app = app.arg(
|
2020-04-03 11:24:47 +02:00
|
|
|
Arg::with_name("one-file-system")
|
2019-12-30 22:10:18 +01:00
|
|
|
.long("one-file-system")
|
2020-01-01 11:21:30 +01:00
|
|
|
.aliases(&["mount", "xdev"])
|
2020-04-03 11:24:47 +02:00
|
|
|
.hidden_short_help(true)
|
|
|
|
.long_help(
|
|
|
|
"By default, fd will traverse the file system tree as far as other options \
|
|
|
|
dictate. With this flag, fd ensures that it does not descend into a \
|
|
|
|
different file system than the one it started in. Comparable to the -mount \
|
|
|
|
or -xdev filters of find(1).",
|
|
|
|
),
|
2020-01-01 11:17:16 +01:00
|
|
|
);
|
2019-12-30 22:05:42 +01:00
|
|
|
}
|
2020-01-01 11:17:16 +01:00
|
|
|
|
|
|
|
app
|
2017-10-05 05:14:01 +02:00
|
|
|
}
|