1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
use std::fmt;
use crate::options::flags;
use crate::options::parser::MatchedFlags;
use crate::fs::feature::xattr;
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
-a, --all show hidden and 'dot' files
-d, --list-dirs list directories like regular files
-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
-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'
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
-U, --created use the created timestamp field
--changed use the changed timestamp field
--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"##;
/// 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 section’s help.
#[derive(PartialEq, Debug)]
pub struct HelpString {
/// Only show the help for the long section, not all the help.
only_long: bool,
/// Whether the --git option should be included in the help.
git: bool,
/// Whether the --extended option should be included in the help.
xattrs: bool,
}
impl HelpString {
/// Determines how to show help, if at all, based on the user’s
/// command-line arguments. This one works backwards from the other
/// ‘deduce’ functions, returning Err if help needs to be shown.
///
/// We don’t do any strict-mode error checking here: it’s 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<(), HelpString> {
if matches.count(&flags::HELP) > 0 {
let only_long = matches.count(&flags::LONG) > 0;
let git = cfg!(feature="git");
let xattrs = xattr::ENABLED;
Err(HelpString { only_long, git, xattrs })
}
else {
Ok(()) // no help needs to be shown
}
}
}
impl fmt::Display for HelpString {
/// 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> {
writeln!(f, "Usage:\n exa [options] [files...]")?;
if !self.only_long {
write!(f, "{}", OPTIONS)?;
}
write!(f, "{}", LONG_OPTIONS)?;
if self.git {
write!(f, "\n{}", GIT_HELP)?;
}
if self.xattrs {
write!(f, "\n{}", EXTENDED_HELP)?;
}
write!(f, "\n{}", OCTAL_HELP)?;
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::options::Options;
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);
assert!(opts.is_err())
}
#[test]
fn help_with_file() {
let args = [ os("--help"), os("me") ];
let opts = Options::parse(&args, &None);
assert!(opts.is_err())
}
#[test]
fn unhelpful() {
let args = [];
let opts = Options::parse(&args, &None);
assert!(opts.is_ok()) // no help when --help isn’t passed
}
}
|