mirror of
				https://github.com/sharkdp/bat.git
				synced 2025-11-04 00:51:56 +00:00 
			
		
		
		
	Split app to separate module
This commit is contained in:
		
				
					committed by
					
						
						David Peter
					
				
			
			
				
	
			
			
			
						parent
						
							ccf88fd5d8
						
					
				
				
					commit
					64a9341b73
				
			
							
								
								
									
										194
									
								
								src/app.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/app.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
use atty::{self, Stream};
 | 
			
		||||
use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand};
 | 
			
		||||
use console::Term;
 | 
			
		||||
use errors::*;
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use std::env;
 | 
			
		||||
use {OutputComponent, OutputComponents};
 | 
			
		||||
 | 
			
		||||
pub struct App {
 | 
			
		||||
    pub matches: ArgMatches<'static>,
 | 
			
		||||
    interactive_output: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl App {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        let interactive_output = atty::is(Stream::Stdout);
 | 
			
		||||
 | 
			
		||||
        App {
 | 
			
		||||
            matches: Self::matches(interactive_output),
 | 
			
		||||
            interactive_output,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn matches(interactive_output: bool) -> ArgMatches<'static> {
 | 
			
		||||
        let clap_color_setting = if interactive_output {
 | 
			
		||||
            AppSettings::ColoredHelp
 | 
			
		||||
        } else {
 | 
			
		||||
            AppSettings::ColorNever
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        ClapApp::new(crate_name!())
 | 
			
		||||
            .version(crate_version!())
 | 
			
		||||
            .global_setting(clap_color_setting)
 | 
			
		||||
            .global_setting(AppSettings::DeriveDisplayOrder)
 | 
			
		||||
            .global_setting(AppSettings::UnifiedHelpMessage)
 | 
			
		||||
            .global_setting(AppSettings::NextLineHelp)
 | 
			
		||||
            .setting(AppSettings::InferSubcommands)
 | 
			
		||||
            .setting(AppSettings::ArgsNegateSubcommands)
 | 
			
		||||
            .setting(AppSettings::DisableHelpSubcommand)
 | 
			
		||||
            .setting(AppSettings::VersionlessSubcommands)
 | 
			
		||||
            .max_term_width(90)
 | 
			
		||||
            .about(crate_description!())
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("language")
 | 
			
		||||
                    .short("l")
 | 
			
		||||
                    .long("language")
 | 
			
		||||
                    .help("Set the language for highlighting")
 | 
			
		||||
                    .takes_value(true),
 | 
			
		||||
            )
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("FILE")
 | 
			
		||||
                    .help("File(s) to print")
 | 
			
		||||
                    .multiple(true)
 | 
			
		||||
                    .empty_values(false),
 | 
			
		||||
            )
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("style")
 | 
			
		||||
                    .long("style")
 | 
			
		||||
                    .use_delimiter(true)
 | 
			
		||||
                    .takes_value(true)
 | 
			
		||||
                    .possible_values(&[
 | 
			
		||||
                        "auto", "full", "plain", "changes", "header", "grid", "numbers",
 | 
			
		||||
                    ])
 | 
			
		||||
                    .default_value("auto")
 | 
			
		||||
                    .help("Additional info to display along with content"),
 | 
			
		||||
            )
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("color")
 | 
			
		||||
                    .long("color")
 | 
			
		||||
                    .takes_value(true)
 | 
			
		||||
                    .possible_values(&["auto", "never", "always"])
 | 
			
		||||
                    .default_value("auto")
 | 
			
		||||
                    .help("When to use colors"),
 | 
			
