فهرست منبع

Document the parsing decisions

Even though these can’t actually be viewed with `cargo doc` yet, they’re still good to have around.
Benjamin Sago 8 سال پیش
والد
کامیت
8d96be7f6a
3فایلهای تغییر یافته به همراه97 افزوده شده و 0 حذف شده
  1. 1 0
      Cargo.toml
  2. 66 0
      src/options/mod.rs
  3. 30 0
      src/options/parser.rs

+ 1 - 0
Cargo.toml

@@ -16,6 +16,7 @@ license = "MIT"
 [[bin]]
 name = "exa"
 path = "src/bin/main.rs"
+doc = false
 
 [lib]
 name = "exa"

+ 66 - 0
src/options/mod.rs

@@ -1,3 +1,69 @@
+//! Parsing command-line strings into exa options.
+//!
+//!
+//! ## Useless and overridden options
+//!
+//! Let’s say exa was invoked with just one argument: `exa --inode`. The
+//! `--inode` option is used in the details view, where it adds the inode
+//! column to the output. But because the details view is *only* activated with
+//! the `--long` argument, adding `--inode` without it would not have any
+//! effect.
+//!
+//! For a long time, exa’s philosophy was that the user should be warned
+//! whenever they could be mistaken like this. If you tell exa to display the
+//! inode, and it *doesn’t* display the inode, isn’t that more annoying than
+//! having it throw an error back at you?
+//!
+//! However, this doesn’t take into account *configuration*. Say a user wants
+//! to configure exa so that it lists inodes in the details view, but otherwise
+//! functions normally. A common way to do this for command-line programs is to
+//! define a shell alias that specifies the details they want to use every
+//! time. For the inode column, the alias would be:
+//!
+//! `alias exa="exa --inode"`
+//!
+//! Using this alias means that although the inode column will be shown in the
+//! details view, you’re now *only* allowed to use the details view, as any
+//! other view type will result in an error. Oops!
+//!
+//! Another example is when an option is specified twice, such as `exa
+//! --sort=Name --sort=size`. Did the user change their mind about sorting, and
+//! accidentally specify the option twice?
+//!
+//! Again, exa rejected this case, throwing an error back to the user instead
+//! of trying to guess how they want their output sorted. And again, this
+//! doesn’t take into account aliases being used to set defaults. A user who
+//! wants their files to be sorted case-insensitively may configure their shell
+//! with the following:
+//!
+//! `alias exa="exa --sort=Name"`
+//!
+//! Just like the earlier example, the user now can’t use any other sort order,
+//! because exa refuses to guess which one they meant. It’s *more* annoying to
+//! have to go back and edit the command than if there were no error.
+//!
+//! Fortunately, there’s a heuristic for telling which options came from an
+//! alias and which came from the actual command-line: aliased options are
+//! nearer the beginning of the options array, and command-line options are
+//! nearer the end. This means that after the options have been parsed, exa
+//! needs to traverse them *backwards* to find the last-most-specified one.
+//!
+//! For example, invoking exa with `exa --sort=size` when that alias is present
+//! would result in a full command-line of:
+//!
+//! `exa --sort=Name --sort=size`
+//!
+//! `--sort=size` should override `--sort=Name` because it’s closer to the end
+//! of the arguments array. In fact, because there’s no way to tell where the
+//! arguments came from -- it’s just a heuristic -- this will still work even
+//! if no aliases are being used!
+//!
+//! Finally, this isn’t just useful when options could override each other.
+//! Creating an alias `exal=”exa --long --inode --header”` then invoking `exal
+//! --grid --long` shouldn’t complain about `--long` being given twice when
+//! it’s clear what the user wants.
+
+
 use std::ffi::OsStr;
 
 use getopts;

+ 30 - 0
src/options/parser.rs

@@ -1,3 +1,33 @@
+//! A general parser for command-line options.
+//!
+//! exa uses its own hand-rolled parser for command-line options. It supports
+//! the following syntax:
+//!
+//! - Long options: `--inode`, `--grid`
+//! - Long options with values: `--sort size`, `--level=4`
+//! - Short options: `-i`, `-G`
+//! - Short options with values: `-ssize`, `-L=4`
+//!
+//! These values can be mixed and matched: `exa -lssize --grid`. If you’ve used
+//! other command-line programs, then hopefully it’ll work much like them.
+//!
+//! Because exa already has its own files for the help text, shell completions,
+//! man page, and readme, so it can get away with having the options parser do
+//! very little: all it really needs to do is parse a slice of strings.
+//!
+//!
+//! ## UTF-8 and `OsStr`
+//!
+//! The parser uses `OsStr` as its string type. This is necessary for exa to
+//! list files that have invalid UTF-8 in their names: by treating file paths
+//! as bytes with no encoding, a file can be specified on the command-line and
+//! be looked up without having to be encoded into a `str` first.
+//!
+//! It also avoids the overhead of checking for invalid UTF-8 when parsing
+//! command-line options, as all the options and their values (such as
+//! `--sort size`) are guaranteed to just be 8-bit ASCII.
+
+
 #![allow(unused_variables, dead_code)]
 
 use std::ffi::{OsStr, OsString};