Refactor: cli module

This commit is contained in:
Dan Davison 2019-07-12 11:51:40 -04:00
parent 130af6c725
commit 2c1dd918a6
2 changed files with 140 additions and 133 deletions

133
src/cli.rs Normal file
View File

@ -0,0 +1,133 @@
use std::process;
use console::Term;
use structopt::StructOpt;
use crate::bat::assets::HighlightingAssets;
use crate::paint;
#[derive(StructOpt, Debug)]
#[structopt(name = "delta", about = "A syntax-highlighter for git.")]
pub struct Opt {
/// Use colors appropriate for a light terminal background. For
/// more control, see --theme, --plus-color, and --minus-color.
#[structopt(long = "light")]
pub light: bool,
/// Use colors appropriate for a dark terminal background. For
/// more control, see --theme, --plus-color, and --minus-color.
#[structopt(long = "dark")]
pub dark: bool,
#[structopt(long = "minus-color")]
/// The background color (RGB hex) to use for removed lines.
pub minus_color: Option<String>,
#[structopt(long = "minus-emph-color")]
/// The background color (RGB hex) to use for emphasized sections of removed lines.
pub minus_emph_color: Option<String>,
#[structopt(long = "plus-color")]
/// The background color (RGB hex) to use for added lines.
pub plus_color: Option<String>,
#[structopt(long = "plus-emph-color")]
/// The background color (RGB hex) to use for emphasized sections of added lines.
pub plus_emph_color: Option<String>,
#[structopt(long = "theme")]
/// The syntax highlighting theme to use.
pub theme: Option<String>,
#[structopt(long = "highlight-removed")]
/// Apply syntax highlighting to removed lines. The default is to
/// apply syntax highlighting to unchanged and new lines only.
pub highlight_removed: bool,
#[structopt(long = "no-structural-changes")]
/// Do not modify input text; only add colors. This disables
/// prettification of metadata sections in the git diff output.
pub no_structural_changes: bool,
/// The width (in characters) of the background color
/// highlighting. By default, the width is the current terminal
/// width. Use --width=variable to apply background colors to the
/// end of each line, without right padding to equal width.
#[structopt(short = "w", long = "width")]
pub width: Option<String>,
/// List supported languages and associated file extensions.
#[structopt(long = "list-languages")]
pub list_languages: bool,
/// List available syntax highlighting themes.
#[structopt(long = "list-themes")]
pub list_themes: bool,
/// Compare available syntax highlighting themes. To use this
/// option, supply git diff output to delta on standard input.
/// For example: `git show --color=always | delta --compare-themes`.
#[structopt(long = "compare-themes")]
pub compare_themes: bool,
}
pub fn process_command_line_arguments<'a>(
assets: &'a HighlightingAssets,
opt: &'a Opt,
) -> paint::Config<'a> {
if opt.light && opt.dark {
eprintln!("--light and --dark cannot be used together.");
process::exit(1);
}
match &opt.theme {
Some(theme) => {
if !assets.theme_set.themes.contains_key(theme.as_str()) {
eprintln!("Invalid theme: '{}'", theme);
process::exit(1);
}
let is_light_theme = paint::LIGHT_THEMES.contains(&theme.as_str());
if is_light_theme && opt.dark {
eprintln!(
"{} is a light theme, but you supplied --dark. \
If you use --theme, you do not need to supply --light or --dark.",
theme
);
process::exit(1);
} else if !is_light_theme && opt.light {
eprintln!(
"{} is a dark theme, but you supplied --light. \
If you use --theme, you do not need to supply --light or --dark.",
theme
);
process::exit(1);
}
}
None => (),
};
let terminal_width = Term::stdout().size().1 as usize;
let width = match opt.width.as_ref().map(String::as_str) {
Some("variable") => None,
Some(width) => Some(
width
.parse::<usize>()
.unwrap_or_else(|_| panic!("Invalid width: {}", width)),
),
None => Some(terminal_width - 1),
};
paint::get_config(
&assets.syntax_set,
&opt.theme,
&assets.theme_set,
opt.light,
&opt.minus_color,
&opt.minus_emph_color,
&opt.plus_color,
&opt.plus_emph_color,
opt.highlight_removed,
opt.no_structural_changes,
terminal_width,
width,
)
}

View File

