exa/src/options/help.rs

162 lines
5.5 KiB
Rust
Raw Normal View History

use std::fmt;
use crate::fs::feature::xattr;
2018-12-07 23:43:31 +00:00
use crate::options::flags;
use crate::options::parser::MatchedFlags;
2017-08-05 13:33:32 +00:00
static OPTIONS: &str = r##"
-?, --help show list of command-line options
-v, --version show version of exa
DISPLAY OPTIONS
-1, --oneline display one entry per line
-l, --long display extended file metadata as a table
-G, --grid display entries as a grid (default)
-x, --across sort the grid across, rather than downwards
-R, --recurse recurse into directories
-T, --tree recurse into directories as a tree
-F, --classify display type indicator by file names
--colo[u]r=WHEN when to use terminal colours (always, auto, never)
--colo[u]r-scale highlight levels of file sizes distinctly
--icons display icons
FILTERING AND SORTING OPTIONS
2017-06-29 12:24:55 +00:00
-a, --all show hidden and 'dot' files
-d, --list-dirs list directories like regular files
2018-10-26 23:04:22 +00:00
-L, --level DEPTH limit the depth of recursion
-r, --reverse reverse the sort order
-s, --sort SORT_FIELD which field to sort by
--group-directories-first list directories before other files
2018-10-26 23:21:31 +00:00
-D, --only-dirs list only directories
-I, --ignore-glob GLOBS glob patterns (pipe-separated) of files to ignore
--git-ignore Ignore files mentioned in '.gitignore'
2017-06-29 13:57:43 +00:00
Valid sort fields: name, Name, extension, Extension, size, type,
modified, accessed, created, inode, and none.
date, time, old, and new all refer to modified.
"##;
static LONG_OPTIONS: &str = r##"
LONG VIEW OPTIONS
-b, --binary list file sizes with binary prefixes
-B, --bytes list file sizes in bytes, without any prefixes
-g, --group list each file's group
-h, --header add a header row to each column
-H, --links list each file's number of hard links
-i, --inode list each file's inode number
-m, --modified use the modified timestamp field
-S, --blocks show number of file system blocks
-t, --time FIELD which timestamp field to list (modified, accessed, created)
-u, --accessed use the accessed timestamp field
2017-07-05 23:52:27 +00:00
-U, --created use the created timestamp field
--changed use the changed timestamp field
2019-12-23 11:08:03 +00:00
--time-style how to format timestamps (default, iso, long-iso, full-iso)
--no-permissions suppress the permissions field
--no-filesize suppress the filesize field
--no-user suppress the user field
--no-time suppress the time field"##;
static GIT_HELP: &str = r##" --git list each file's Git status, if tracked or ignored"##;
static EXTENDED_HELP: &str = r##" -@, --extended list each file's extended attributes and sizes"##;
static OCTAL_HELP: &str = r##" --octal-permissions list each file's permission in octal format"##;
2017-08-05 13:33:32 +00:00
/// All the information needed to display the help text, which depends
/// on which features are enabled and whether the user only wants to
/// see one sections help.
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct HelpString {
2017-08-05 13:33:32 +00:00
/// Only show the help for the long section, not all the help.
only_long: bool,
2017-08-05 13:33:32 +00:00
/// Whether the --git option should be included in the help.
git: bool,
2017-08-05 13:33:32 +00:00
/// Whether the --extended option should be included in the help.
xattrs: bool,
}
2017-08-05 13:33:32 +00:00
impl HelpString {
/// Determines how to show help, if at all, based on the users
/// command-line arguments. This one works backwards from the other
/// deduce functions, returning Err if help needs to be shown.
///
/// We dont do any strict-mode error checking here: its OK to give
/// the --help or --long flags more than once. Actually checking for
/// errors when the user wants help is kind of petty!
pub fn deduce(matches: &MatchedFlags) -> Result<(), Self> {
if matches.count(&flags::HELP) > 0 {
let only_long = matches.count(&flags::LONG) > 0;
2017-08-05 13:33:32 +00:00
let git = cfg!(feature="git");
let xattrs = xattr::ENABLED;
Err(Self { only_long, git, xattrs })
2017-08-05 13:33:32 +00:00
}
else {
Ok(()) // no help needs to be shown
}
}
}
impl fmt::Display for HelpString {
2017-08-05 13:33:32 +00:00
/// Format this help options into an actual string of help
/// text to be displayed to the user.
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2018-06-19 12:58:03 +00:00
writeln!(f, "Usage:\n exa [options] [files...]")?;
if ! self.only_long {
2018-04-18 00:16:32 +00:00
write!(f, "{}", OPTIONS)?;
}
2018-04-18 00:16:32 +00:00
write!(f, "{}", LONG_OPTIONS)?;
if self.git {
2018-04-18 00:16:32 +00:00
write!(f, "\n{}", GIT_HELP)?;
}
if self.xattrs {
2018-04-18 00:16:32 +00:00
write!(f, "\n{}", EXTENDED_HELP)?;
}
write!(f, "\n{}", OCTAL_HELP)?;
Ok(())
}
}
2017-08-05 13:33:32 +00:00
#[cfg(test)]
mod test {
2018-12-07 23:43:31 +00:00
use crate::options::Options;
2017-08-05 13:33:32 +00:00
use std::ffi::OsString;
fn os(input: &'static str) -> OsString {
let mut os = OsString::new();
os.push(input);
os
}
#[test]
fn help() {
let args = [ os("--help") ];
let opts = Options::parse(&args, &None);
2017-08-05 13:33:32 +00:00
assert!(opts.is_err())
}
#[test]
fn help_with_file() {
let args = [ os("--help"), os("me") ];
let opts = Options::parse(&args, &None);
2017-08-05 13:33:32 +00:00
assert!(opts.is_err())
}
#[test]
fn unhelpful() {
let args = [];
let opts = Options::parse(&args, &None);
2017-08-05 13:33:32 +00:00
assert!(opts.is_ok()) // no help when --help isnt passed
}
}