use std::io::Write;
use itertools::Itertools;
use crate::cli;
use crate::config;
use crate::features::side_by_side::{Left, Right};
use crate::minusplus::*;
use crate::paint::BgFillMethod;
use crate::style;
use crate::utils::bat::output::PagingMode;
pub fn show_config(config: &config::Config, writer: &mut dyn Write) -> std::io::Result<()> {
writeln!(
writer,
" commit-style = {commit_style}
file-style = {file_style}
hunk-header-style = {hunk_header_style}
minus-style = {minus_style}
minus-non-emph-style = {minus_non_emph_style}
minus-emph-style = {minus_emph_style}
minus-empty-line-marker-style = {minus_empty_line_marker_style}
zero-style = {zero_style}
plus-style = {plus_style}
plus-non-emph-style = {plus_non_emph_style}
plus-emph-style = {plus_emph_style}
plus-empty-line-marker-style = {plus_empty_line_marker_style}
grep-file-style = {grep_file_style}
grep-line-number-style = {grep_line_number_style}
whitespace-error-style = {whitespace_error_style}
blame-palette = {blame_palette}",
blame_palette = config
.blame_palette
.iter()
.map(|s| style::paint_color_string(s, config.true_color, config.git_config()))
.join(" "),
commit_style = config.commit_style.to_painted_string(),
file_style = config.file_style.to_painted_string(),
hunk_header_style = config.hunk_header_style.to_painted_string(),
minus_emph_style = config.minus_emph_style.to_painted_string(),
minus_empty_line_marker_style = config.minus_empty_line_marker_style.to_painted_string(),
minus_non_emph_style = config.minus_non_emph_style.to_painted_string(),
minus_style = config.minus_style.to_painted_string(),
plus_emph_style = config.plus_emph_style.to_painted_string(),
plus_empty_line_marker_style = config.plus_empty_line_marker_style.to_painted_string(),
plus_non_emph_style = config.plus_non_emph_style.to_painted_string(),
plus_style = config.plus_style.to_painted_string(),
grep_file_style = config.grep_file_style.to_painted_string(),
grep_line_number_style = config.grep_line_number_style.to_painted_string(),
whitespace_error_style = config.whitespace_error_style.to_painted_string(),
zero_style = config.zero_style.to_painted_string(),
)?;
writeln!(
writer,
" true-color = {true_color}
file-added-label = {file_added_label}
file-modified-label = {file_modified_label}
file-removed-label = {file_removed_label}
file-renamed-label = {file_renamed_label}
right-arrow = {right_arrow}",
true_color = config.true_color,
file_added_label = format_option_value(&config.file_added_label),
file_modified_label = format_option_value(&config.file_modified_label),
file_removed_label = format_option_value(&config.file_removed_label),
file_renamed_label = format_option_value(&config.file_renamed_label),
right_arrow = format_option_value(&config.right_arrow),
)?;
writeln!(
writer,
" hyperlinks = {hyperlinks}",
hyperlinks = config.hyperlinks
)?;
if config.hyperlinks {
writeln!(
writer,
" hyperlinks-file-link-format = {hyperlinks_file_link_format}",
hyperlinks_file_link_format = format_option_value(&config.hyperlinks_file_link_format),
)?
}
writeln!(
writer,
" inspect-raw-lines = {inspect_raw_lines}
keep-plus-minus-markers = {keep_plus_minus_markers}",
inspect_raw_lines = match config.inspect_raw_lines {
cli::InspectRawLines::True => "true",
cli::InspectRawLines::False => "false",
},
keep_plus_minus_markers = config.keep_plus_minus_markers,
)?;
writeln!(
writer,
" line-numbers = {line_numbers}",
line_numbers = config.line_numbers
)?;
if config.line_numbers {
writeln!(
writer,
" line-numbers-minus-style = {line_numbers_minus_style}
line-numbers-zero-style = {line_numbers_zero_style}
line-numbers-plus-style = {line_numbers_plus_style}
line-numbers-left-style = {line_numbers_left_style}
line-numbers-right-style = {line_numbers_right_style}
line-numbers-left-format = {line_numbers_left_format}
line-numbers-right-format = {line_numbers_right_format}",
line_numbers_minus_style =
config.line_numbers_style_minusplus[Minus].to_painted_string(),
line_numbers_zero_style = config.line_numbers_zero_style.to_painted_string(),
line_numbers_plus_style = config.line_numbers_style_minusplus[Plus].to_painted_string(),
line_numbers_left_style = config.line_numbers_style_leftright[Left].to_painted_string(),
line_numbers_right_style =
config.line_numbers_style_leftright[Right].to_painted_string(),
line_numbers_left_format = format_option_value(&config.line_numbers_format[Left]),
line_numbers_right_format = format_option_value(&config.line_numbers_format[Right]),
)?
}
writeln!(
writer,
" max-line-distance = {max_line_distance}
max-line-length = {max_line_length}
diff-stat-align-width = {diff_stat_align_width}
line-fill-method = {line_fill_method}
navigate = {navigate}
navigate-regex = {navigate_regex}
pager = {pager}
paging = {paging_mode}
side-by-side = {side_by_side}
syntax-theme = {syntax_theme}
width = {width}
tabs = {tab_width}
word-diff-regex = {tokenization_regex}",
diff_stat_align_width = config.diff_stat_align_width,
max_line_distance = config.max_line_distance,
max_line_length = config.max_line_length,
line_fill_method = match config.line_fill_method {
BgFillMethod::TryAnsiSequence => "ansi",
BgFillMethod::Spaces => "spaces",
},
navigate = config.navigate,
navigate_regex = match &config.navigate_regex {
None => "".to_string(),
Some(s) => format_option_value(s),
},
pager = config.pager.clone().unwrap_or_else(|| "none".to_string()),
paging_mode = match config.paging_mode {
PagingMode::Always => "always",
PagingMode::Never => "never",
PagingMode::QuitIfOneScreen => "auto",
PagingMode::Capture => unreachable!("capture can not be set"),
},
side_by_side = config.side_by_side,
syntax_theme = config
.syntax_theme
.clone()
.map(|t| t.name.unwrap_or_else(|| "none".to_string()))
.unwrap_or_else(|| "none".to_string()),
width = match config.decorations_width {
cli::Width::Fixed(width) => width.to_string(),
cli::Width::Variable => "variable".to_string(),
},
tab_width = config.tab_cfg.width(),
tokenization_regex = format_option_value(config.tokenization_regex.to_string()),
)?;
Ok(())
}
fn format_option_value<S>(s: S) -> String
where
S: AsRef<str>,
{
let s = s.as_ref();
if s.ends_with(' ')
|| s.starts_with(' ')
|| s.contains(&['\\', '{', '}', ':'][..])
|| s.is_empty()
{
format!("'{s}'")
} else {
s.to_string()
}
}
#[cfg(test)]
mod tests {
use crate::tests::integration_test_utils;
use super::*;
use crate::ansi;
use std::io::{Cursor, Read, Seek};
#[test]
fn test_show_config() {
let config = integration_test_utils::make_config_from_args(&[]);
let mut writer = Cursor::new(vec![0; 1024]);
show_config(&config, &mut writer).unwrap();
let mut s = String::new();
writer.rewind().unwrap();
writer.read_to_string(&mut s).unwrap();
let s = ansi::strip_ansi_codes(&s);
assert!(s.contains(" commit-style = raw\n"));
assert!(s.contains(r" word-diff-regex = '\w+'"));
}
}