@ -2,6 +2,7 @@
extern crate error_chain;
mod bat;
mod cli;
mod draw;
mod paint;
mod parse;
@ -9,7 +10,6 @@ mod parse;
use std::io::{self, BufRead, ErrorKind, Read, Write};
use std::process;
use console::Term;
use structopt::StructOpt;
use crate::bat::assets::{list_languages, HighlightingAssets};
@ -26,73 +26,8 @@ mod errors {
}
}
#[derive(StructOpt, Debug)]
#[structopt(name = "delta", about = "A syntax-highlighter for git.")]
struct Opt {
/// Use colors appropriate for a light terminal background. For
/// more control, see --theme, --plus-color, and --minus-color.
#[structopt(long = "light")]
light: bool,
/// Use colors appropriate for a dark terminal background. For
/// more control, see --theme, --plus-color, and --minus-color.
#[structopt(long = "dark")]
dark: bool,
#[structopt(long = "minus-color")]
/// The background color (RGB hex) to use for removed lines.
minus_color: Option<String>,
#[structopt(long = "minus-emph-color")]
/// The background color (RGB hex) to use for emphasized sections of removed lines.
minus_emph_color: Option<String>,
#[structopt(long = "plus-color")]
/// The background color (RGB hex) to use for added lines.
plus_color: Option<String>,
#[structopt(long = "plus-emph-color")]
/// The background color (RGB hex) to use for emphasized sections of added lines.
plus_emph_color: Option<String>,
#[structopt(long = "theme")]
/// The syntax highlighting theme to use.
theme: Option<String>,
#[structopt(long = "highlight-removed")]
/// Apply syntax highlighting to removed lines. The default is to
/// apply syntax highlighting to unchanged and new lines only.
highlight_removed: bool,
#[structopt(long = "no-structural-changes")]
/// Do not modify input text; only add colors. This disables
/// prettification of metadata sections in the git diff output.
no_structural_changes: bool,
/// The width (in characters) of the background color
/// highlighting. By default, the width is the current terminal
/// width. Use --width=variable to apply background colors to the
/// end of each line, without right padding to equal width.
#[structopt(short = "w", long = "width")]
width: Option<String>,
/// List supported languages and associated file extensions.
#[structopt(long = "list-languages")]
list_languages: bool,
/// List available syntax highlighting themes.
#[structopt(long = "list-themes")]
list_themes: bool,
/// Compare available syntax highlighting themes. To use this
/// option, supply git diff output to delta on standard input.
/// For example: `git show --color=always | delta --compare-themes`.
#[structopt(long = "compare-themes")]
compare_themes: bool,
}
fn main() -> std::io::Result<()> {
let opt = Opt::from_args();
let opt = cli::Opt::from_args();
let assets = HighlightingAssets::new();
@ -107,7 +42,7 @@ fn main() -> std::io::Result<()> {
process::exit(0);
}
let paint_config = process_command_line_arguments(&assets, &opt);
let paint_config = cli::process_command_line_arguments(&assets, &opt);
let mut output_type =
OutputType::from_mode(PagingMode::QuitIfOneScreen, Some(paint_config.pager)).unwrap();
@ -128,69 +63,8 @@ fn main() -> std::io::Result<()> {
Ok(())
}
fn process_command_line_arguments<'a>(
assets: &'a HighlightingAssets,
opt: &'a Opt,
) -> paint::Config<'a> {
if opt.light && opt.dark {
eprintln!("--light and --dark cannot be used together.");
process::exit(1);
}
match &opt.theme {
Some(theme) => {
if !assets.theme_set.themes.contains_key(theme.as_str()) {
eprintln!("Invalid theme: '{}'", theme);
process::exit(1);
}
let is_light_theme = paint::LIGHT_THEMES.contains(&theme.as_str());
if is_light_theme && opt.dark {
eprintln!(
"{} is a light theme, but you supplied --dark. \
If you use --theme, you do not need to supply --light or --dark.",
theme
);
process::exit(1);
} else if !is_light_theme && opt.light {
eprintln!(
"{} is a dark theme, but you supplied --light. \
If you use --theme, you do not need to supply --light or --dark.",
theme
);
process::exit(1);
}
}
None => (),
};
let terminal_width = Term::stdout().size().1 as usize;
let width = match opt.width.as_ref().map(String::as_str) {
Some("variable") => None,
Some(width) => Some(
width
.parse::<usize>()
.unwrap_or_else(|_| panic!("Invalid width: {}", width)),
),
None => Some(terminal_width - 1),
};
paint::get_config(
&assets.syntax_set,
&opt.theme,
&assets.theme_set,
opt.light,
&opt.minus_color,
&opt.minus_emph_color,
&opt.plus_color,
&opt.plus_emph_color,
opt.highlight_removed,
opt.no_structural_changes,
terminal_width,
width,
)
}
fn compare_themes(assets: &HighlightingAssets) -> std::io::Result<()> {
let mut opt = Opt::from_args();
let mut opt = cli::Opt::from_args();
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
@ -207,7 +81,7 @@ fn compare_themes(assets: &HighlightingAssets) -> std::io::Result<()> {
writeln!(stdout, "{}\n{}\n{}\n", hline, theme, hline)?;
opt.theme = Some(theme.to_string());
paint_config = process_command_line_arguments(&assets, &opt);
paint_config = cli::process_command_line_arguments(&assets, &opt);
let mut output_type =
OutputType::from_mode(PagingMode::QuitIfOneScreen, Some(paint_config.pager)).unwrap();
let mut writer = output_type.handle().unwrap();
@ -288,10 +162,10 @@ modified: a.py
pass
";
let mut opt = Opt::from_args();
let mut opt = cli::Opt::from_args();
opt.width = Some("variable".to_string());
let assets = HighlightingAssets::new();
let paint_config = process_command_line_arguments(&assets, &opt);
let paint_config = cli::process_command_line_arguments(&assets, &opt);
let mut writer: Vec<u8> = Vec::new();
delta(
input.split("\n").map(String::from),