<commit_before>use std::io::{self, Cursor, Read, Write};
use std::collections::BTreeMap;
use std::fmt::Display;
use std::cmp;

use vec_map::VecMap;

use errors::{Error, Result as ClapResult};

use args::{AnyArg, ArgSettings, DispOrder};
use app::{App, AppSettings};
use app::parser::Parser;
use fmt::{Format, Colorizer};

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
use term_size;
#[cfg(any(not(feature = "wrap_help"), target_os = "windows"))]
mod term_size {
    pub fn dimensions() -> Option<(usize, usize)> {
        None
    }
}

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
use unicode_width::UnicodeWidthStr;

use strext::_StrExt;

#[cfg(any(not(feature = "wrap_help"), target_os = "windows"))]
fn str_width(s: &str) -> usize {
    s.len()
}

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
fn str_width(s: &str) -> usize {
    UnicodeWidthStr::width(s)
}

const TAB: &'static str = "    ";

// These are just convenient traits to make the code easier to read.
trait ArgWithDisplay<'b, 'c>: AnyArg<'b, 'c> + Display {}
impl<'b, 'c, T> ArgWithDisplay<'b, 'c> for T where T: AnyArg<'b, 'c> + Display {}

trait ArgWithOrder<'b, 'c>: ArgWithDisplay<'b, 'c> + DispOrder {
    fn as_base(&self) -> &ArgWithDisplay<'b, 'c>;
}
impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T
    where T: ArgWithDisplay<'b, 'c> + DispOrder
{
    fn as_base(&self) -> &ArgWithDisplay<'b, 'c> {
        self
    }
}

fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> {
    x
}

impl<'b, 'c> DispOrder for App<'b, 'c> {
    fn disp_ord(&self) -> usize {
        999
    }
}

macro_rules! color {
    ($_self:ident, $s:expr, $c:ident) => {
        if $_self.color {
            write!($_self.writer, "{}", $_self.cizer.$c($s))
        } else {
            write!($_self.writer, "{}", $s)
        }
    };
    ($_self:ident, $fmt_s:expr, $v:expr, $c:ident) => {
        if $_self.color {
            write!($_self.writer, "{}", $_self.cizer.$c(format!($fmt_s, $v)))
        } else {
            write!($_self.writer, $fmt_s, $v)
        }
    };
}

/// `clap` Help Writer.
///
/// Wraps a writer stream providing different methods to generate help for `clap` objects.
pub struct Help<'a> {
    writer: &'a mut Write,
    next_line_help: bool,
    hide_pv: bool,
    term_w: usize,
    color: bool,
    cizer: Colorizer,
}

// Public Functions
impl<'a> Help<'a> {
    /// Create a new `Help` instance.
    pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool, cizer: Colorizer, term_w: Option<usize>) -> Self {
        debugln!("fn=Help::new;");
        Help {
            writer: w,
            next_line_help: next_line_help,
            hide_pv: hide_pv,
            term_w: match term_w {
                Some(width) => width,
                None        => term_size::dimensions().map_or(120, |(w, _)| w),
            },
            color: color,
            cizer: cizer,
        }
    }

    /// Reads help settings from an App
    /// and write its help to the wrapped stream.
    pub fn write_app_help(w: &'a mut Write, app: &App) -> ClapResult<()> {
        debugln!("fn=Help::write_app_help;");
        Self::write_parser_help(w, &app.p)
    }

    /// Reads help settings from a Parser
    /// and write its help to the wrapped stream.
    pub fn write_parser_help(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
        debugln!("fn=Help::write_parser_help;");<commit_msg>feat(Help): adds new short hand way to use source formatting and ignore term width in help messages<commit_after>use std::io::{self, Cursor, Read, Write};
use std::collections::BTreeMap;
use std::fmt::Display;
use std::cmp;
use std::usize;

use vec_map::VecMap;

use errors::{Error, Result as ClapResult};

use args::{AnyArg, ArgSettings, DispOrder};
use app::{App, AppSettings};
use app::parser::Parser;
use fmt::{Format, Colorizer};

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
use term_size;
#[cfg(any(not(feature = "wrap_help"), target_os = "windows"))]
mod term_size {
    pub fn dimensions() -> Option<(usize, usize)> {
        None
    }
}

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
use unicode_width::UnicodeWidthStr;

use strext::_StrExt;

#[cfg(any(not(feature = "wrap_help"), target_os = "windows"))]
fn str_width(s: &str) -> usize {
    s.len()
}

#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
fn str_width(s: &str) -> usize {
    UnicodeWidthStr::width(s)
}

const TAB: &'static str = "    ";

// These are just convenient traits to make the code easier to read.
trait ArgWithDisplay<'b, 'c>: AnyArg<'b, 'c> + Display {}
impl<'b, 'c, T> ArgWithDisplay<'b, 'c> for T where T: AnyArg<'b, 'c> + Display {}

trait ArgWithOrder<'b, 'c>: ArgWithDisplay<'b, 'c> + DispOrder {
    fn as_base(&self) -> &ArgWithDisplay<'b, 'c>;
}
impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T
    where T: ArgWithDisplay<'b, 'c> + DispOrder
{
    fn as_base(&self) -> &ArgWithDisplay<'b, 'c> {
        self
    }
}

fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> {
    x
}

impl<'b, 'c> DispOrder for App<'b, 'c> {
    fn disp_ord(&self) -> usize {
        999
    }
}

macro_rules! color {
    ($_self:ident, $s:expr, $c:ident) => {
        if $_self.color {
            write!($_self.writer, "{}", $_self.cizer.$c($s))
        } else {
            write!($_self.writer, "{}", $s)
        }
    };
    ($_self:ident, $fmt_s:expr, $v:expr, $c:ident) => {
        if $_self.color {
            write!($_self.writer, "{}", $_self.cizer.$c(format!($fmt_s, $v)))
        } else {
            write!($_self.writer, $fmt_s, $v)
        }
    };
}

/// `clap` Help Writer.
///
/// Wraps a writer stream providing different methods to generate help for `clap` objects.
pub struct Help<'a> {
    writer: &'a mut Write,
    next_line_help: bool,
    hide_pv: bool,
    term_w: usize,
    color: bool,
    cizer: Colorizer,
}

// Public Functions
impl<'a> Help<'a> {
    /// Create a new `Help` instance.
    pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool, cizer: Colorizer, term_w: Option<usize>) -> Self {
        debugln!("fn=Help::new;");
        Help {
            writer: w,
            next_line_help: next_line_help,
            hide_pv: hide_pv,
            term_w: match term_w {
                Some(width) => if width == 0 {
                    usize::MAX
                } else {
                    width
                },
                None        => term_size::dimensions().map_or(120, |(w, _)| w),
            },
            color: color,
            cizer: cizer,
        }
    }

    /// Reads help settings from an App
    /// and write its help to the wrapped stream.
    pub fn write_app_help(w: &'a mut Write, app: &App) -> ClapResult<()> {
        debugln!("fn=Help::write_app_help;");
        Self::write_parser_help(w, &app.p)
    }

    /// Reads help settings from a Parser
    /// and write its help to the wrapped stream.
    pub fn write_parser_help(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
        debugln!("fn=Help::write_parser_help;");
{'fraction_non_alphanumeric': 0.17785234899328858, 'fraction_numerical': 0.0018176733780760625, 'mean_word_length': 2.7826546800634584, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1149939', 'n_tokens_mistral': 2574, 'n_tokens_neox': 2626, 'n_words': 642}