summaryrefslogtreecommitdiffstats
path: root/src/config.rs
blob: 2151b08637d07ab9d1755462761ece38214f9529 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::str::FromStr;

use syntect::highlighting::{Color, Style, StyleModifier, Theme, ThemeSet};
use syntect::parsing::SyntaxSet;

use crate::cli;
use crate::style;

pub struct Config<'a> {
    pub theme: &'a Theme,
    pub theme_name: &'a str,
    pub minus_style_modifier: StyleModifier,
    pub minus_emph_style_modifier: StyleModifier,
    pub plus_style_modifier: StyleModifier,
    pub plus_emph_style_modifier: StyleModifier,
    pub syntax_set: &'a SyntaxSet,
    pub terminal_width: usize,
    pub width: Option<usize>,
    pub pager: &'a str,
    pub opt: &'a cli::Opt,
    pub no_style: Style,
    pub max_buffered_lines: usize,
}

pub fn get_config<'a>(
    opt: &'a cli::Opt,
    syntax_set: &'a SyntaxSet,
    theme_set: &'a ThemeSet,
    terminal_width: usize,
    width: Option<usize>,
) -> Config<'a> {
    let theme_name = match opt.theme {
        Some(ref theme) => theme,
        None => {
            if opt.light {
                style::DEFAULT_LIGHT_THEME
            } else {
                style::DEFAULT_DARK_THEME
            }
        }
    };
    let is_light_theme = style::LIGHT_THEMES.contains(&theme_name);

    let minus_style_modifier = StyleModifier {
        background: Some(color_from_arg(
            &opt.minus_color,
            is_light_theme,
            style::LIGHT_THEME_MINUS_COLOR,
            style::DARK_THEME_MINUS_COLOR,
        )),
        foreground: if opt.highlight_removed {
            None
        } else {
            Some(style::NO_COLOR)
        },
        font_style: None,
    };

    let minus_emph_style_modifier = StyleModifier {
        background: Some(color_from_arg(
            &opt.minus_emph_color,
            is_light_theme,
            style::LIGHT_THEME_MINUS_EMPH_COLOR,
            style::DARK_THEME_MINUS_EMPH_COLOR,
        )),
        foreground: if opt.highlight_removed {
            None
        } else {
            Some(style::NO_COLOR)
        },
        font_style: None,
    };

    let plus_style_modifier = StyleModifier {
        background: Some(color_from_arg(
            &opt.plus_color,
            is_light_theme,
            style::LIGHT_THEME_PLUS_COLOR,
            style::DARK_THEME_PLUS_COLOR,
        )),
        foreground: None,
        font_style: None,
    };

    let plus_emph_style_modifier = StyleModifier {
        background: Some(color_from_arg(
            &opt.plus_emph_color,
            is_light_theme,
            style::LIGHT_THEME_PLUS_EMPH_COLOR,
            style::DARK_THEME_PLUS_EMPH_COLOR,
        )),
        foreground: None,
        font_style: None,
    };

    Config {
        theme: &theme_set.themes[theme_name],
        theme_name,
        minus_style_modifier,
        minus_emph_style_modifier,
        plus_style_modifier,
        plus_emph_style_modifier,
        terminal_width,
        width,
        syntax_set,
        pager: "less",
        opt,
        no_style: style::get_no_style(),
        max_buffered_lines: 32,
    }
}

fn color_from_arg(
    arg: &Option<String>,
    is_light_theme: bool,
    light_theme_default: Color,
    dark_theme_default: Color,
) -> Color {
    arg.as_ref()
        .and_then(|s| Color::from_str(s).ok())
        .unwrap_or_else(|| {
            if is_light_theme {
                light_theme_default
            } else {
                dark_theme_default
            }
        })
}