Reorganize optionally depending on term_width

This commit is contained in:
Árpád Goretity 2017-10-06 13:14:01 +02:00
parent 3224e2e1cd
commit ac97edde90
3 changed files with 116 additions and 114 deletions

View file

@ -25,7 +25,6 @@ unicode-width = "0.1.4"
textwrap = "0.8.0"
strsim = { version = "0.6.0", optional = true }
ansi_term = { version = "0.9.0", optional = true }
term_size = { version = "0.3.0", optional = true }
yaml-rust = { version = "0.3.5", optional = true }
clippy = { version = "~0.0.131", optional = true }
atty = { version = "0.2.2", optional = true }
@ -37,10 +36,10 @@ lazy_static = "0.2"
version-sync = "0.3"
[features]
default = ["suggestions", "color", "wrap_help", "vec_map"]
default = ["suggestions", "color", "vec_map"]
suggestions = ["strsim"]
color = ["ansi_term", "atty"]
wrap_help = ["term_size"]
wrap_help = ["textwrap/term_size"]
yaml = ["yaml-rust"]
unstable = [] # for building with unstable clap features (doesn't require nightly Rust) (currently none)
nightly = [] # for building with unstable Rust features (currently none)

View file

@ -16,13 +16,16 @@ use map::VecMap;
// Third Party
use unicode_width::UnicodeWidthStr;
#[cfg(feature = "wrap_help")]
use term_size;
use textwrap;
#[cfg(feature = "wrap_help")]
fn term_width() -> usize {
textwrap::termwidth()
}
#[cfg(not(feature = "wrap_help"))]
mod term_size {
pub fn dimensions() -> Option<(usize, usize)> { None }
fn term_width() -> usize {
120
}
fn str_width(s: &str) -> usize { UnicodeWidthStr::width(s) }
@ -101,7 +104,7 @@ impl<'a> Help<'a> {
term_w: match term_w {
Some(width) => if width == 0 { usize::MAX } else { width },
None => {
cmp::min(term_size::dimensions().map_or(120, |(w, _)| w),
cmp::min(term_width(),
match max_w {
None | Some(0) => usize::MAX,
Some(mw) => mw,

View file

@ -38,7 +38,7 @@
//! The first example shows a method that allows more advanced configuration options (not shown in
//! this small example), or even dynamically generating arguments when desired. The downside is it's
//! more verbose.
//!
//!
//! ```no_run
//! // (Full example with detailed comments in examples/01b_quick_example.rs)
//! //
@ -47,7 +47,7 @@
//! // to generate arguments dynamically.
//! extern crate clap;
//! use clap::{Arg, App, SubCommand};
//!
//!
//! fn main() {
//! let matches = App::new("My Super Program")
//! .version("1.0")
@ -75,15 +75,15 @@
//! .short("d")
//! .help("print debug information verbosely")))
//! .get_matches();
//!
//!
//! // Gets a value for config if supplied by user, or defaults to "default.conf"
//! let config = matches.value_of("config").unwrap_or("default.conf");
//! println!("Value for config: {}", config);
//!
//!
//! // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
//! // required we could have used an 'if let' to conditionally get the value)
//! println!("Using input file: {}", matches.value_of("INPUT").unwrap());
//!
//!
//! // Vary the output based on how many times the user used the "verbose" flag
//! // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
//! match matches.occurrences_of("v") {
@ -92,7 +92,7 @@
//! 2 => println!("Tons of verbose info"),
//! 3 | _ => println!("Don't be crazy"),
//! }
//!
//!
//! // You can handle information about subcommands by requesting their matches by name
//! // (as below), requesting just the name used, or both at the same time
//! if let Some(matches) = matches.subcommand_matches("test") {
@ -102,15 +102,15 @@
//! println!("Printing normally...");
//! }
//! }
//!
//!
//! // more program logic goes here...
//! }
//! ```
//!
//!
//! The next example shows a far less verbose method, but sacrifices some of the advanced
//! configuration options (not shown in this small example). This method also takes a *very* minor
//! runtime penalty.
//!
//!
//! ```no_run
//! // (Full example with detailed comments in examples/01a_quick_example.rs)
//! //
@ -118,7 +118,7 @@
//! // which is less verbose
//! extern crate clap;
//! use clap::{Arg, App, SubCommand};
//!
//!
//! fn main() {
//! let matches = App::new("myapp")
//! .version("1.0")
@ -134,18 +134,18 @@
//! .author("Someone E. <someone_else@other.com>")
//! .arg_from_usage("-d, --debug 'Print debug information'"))
//! .get_matches();
//!
//!
//! // Same as previous example...
//! }
//! ```
//!
//!
//! This third method shows how you can use a YAML file to build your CLI and keep your Rust source
//! tidy or support multiple localized translations by having different YAML files for each
//! localization.
//!
//! First, create the `cli.yml` file to hold your CLI options, but it could be called anything we
//! like:
//!
//!
//! ```yaml
//! name: myapp
//! version: "1.0"
@ -176,14 +176,14 @@
//! short: d
//! help: print debug information
//! ```
//!
//!
//! Since this feature requires additional dependencies that not everyone may want, it is *not*
//! compiled in by default and we need to enable a feature flag in Cargo.toml:
//!
//! Simply change your `clap = "~2.19.0"` to `clap = {version = "~2.19.0", features = ["yaml"]}`.
//!
//! At last we create our `main.rs` file just like we would have with the previous two examples:
//!
//!
//! ```ignore
//! // (Full example with detailed comments in examples/17_yaml.rs)
//! //
@ -192,23 +192,23 @@
//! #[macro_use]
//! extern crate clap;
//! use clap::App;
//!
//!
//! fn main() {
//! // The YAML file is found relative to the current file, similar to how modules are found
//! let yaml = load_yaml!("cli.yml");
//! let matches = App::from_yaml(yaml).get_matches();
//!
//!
//! // Same as previous examples...
//! }
//! ```
//!
//!
//! Finally there is a macro version, which is like a hybrid approach offering the speed of the
//! builder pattern (the first example), but without all the verbosity.
//!
//!
//! ```no_run
//! #[macro_use]
//! extern crate clap;
//!
//!
//! fn main() {
//! let matches = clap_app!(myapp =>
//! (version: "1.0")
@ -224,55 +224,55 @@
//! (@arg verbose: -v --verbose "Print test information verbosely")
//! )
//! ).get_matches();
//!
//!
//! // Same as before...
//! }
//! ```
//!
//!
//! If you were to compile any of the above programs and run them with the flag `--help` or `-h` (or
//! `help` subcommand, since we defined `test` as a subcommand) the following would be output
//!
//!
//! ```text
//! $ myprog --help
//! My Super Program 1.0
//! Kevin K. <kbknapp@gmail.com>
//! Does awesome things
//!
//!
//! USAGE:
//! MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]
//!
//!
//! FLAGS:
//! -h, --help Prints this message
//! -v Sets the level of verbosity
//! -V, --version Prints version information
//!
//!
//! OPTIONS:
//! -c, --config <FILE> Sets a custom config file
//!
//!
//! ARGS:
//! INPUT The input file to use
//!
//!
//! SUBCOMMANDS:
//! help Prints this message
//! test Controls testing features
//! ```
//!
//!
//! **NOTE:** You could also run `myapp test --help` to see similar output and options for the
//! `test` subcommand.
//!
//!
//! ## Try it!
//!
//!
//! ### Pre-Built Test
//!
//!
//! To try out the pre-built example, use the following steps:
//!
//!
//! * Clone the repository `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/tests`
//! * Compile the example `$ cargo build --release`
//! * Run the help info `$ ./target/release/claptests --help`
//! * Play with the arguments!
//!
//!
//! ### BYOB (Build Your Own Binary)
//!
//!
//! To test out `clap`'s default auto-generated help/version follow these steps:
//!
//! * Create a new cargo project `$ cargo new fake --bin && cd fake`
@ -282,104 +282,106 @@
//! [dependencies]
//! clap = "2"
//! ```
//!
//!
//! * Add the following to your `src/main.rs`
//!
//!
//! ```no_run
//! extern crate clap;
//! use clap::App;
//!
//!
//! fn main() {
//! App::new("fake").version("v1.0-beta").get_matches();
//! }
//! ```
//!
//!
//! * Build your program `$ cargo build --release`
//! * Run with help or version `$ ./target/release/fake --help` or `$ ./target/release/fake
//! --version`
//!
//!
//! ## Usage
//!
//!
//! For full usage, add `clap` as a dependency in your `Cargo.toml` (it is **highly** recommended to
//! use the `~major.minor.patch` style versions in your `Cargo.toml`, for more information see
//! [Compatibility Policy](#compatibility-policy)) to use from crates.io:
//!
//!
//! ```toml
//! [dependencies]
//! clap = "~2.19.0"
//! ```
//!
//!
//! Or get the latest changes from the master branch at github:
//!
//!
//! ```toml
//! [dependencies.clap]
//! git = "https://github.com/kbknapp/clap-rs.git"
//! ```
//!
//!
//! Add `extern crate clap;` to your crate root.
//!
//! Define a list of valid arguments for your program (see the
//!
//! Define a list of valid arguments for your program (see the
//! [documentation](https://docs.rs/clap/) or [examples/](examples) directory of this repo)
//!
//!
//! Then run `cargo build` or `cargo update && cargo build` for your project.
//!
//!
//! ### Optional Dependencies / Features
//!
//!
//! #### Features enabled by default
//!
//!
//! * `suggestions`: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
//! * `color`: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term` and `atty`)
//! * `wrap_help`: Wraps the help at the actual terminal width when available, instead of 120 chracters. (builds dependency `term_size`)
//!
//! * `wrap_help`: Wraps the help at the actual terminal width when
//! available, instead of 120 chracters. (builds dependency `textwrap`
//! with feature `term_size`)
//!
//! To disable these, add this to your `Cargo.toml`:
//!
//!
//! ```toml
//! [dependencies.clap]
//! version = "~2.19.0"
//! default-features = false
//! ```
//!
//!
//! You can also selectively enable only the features you'd like to include, by adding:
//!
//!
//! ```toml
//! [dependencies.clap]
//! version = "~2.19.0"
//! default-features = false
//!
//!
//! # Cherry-pick the features you'd like to use
//! features = [ "suggestions", "color" ]
//! ```
//!
//!
//! #### Opt-in features
//!
//!
//! * **"yaml"**: Enables building CLIs from YAML documents. (builds dependency `yaml-rust`)
//! * **"unstable"**: Enables unstable `clap` features that may change from release to release
//!
//!
//! ### Dependencies Tree
//!
//! The following graphic depicts `clap`s dependency graph (generated using
//!
//! The following graphic depicts `clap`s dependency graph (generated using
//! [cargo-graph](https://github.com/kbknapp/cargo-graph)).
//!
//!
//! * **Dashed** Line: Optional dependency
//! * **Red** Color: **NOT** included by default (must use cargo `features` to enable)
//! * **Blue** Color: Dev dependency, only used while developing.
//!
//!
//! ![clap dependencies](clap_dep_graph.png)
//!
//!
//! ### More Information
//!
//!
//! You can find complete documentation on the [docs.rs](https://docs.rs/clap/) for this project.
//!
//!
//! You can also find usage examples in the [examples/](examples) directory of this repo.
//!
//!
//! #### Video Tutorials
//!
//!
//! There's also the video tutorial series [Argument Parsing with Rust v2](https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U).
//!
//!
//! These videos slowly trickle out as I finish them and currently a work in progress.
//!
//!
//! ## How to Contribute
//!
//!
//! Contributions are always welcome! And there is a multitude of ways in which you can help
//! depending on what you like to do, or are good at. Anything from documentation, code cleanup,
//! issue completion, new features, you name it, even filing issues is contributing and greatly
@ -388,82 +390,82 @@
//! Another really great way to help is if you find an interesting, or helpful way in which to use
//! `clap`. You can either add it to the [examples/](examples) directory, or file an issue and tell
//! me. I'm all about giving credit where credit is due :)
//!
//!
//! Please read [CONTRIBUTING.md](.github/CONTRIBUTING.md) before you start contributing.
//!
//!
//!
//!
//! ### Testing Code
//!
//!
//! To test with all features both enabled and disabled, you can run theese commands:
//!
//!
//! ```text
//! $ cargo test --no-default-features
//! $ cargo test --features "yaml unstable"
//! ```
//!
//!
//! Alternatively, if you have [`just`](https://github.com/casey/just) installed you can run the
//! prebuilt recipies. *Not* using `just` is prfeclty fine as well, it simply bundles commands
//! automatically.
//!
//!
//! For example, to test the code, as above simply run:
//!
//!
//! ```text
//! $ just run-tests`
//! ```
//!
//!
//! From here on, I will lis the appropriate `cargo` command as well as the `just` command.
//!
//!
//! Sometimes it's helpful to only run a subset of the tests, which can be done via:
//!
//!
//! ```text
//! $ cargo test --test <test_name>
//!
//!
//! # Or
//!
//!
//! $ just run-test <test_name>
//! ```
//!
//!
//! ### Linting Code
//!
//!
//! During the CI process `clap` runs against many different lints using
//! [`clippy`](https://github.com/Manishearth/rust-clippy). In order to check if these lints pass on
//! your own computer prior to submitting a PR you'll need a nightly compiler.
//!
//!
//! In order to check the code for lints run either:
//!
//!
//! ```text
//! $ rustup override add nightly
//! $ cargo build --features lints
//! $ rustup override remove
//!
//!
//! # Or
//!
//!
//! $ just lint
//! ```
//!
//!
//! ### Debugging Code
//!
//!
//! Another helpful technique is to see the `clap` debug output while developing features. In order
//! to see the debug output while running the full test suite or individual tests, run:
//!
//!
//! ```text
//! $ cargo test --features debug
//!
//!
//! # Or for individual tests
//! $ cargo test --test <test_name> --features debug
//!
//!
//! # The corresponding just command for individual debugging tests is:
//! $ just debug <test_name>
//! ```
//!
//!
//! ### Goals
//!
//!
//! There are a few goals of `clap` that I'd like to maintain throughout contributions. If your
//! proposed changes break, or go against any of these goals we'll discuss the changes further
//! before merging (but will *not* be ignored, all contributes are welcome!). These are by no means
//! hard-and-fast rules, as I'm no expert and break them myself from time to time (even if by
//! mistake or ignorance).
//!
//!
//! * Remain backwards compatible when possible
//! - If backwards compatibility *must* be broken, use deprecation warnings if at all possible before
//! removing legacy code - This does not apply for security concerns
@ -475,7 +477,7 @@
//! - Once parsing is complete, the memory footprint of `clap` should be low since the main program
//! is the star of the show
//! * `panic!` on *developer* error, exit gracefully on *end-user* error
//!
//!
//! ### Compatibility Policy
//!
//! Because `clap` takes `SemVer` and compatibility seriously, this is the official policy regarding
@ -488,7 +490,7 @@
//! In order to keep from being suprised of breaking changes, it is **highly** recommended to use
//! the `~major.minor.patch` style in your `Cargo.toml`:
//!
//! ```toml
//! ```toml
//! [dependencies] clap = "~2.19.0"
//! ```
//!
@ -501,12 +503,12 @@
//! releases as well. For example, current stable Rust at the time of this writing is 1.13.0,
//! meaning `clap` is guaranteed to compile with 1.11.0 and beyond. At the 1.14.0 release, `clap`
//! will be guaranteed to compile with 1.12.0 and beyond, etc.
//!
//!
//! Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be
//! clearly annotated in the `CHANGELOG.md`
//!
//!
//! ## License
//!
//!
//! `clap` is licensed under the MIT license. Please read the [LICENSE-MIT](LICENSE-MIT) file in
//! this repository for more information.
@ -541,8 +543,6 @@ extern crate unicode_width;
extern crate bitflags;
#[cfg(feature = "vec_map")]
extern crate vec_map;
#[cfg(feature = "wrap_help")]
extern crate term_size;
extern crate textwrap;
#[cfg(feature = "color")]
extern crate atty;