1use std::io::{self, ErrorKind};
2use std::process;
3
4use bytelines::ByteLinesReader;
5
6use crate::cli;
7use crate::config;
8use crate::delta::delta;
9use crate::fatal;
10use crate::git_config;
11use crate::subcommands;
12use crate::utils;
13use crate::utils::bat::assets::list_languages;
14use crate::utils::bat::output::OutputType;
15
16#[cfg(not(tarpaulin_include))]
17pub fn mainfn() -> std::io::Result<()> {
20 utils::process::start_determining_calling_process_in_thread();
25
26 ctrlc::set_handler(|| {})
29 .unwrap_or_else(|err| eprintln!("Failed to set ctrl-c handler: {}", err));
30 let exit_code = run_app()?;
31 process::exit(exit_code);
33}
34
35#[cfg(not(tarpaulin_include))]
36fn run_app() -> std::io::Result<i32> {
40 let assets = utils::bat::assets::load_highlighting_assets();
41 let opt = cli::Opt::from_args_and_git_config(git_config::GitConfig::try_create(), assets);
42
43 let subcommand_result = if opt.list_languages {
44 Some(list_languages())
45 } else if opt.list_syntax_themes {
46 Some(subcommands::list_syntax_themes::list_syntax_themes())
47 } else if opt.show_syntax_themes {
48 Some(subcommands::show_syntax_themes::show_syntax_themes())
49 } else if opt.show_themes {
50 Some(subcommands::show_themes::show_themes(
51 opt.dark,
52 opt.light,
53 opt.computed.is_light_mode,
54 ))
55 } else if opt.show_colors {
56 Some(subcommands::show_colors::show_colors())
57 } else if opt.parse_ansi {
58 Some(subcommands::parse_ansi::parse_ansi())
59 } else {
60 None
61 };
62 if let Some(result) = subcommand_result {
63 if let Err(error) = result {
64 match error.kind() {
65 ErrorKind::BrokenPipe => {}
66 _ => fatal(format!("{}", error)),
67 }
68 }
69 return Ok(0);
70 };
71
72 let _show_config = opt.show_config;
73 let config = config::Config::from(opt);
74
75 if _show_config {
76 let stdout = io::stdout();
77 let mut stdout = stdout.lock();
78 subcommands::show_config::show_config(&config, &mut stdout)?;
79 return Ok(0);
80 }
81
82 let mut output_type =
83 OutputType::from_mode(config.paging_mode, config.pager.clone(), &config).unwrap();
84 let mut writer = output_type.handle().unwrap();
85
86 match (config.minus_file.as_ref(), config.plus_file.as_ref()) {
87 (None, None) => {}
88 (Some(minus_file), Some(plus_file)) => {
89 let exit_code = subcommands::diff::diff(minus_file, plus_file, &config, &mut writer);
90 return Ok(exit_code);
91 }
92 _ => {
93 eprintln!(
94 "\
95 The main way to use delta is to configure it as the pager for git: \
96 see https://github.com/dandavison/delta#configuration. \
97 You can also use delta to diff two files: `delta file_A file_B`."
98 );
99 return Ok(config.error_exit_code);
100 }
101 }
102
103 if let Err(error) = delta(io::stdin().lock().byte_lines(), &mut writer, &config) {
104 match error.kind() {
105 ErrorKind::BrokenPipe => return Ok(0),
106 _ => eprintln!("{}", error),
107 }
108 };
109 Ok(0)
110}