help.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. use std::fmt;
  2. use crate::options::flags;
  3. use crate::options::parser::MatchedFlags;
  4. use crate::fs::feature::xattr;
  5. static OPTIONS: &str = r##"
  6. -?, --help show list of command-line options
  7. -v, --version show version of exa
  8. DISPLAY OPTIONS
  9. -1, --oneline display one entry per line
  10. -l, --long display extended file metadata as a table
  11. -G, --grid display entries as a grid (default)
  12. -x, --across sort the grid across, rather than downwards
  13. -R, --recurse recurse into directories
  14. -T, --tree recurse into directories as a tree
  15. -F, --classify display type indicator by file names
  16. --colo[u]r=WHEN when to use terminal colours (always, auto, never)
  17. --colo[u]r-scale highlight levels of file sizes distinctly
  18. --icons display icons
  19. FILTERING AND SORTING OPTIONS
  20. -a, --all show hidden and 'dot' files
  21. -d, --list-dirs list directories like regular files
  22. -L, --level DEPTH limit the depth of recursion
  23. -r, --reverse reverse the sort order
  24. -s, --sort SORT_FIELD which field to sort by
  25. --group-directories-first list directories before other files
  26. -D, --only-dirs list only directories
  27. -I, --ignore-glob GLOBS glob patterns (pipe-separated) of files to ignore
  28. --git-ignore Ignore files mentioned in '.gitignore'
  29. Valid sort fields: name, Name, extension, Extension, size, type,
  30. modified, accessed, created, inode, and none.
  31. date, time, old, and new all refer to modified.
  32. "##;
  33. static LONG_OPTIONS: &str = r##"
  34. LONG VIEW OPTIONS
  35. -b, --binary list file sizes with binary prefixes
  36. -B, --bytes list file sizes in bytes, without any prefixes
  37. -g, --group list each file's group
  38. -h, --header add a header row to each column
  39. -H, --links list each file's number of hard links
  40. -i, --inode list each file's inode number
  41. -m, --modified use the modified timestamp field
  42. -S, --blocks show number of file system blocks
  43. -t, --time FIELD which timestamp field to list (modified, accessed, created)
  44. -u, --accessed use the accessed timestamp field
  45. -U, --created use the created timestamp field
  46. --changed use the changed timestamp field
  47. --time-style how to format timestamps (default, iso, long-iso, full-iso)
  48. --no-permissions suppress the permissions field
  49. --no-filesize suppress the filesize field
  50. --no-user suppress the user field
  51. --no-time suppress the time field"##;
  52. static GIT_HELP: &str = r##" --git list each file's Git status, if tracked or ignored"##;
  53. static EXTENDED_HELP: &str = r##" -@, --extended list each file's extended attributes and sizes"##;
  54. static OCTAL_HELP: &str = r##" --octal-permissions list each file's permission in octal format"##;
  55. /// All the information needed to display the help text, which depends
  56. /// on which features are enabled and whether the user only wants to
  57. /// see one section’s help.
  58. #[derive(PartialEq, Debug)]
  59. pub struct HelpString {
  60. /// Only show the help for the long section, not all the help.
  61. only_long: bool,
  62. /// Whether the --git option should be included in the help.
  63. git: bool,
  64. /// Whether the --extended option should be included in the help.
  65. xattrs: bool,
  66. }
  67. impl HelpString {
  68. /// Determines how to show help, if at all, based on the user’s
  69. /// command-line arguments. This one works backwards from the other
  70. /// ‘deduce’ functions, returning Err if help needs to be shown.
  71. ///
  72. /// We don’t do any strict-mode error checking here: it’s OK to give
  73. /// the --help or --long flags more than once. Actually checking for
  74. /// errors when the user wants help is kind of petty!
  75. pub fn deduce(matches: &MatchedFlags) -> Result<(), HelpString> {
  76. if matches.count(&flags::HELP) > 0 {
  77. let only_long = matches.count(&flags::LONG) > 0;
  78. let git = cfg!(feature="git");
  79. let xattrs = xattr::ENABLED;
  80. Err(HelpString { only_long, git, xattrs })
  81. }
  82. else {
  83. Ok(()) // no help needs to be shown
  84. }
  85. }
  86. }
  87. impl fmt::Display for HelpString {
  88. /// Format this help options into an actual string of help
  89. /// text to be displayed to the user.
  90. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  91. writeln!(f, "Usage:\n exa [options] [files...]")?;
  92. if !self.only_long {
  93. write!(f, "{}", OPTIONS)?;
  94. }
  95. write!(f, "{}", LONG_OPTIONS)?;
  96. if self.git {
  97. write!(f, "\n{}", GIT_HELP)?;
  98. }
  99. if self.xattrs {
  100. write!(f, "\n{}", EXTENDED_HELP)?;
  101. }
  102. write!(f, "\n{}", OCTAL_HELP)?;
  103. Ok(())
  104. }
  105. }
  106. #[cfg(test)]
  107. mod test {
  108. use crate::options::Options;
  109. use std::ffi::OsString;
  110. fn os(input: &'static str) -> OsString {
  111. let mut os = OsString::new();
  112. os.push(input);
  113. os
  114. }
  115. #[test]
  116. fn help() {
  117. let args = [ os("--help") ];
  118. let opts = Options::parse(&args, &None);
  119. assert!(opts.is_err())
  120. }
  121. #[test]
  122. fn help_with_file() {
  123. let args = [ os("--help"), os("me") ];
  124. let opts = Options::parse(&args, &None);
  125. assert!(opts.is_err())
  126. }
  127. #[test]
  128. fn unhelpful() {
  129. let args = [];
  130. let opts = Options::parse(&args, &None);
  131. assert!(opts.is_ok()) // no help when --help isn’t passed
  132. }
  133. }