		||||
            )
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("paging")
 | 
			
		||||
                    .long("paging")
 | 
			
		||||
                    .takes_value(true)
 | 
			
		||||
                    .possible_values(&["auto", "never", "always"])
 | 
			
		||||
                    .default_value("auto")
 | 
			
		||||
                    .help("When to use the pager"),
 | 
			
		||||
            )
 | 
			
		||||
            .arg(
 | 
			
		||||
                Arg::with_name("list-languages")
 | 
			
		||||
                    .long("list-languages")
 | 
			
		||||
                    .help("Displays supported languages"),
 | 
			
		||||
            )
 | 
			
		||||
            .subcommand(
 | 
			
		||||
                SubCommand::with_name("cache")
 | 
			
		||||
                    .about("Modify the syntax-definition and theme cache")
 | 
			
		||||
                    .arg(
 | 
			
		||||
                        Arg::with_name("init")
 | 
			
		||||
                            .long("init")
 | 
			
		||||
                            .short("i")
 | 
			
		||||
                            .help("Initialize the cache by loading from the config dir"),
 | 
			
		||||
                    )
 | 
			
		||||
                    .arg(
 | 
			
		||||
                        Arg::with_name("clear")
 | 
			
		||||
                            .long("clear")
 | 
			
		||||
                            .short("c")
 | 
			
		||||
                            .help("Reset the cache"),
 | 
			
		||||
                    )
 | 
			
		||||
                    .arg(
 | 
			
		||||
                        Arg::with_name("config-dir")
 | 
			
		||||
                            .long("config-dir")
 | 
			
		||||
                            .short("d")
 | 
			
		||||
                            .help("Show the configuration directory"),
 | 
			
		||||
                    )
 | 
			
		||||
                    .group(
 | 
			
		||||
                        ArgGroup::with_name("cache-actions")
 | 
			
		||||
                            .args(&["init", "clear", "config-dir"])
 | 
			
		||||
                            .required(true),
 | 
			
		||||
                    ),
 | 
			
		||||
            )
 | 
			
		||||
            .help_message("Print this help message.")
 | 
			
		||||
            .version_message("Show version information.")
 | 
			
		||||
            .get_matches()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn config(&self) -> Result<Config> {
 | 
			
		||||
        let files = self.files();
 | 
			
		||||
 | 
			
		||||
        Ok(Config {
 | 
			
		||||
            true_color: is_truecolor_terminal(),
 | 
			
		||||
            output_components: self.output_components()?,
 | 
			
		||||
            language: self.matches.value_of("language"),
 | 
			
		||||
            colored_output: match self.matches.value_of("color") {
 | 
			
		||||
                Some("always") => true,
 | 
			
		||||
                Some("never") => false,
 | 
			
		||||
                Some("auto") | _ => self.interactive_output,
 | 
			
		||||
            },
 | 
			
		||||
            paging: match self.matches.value_of("paging") {
 | 
			
		||||
                Some("always") => true,
 | 
			
		||||
                Some("never") => false,
 | 
			
		||||
                Some("auto") | _ => if files.contains(&None) {
 | 
			
		||||
                    // If we are reading from stdin, only enable paging if we write to an
 | 
			
		||||
                    // interactive terminal and if we do not *read* from an interactive
 | 
			
		||||
                    // terminal.
 | 
			
		||||
                    self.interactive_output && !atty::is(Stream::Stdin)
 | 
			
		||||
                } else {
 | 
			
		||||
                    self.interactive_output
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            term_width: Term::stdout().size().1 as usize,
 | 
			
		||||
            files,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn files(&self) -> Vec<Option<&str>> {
 | 
			
		||||
        self.matches
 | 
			
		||||
            .values_of("FILE")
 | 
			
		||||
            .map(|values| {
 | 
			
		||||
                values
 | 
			
		||||
                    .map(|filename| {
 | 
			
		||||
                        if filename == "-" {
 | 
			
		||||
                            None
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Some(filename)
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                    .collect()
 | 
			
		||||
            })
 | 
			
		||||
            .unwrap_or_else(|| vec![None]) // read from stdin (None) if no args are given
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn output_components(&self) -> Result<OutputComponents> {
 | 
			
		||||
        let matches = &self.matches;
 | 
			
		||||
        Ok(OutputComponents(
 | 
			
		||||
            values_t!(matches.values_of("style"), OutputComponent)?
 | 
			
		||||
                .into_iter()
 | 
			
		||||
                .map(|style| style.components(self.interactive_output))
 | 
			
		||||
                .fold(HashSet::new(), |mut acc, components| {
 | 
			
		||||
                    acc.extend(components.iter().cloned());
 | 
			
		||||
                    acc
 | 
			
		||||
                }),
 | 
			
		||||
        ))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Config<'a> {
 | 
			
		||||
    pub true_color: bool,
 | 
			
		||||
    pub output_components: OutputComponents,
 | 
			
		||||
    pub language: Option<&'a str>,
 | 
			
		||||
    pub colored_output: bool,
 | 
			
		||||
    pub paging: bool,
 | 
			
		||||
    pub term_width: usize,
 | 
			
		||||
    pub files: Vec<Option<&'a str>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_truecolor_terminal() -> bool {
 | 
			
		||||
    env::var("COLORTERM")
 | 
			
		||||
        .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
 | 
			
		||||
        .unwrap_or(false)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										172
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -17,13 +17,13 @@ extern crate directories;
 | 
			
		||||
extern crate git2;
 | 
			
		||||
extern crate syntect;
 | 
			
		||||
 | 
			
		||||
mod app;
 | 
			
		||||
mod assets;
 | 
			
		||||
mod diff;
 | 
			
		||||
mod printer;
 | 
			
		||||
mod terminal;
 | 
			
		||||
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::fs::{self, File};
 | 
			
		||||
use std::io::{self, BufRead, BufReader, Write};
 | 
			
		||||
use std::process::{self, Child, Command, Stdio};
 | 
			
		||||
@@ -34,13 +34,12 @@ use std::os::unix::fs::FileTypeExt;
 | 
			
		||||
 | 
			
		||||
use ansi_term::Colour::{Fixed, Green, Red, White, Yellow};
 | 
			
		||||
use ansi_term::Style;
 | 
			
		||||
use atty::Stream;
 | 
			
		||||
use clap::{App, AppSettings, Arg, ArgGroup, SubCommand};
 | 
			
		||||
 | 
			
		||||
use syntect::easy::HighlightLines;
 | 
			
		||||
use syntect::highlighting::Theme;
 | 
			
		||||
use syntect::parsing::SyntaxSet;
 | 
			
		||||
 | 
			
		||||
use app::{App, Config};
 | 
			
		||||
use assets::{config_dir, syntax_set_path, theme_set_path, HighlightingAssets};
 | 
			
		||||
use diff::get_git_diff;
 | 
			
		||||
use printer::Printer;
 | 
			
		||||
@@ -215,7 +214,7 @@ impl Colors {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn print_file(
 | 
			
		||||
    options: &Options,
 | 
			
		||||
    config: &Config,
 | 
			
		||||
    theme: &Theme,
 | 
			
		||||
    syntax_set: &SyntaxSet,
 | 
			
		||||
    printer: &mut Printer,
 | 
			
		||||
@@ -228,7 +227,7 @@ fn print_file(
 | 
			
		||||
        Some(filename) => Box::new(BufReader::new(File::open(filename)?)),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let syntax = match (options.language, filename) {
 | 
			
		||||
    let syntax = match (config.language, filename) {
 | 
			
		||||
        (Some(language), _) => syntax_set.find_syntax_by_token(language),
 | 
			
		||||
        (None, Some(filename)) => {
 | 
			
		||||
            #[cfg(not(unix))]
 | 
			
		||||
@@ -292,110 +291,10 @@ fn get_output_type(paging: bool) -> OutputType {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_truecolor_terminal() -> bool {
 | 
			
		||||
    env::var("COLORTERM")
 | 
			
		||||
        .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
 | 
			
		||||
        .unwrap_or(false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn run() -> Result<()> {
 | 
			
		||||
    let interactive_terminal = atty::is(Stream::Stdout);
 | 
			
		||||
    let app = App::new();
 | 
			
		||||
 | 
			
		||||
    let clap_color_setting = if interactive_terminal {
 | 
			
		||||
        AppSettings::ColoredHelp
 | 
			
		||||
    } else {
 | 
			
		||||
        AppSettings::ColorNever
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let app_matches = App::new(crate_name!())
 | 
			
		||||
        .version(crate_version!())
 | 
			
		||||
        .global_setting(clap_color_setting)
 | 
			
		||||
        .global_setting(AppSettings::DeriveDisplayOrder)
 | 
			
		||||
        .global_setting(AppSettings::UnifiedHelpMessage)
 | 
			
		||||
        .global_setting(AppSettings::NextLineHelp)
 | 
			
		||||
        .setting(AppSettings::InferSubcommands)
 | 
			
		||||
        .setting(AppSettings::ArgsNegateSubcommands)
 | 
			
		||||
        .setting(AppSettings::DisableHelpSubcommand)
 | 
			
		||||
        .setting(AppSettings::VersionlessSubcommands)
 | 
			
		||||
        .max_term_width(90)
 | 
			
		||||
        .about(crate_description!())
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("language")
 | 
			
		||||
                .short("l")
 | 
			
		||||
                .long("language")
 | 
			
		||||
                .help("Set the language for highlighting")
 | 
			
		||||
                .takes_value(true),
 | 
			
		||||
        )
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("FILE")
 | 
			
		||||
                .help("File(s) to print")
 | 
			
		||||
                .multiple(true)
 | 
			
		||||
                .empty_values(false),
 | 
			
		||||
        )
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("style")
 | 
			
		||||
                .long("style")
 | 
			
		||||
                .use_delimiter(true)
 | 
			
		||||
                .takes_value(true)
 | 
			
		||||
                .possible_values(&[
 | 
			
		||||
                    "auto", "full", "plain", "changes", "header", "grid", "numbers",
 | 
			
		||||
                ])
 | 
			
		||||
                .default_value("auto")
 | 
			
		||||
                .help("Additional info to display along with content"),
 | 
			
		||||
        )
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("color")
 | 
			
		||||
                .long("color")
 | 
			
		||||
                .takes_value(true)
 | 
			
		||||
                .possible_values(&["auto", "never", "always"])
 | 
			
		||||
                .default_value("auto")
 | 
			
		||||
                .help("When to use colors"),
 | 
			
		||||
        )
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("paging")
 | 
			
		||||
                .long("paging")
 | 
			
		||||
                .takes_value(true)
 | 
			
		||||
                .possible_values(&["auto", "never", "always"])
 | 
			
		||||
                .default_value("auto")
 | 
			
		||||
                .help("When to use the pager"),
 | 
			
		||||
        )
 | 
			
		||||
        .arg(
 | 
			
		||||
            Arg::with_name("list-languages")
 | 
			
		||||
                .long("list-languages")
 | 
			
		||||
                .help("Displays supported languages"),
 | 
			
		||||
        )
 | 
			
		||||
        .subcommand(
 | 
			
		||||
            SubCommand::with_name("cache")
 | 
			
		||||
                .about("Modify the syntax-definition and theme cache")
 | 
			
		||||
                .arg(
 | 
			
		||||
                    Arg::with_name("init")
 | 
			
		||||
                        .long("init")
 | 
			
		||||
                        .short("i")
 | 
			
		||||
                        .help("Initialize the cache by loading from the config dir"),
 | 
			
		||||
                )
 | 
			
		||||
                .arg(
 | 
			
		||||
                    Arg::with_name("clear")
 | 
			
		||||
                        .long("clear")
 | 
			
		||||
                        .short("c")
 | 
			
		||||
                        .help("Reset the cache"),
 | 
			
		||||
                )
 | 
			
		||||
                .arg(
 | 
			
		||||
                    Arg::with_name("config-dir")
 | 
			
		||||
                        .long("config-dir")
 | 
			
		||||
                        .short("d")
 | 
			
		||||
                        .help("Show the configuration directory"),
 | 
			
		||||
                )
 | 
			
		||||
                .group(
 | 
			
		||||
                    ArgGroup::with_name("cache-actions")
 | 
			
		||||
                        .args(&["init", "clear", "config-dir"])
 | 
			
		||||
                        .required(true),
 | 
			
		||||
                ),
 | 
			
		||||
        )
 | 
			
		||||
        .help_message("Print this help message.")
 | 
			
		||||
        .version_message("Show version information.")
 | 
			
		||||
        .get_matches();
 | 
			
		||||
 | 
			
		||||
    match app_matches.subcommand() {
 | 
			
		||||
    match app.matches.subcommand() {
 | 
			
		||||
        ("cache", Some(cache_matches)) => {
 | 
			
		||||
            if cache_matches.is_present("init") {
 | 
			
		||||
                let assets = HighlightingAssets::from_files()?;
 | 
			
		||||
@@ -413,57 +312,12 @@ fn run() -> Result<()> {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        _ => {
 | 
			
		||||
            let files: Vec<Option<&str>> = app_matches
 | 
			
		||||
                .values_of("FILE")
 | 
			
		||||
                .map(|values| {
 | 
			
		||||
                    values
 | 
			
		||||
                        .map(|filename| {
 | 
			
		||||
                            if filename == "-" {
 | 
			
		||||
                                None
 | 
			
		||||
                            } else {
 | 
			
		||||
                                Some(filename)
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                        .collect()
 | 
			
		||||
                })
 | 
			
		||||
                .unwrap_or_else(|| vec![None]); // read from stdin (None) if no args are given
 | 
			
		||||
 | 
			
		||||
            let output_components = values_t!(app_matches.values_of("style"), OutputComponent)?
 | 
			
		||||
                .into_iter()
 | 
			
		||||
                .map(|style| style.components(interactive_terminal))
 | 
			
		||||
                .fold(HashSet::new(), |mut acc, components| {
 | 
			
		||||
                    acc.extend(components.iter().cloned());
 | 
			
		||||
                    acc
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            let options = Options {
 | 
			
		||||
                true_color: is_truecolor_terminal(),
 | 
			
		||||
                output_components: OutputComponents(output_components),
 | 
			
		||||
                language: app_matches.value_of("language"),
 | 
			
		||||
                colored_output: match app_matches.value_of("color") {
 | 
			
		||||
                    Some("always") => true,
 | 
			
		||||
                    Some("never") => false,
 | 
			
		||||
                    _ => interactive_terminal,
 | 
			
		||||
                },
 | 
			
		||||
                paging: match app_matches.value_of("paging") {
 | 
			
		||||
                    Some("always") => true,
 | 
			
		||||
                    Some("never") => false,
 | 
			
		||||
                    Some("auto") | _ => if files.contains(&None) {
 | 
			
		||||
                        // If we are reading from stdin, only enable paging if we write to an
 | 
			
		||||
                        // interactive terminal and if we do not *read* from an interactive
 | 
			
		||||
                        // terminal.
 | 
			
		||||
                        interactive_terminal && !atty::is(Stream::Stdin)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        interactive_terminal
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                term_width: console::Term::stdout().size().1 as usize,
 | 
			
		||||
            };
 | 
			
		||||
            let config = app.config()?;
 | 
			
		||||
 | 
			
		||||
            let assets = HighlightingAssets::new();
 | 
			
		||||
            let theme = assets.default_theme()?;
 | 
			
		||||
 | 
			
		||||
            if app_matches.is_present("list-languages") {
 | 
			
		||||
            if app.matches.is_present("list-languages") {
 | 
			
		||||
                let languages = assets.syntax_set.syntaxes();
 | 
			
		||||
 | 
			
		||||
                let longest = languages
 | 
			
		||||
@@ -481,7 +335,7 @@ fn run() -> Result<()> {
 | 
			
		||||
                    print!("{:width$}{}", lang.name, separator, width = longest);
 | 
			
		||||
 | 
			
		||||
                    // Line-wrapping for the possible file extension overflow.
 | 
			
		||||
                    let desired_width = options.term_width - longest - separator.len();
 | 
			
		||||
                    let desired_width = config.term_width - longest - separator.len();
 | 
			
		||||
                    // Number of characters on this line so far, wrap before `desired_width`
 | 
			
		||||
                    let mut num_chars = 0;
 | 
			
		||||
 | 
			
		||||
@@ -507,14 +361,14 @@ fn run() -> Result<()> {
 | 
			
		||||
                return Ok(());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let mut output_type = get_output_type(options.paging);
 | 
			
		||||
            let mut output_type = get_output_type(config.paging);
 | 
			
		||||
            let handle = output_type.handle()?;
 | 
			
		||||
            let mut printer = Printer::new(handle, &options);
 | 
			
		||||
            let mut printer = Printer::new(handle, &config);
 | 
			
		||||
 | 
			
		||||
            for file in files {
 | 
			
		||||
            for file in &config.files {
 | 
			
		||||
                printer.line_changes = file.and_then(|filename| get_git_diff(filename));
 | 
			
		||||
 | 
			
		||||
                print_file(&options, theme, &assets.syntax_set, &mut printer, file)?;
 | 
			
		||||
                print_file(&config, theme, &assets.syntax_set, &mut printer, *file)?;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,24 @@
 | 
			
		||||
use ansi_term::Style;
 | 
			
		||||
use app::Config;
 | 
			
		||||
use diff::{LineChange, LineChanges};
 | 
			
		||||
use errors::*;
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use syntect::highlighting;
 | 
			
		||||
use terminal::as_terminal_escaped;
 | 
			
		||||
use {Colors, Options};
 | 
			
		||||
use Colors;
 | 
			
		||||
 | 
			
		||||
const PANEL_WIDTH: usize = 7;
 | 
			
		||||
 | 
			
		||||
pub struct Printer<'a> {
 | 
			
		||||
    handle: &'a mut Write,
 | 
			
		||||
    colors: Colors,
 | 
			
		||||
    options: &'a Options<'a>,
 | 
			
		||||
    config: &'a Config<'a>,
 | 
			
		||||
    pub line_changes: Option<LineChanges>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Printer<'a> {
 | 
			
		||||
    pub fn new(handle: &'a mut Write, options: &'a Options) -> Self {
 | 
			
		||||
        let colors = if options.colored_output {
 | 
			
		||||
    pub fn new(handle: &'a mut Write, config: &'a Config) -> Self {
 | 
			
		||||
        let colors = if config.colored_output {
 | 
			
		||||
            Colors::colored()
 | 
			
		||||
        } else {
 | 
			
		||||
            Colors::plain()
 | 
			
		||||
@@ -26,17 +27,17 @@ impl<'a> Printer<'a> {
 | 
			
		||||
        Printer {
 | 
			
		||||
            handle,
 | 
			
		||||
            colors,
 | 
			
		||||
            options,
 | 
			
		||||
            config,
 | 
			
		||||
            line_changes: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
 | 
			
		||||
        if !self.options.output_components.header() {
 | 
			
		||||
        if !self.config.output_components.header() {
 | 
			
		||||
            return Ok(());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if self.options.output_components.grid() {
 | 
			
		||||
        if self.config.output_components.grid() {
 | 
			
		||||
            self.print_horizontal_line('┬')?;
 | 
			
		||||
 | 
			
		||||
            write!(
 | 
			
		||||
@@ -54,7 +55,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
            self.colors.filename.paint(filename.unwrap_or("STDIN"))
 | 
			
		||||
        )?;
 | 
			
		||||
 | 
			
		||||
        if self.options.output_components.grid() {
 | 
			
		||||
        if self.config.output_components.grid() {
 | 
			
		||||
            self.print_horizontal_line('┼')?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +63,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn print_footer(&mut self) -> Result<()> {
 | 
			
		||||
        if self.options.output_components.grid() {
 | 
			
		||||
        if self.config.output_components.grid() {
 | 
			
		||||
            self.print_horizontal_line('┴')
 | 
			
		||||
        } else {
 | 
			
		||||
            Ok(())
 | 
			
		||||
@@ -80,12 +81,12 @@ impl<'a> Printer<'a> {
 | 
			
		||||
            self.print_line_border(),
 | 
			
		||||
            Some(as_terminal_escaped(
 | 
			
		||||
                ®ions,
 | 
			
		||||
                self.options.true_color,
 | 
			
		||||
                self.options.colored_output,
 | 
			
		||||
                self.config.true_color,
 | 
			
		||||
                self.config.colored_output,
 | 
			
		||||
            )),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        let grid_requested = self.options.output_components.grid();
 | 
			
		||||
        let grid_requested = self.config.output_components.grid();
 | 
			
		||||
        write!(
 | 
			
		||||
            self.handle,
 | 
			
		||||
            "{}",
 | 
			
		||||
@@ -104,14 +105,14 @@ impl<'a> Printer<'a> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_line_number(&self, line_number: usize) -> Option<String> {
 | 
			
		||||
        if self.options.output_components.numbers() {
 | 
			
		||||
        if self.config.output_components.numbers() {
 | 
			
		||||
            Some(
 | 
			
		||||
                self.colors
 | 
			
		||||
                    .line_number
 | 
			
		||||
                    .paint(format!("{:4}", line_number))
 | 
			
		||||
                    .to_string(),
 | 
			
		||||
            )
 | 
			
		||||
        } else if self.options.output_components.grid() {
 | 
			
		||||
        } else if self.config.output_components.grid() {
 | 
			
		||||
            Some("    ".to_owned())
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
@@ -119,7 +120,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_git_marker(&self, line_number: usize) -> Option<String> {
 | 
			
		||||
        if self.options.output_components.changes() {
 | 
			
		||||
        if self.config.output_components.changes() {
 | 
			
		||||
            Some(
 | 
			
		||||
                if let Some(ref changes) = self.line_changes {
 | 
			
		||||
                    match changes.get(&(line_number as u32)) {
 | 
			
		||||
@@ -133,7 +134,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
                    Style::default().paint(" ")
 | 
			
		||||
                }.to_string(),
 | 
			
		||||
            )
 | 
			
		||||
        } else if self.options.output_components.grid() {
 | 
			
		||||
        } else if self.config.output_components.grid() {
 | 
			
		||||
            Some(" ".to_owned())
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
@@ -141,7 +142,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_line_border(&self) -> Option<String> {
 | 
			
		||||
        if self.options.output_components.grid() {
 | 
			
		||||
        if self.config.output_components.grid() {
 | 
			
		||||
            Some(self.colors.grid.paint("│").to_string())
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
@@ -149,7 +150,7 @@ impl<'a> Printer<'a> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
 | 
			
		||||
        let hline = "─".repeat(self.options.term_width - (PANEL_WIDTH + 1));
 | 
			
		||||
        let hline = "─".repeat(self.config.term_width - (PANEL_WIDTH + 1));
 | 
			
		||||
        let hline = format!("{}{}{}", "─".repeat(PANEL_WIDTH), grid_char, hline);
 | 
			
		||||
 | 
			
		||||
        writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user