summaryrefslogtreecommitdiffstats
path: root/src/pretty_printer.rs
blob: da46ce9b1eb7d2a5f59043cc713092b22c1e2633 (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
use std::ffi::OsStr;
use std::io::Read;

use crate::{
    config::{
        Config, HighlightedLineRanges, LineRanges, StyleComponents, SyntaxMapping, WrappingMode,
    },
    errors::Result,
    input::{Input, InputKind, OpenedInput},
    Controller, HighlightingAssets,
};

#[cfg(feature = "paging")]
use crate::config::PagingMode;

pub struct PrettyPrinter<'a> {
    inputs: Vec<Input>,
    config: Config<'a>,
    assets: HighlightingAssets,
}

impl<'a> PrettyPrinter<'a> {
    pub fn new() -> Self {
        let mut config = Config::default();

        config.colored_output = true;
        config.true_color = true;

        PrettyPrinter {
            inputs: vec![],
            config,
            assets: HighlightingAssets::from_binary(),
        }
    }

    /// Add a file which should be pretty-printed
    pub fn input_file(&mut self, path: &OsStr) -> &mut Self {
        // self.inputs
        //     .push(Input::Ordinary(OrdinaryFile::from_path(path)));
        self
    }

    /// Add multiple files which should be pretty-printed
    pub fn input_files<I, P>(&mut self, paths: I) -> &mut Self
    where
        I: IntoIterator<Item = P>,
        P: AsRef<OsStr>,
    {
        for path in paths {
            // self.inputs
            //     .push(Input::Ordinary(OrdinaryFile::from_path(path.as_ref())));
        }
        self
    }

    /// Add STDIN as an input
    pub fn input_stdin(&mut self) -> &mut Self {
        // self.inputs.push(Input::StdIn(None));
        self
    }

    /// Add a custom reader as an input
    pub fn input_reader(&mut self, reader: impl Read) -> &mut Self {
        //self.inputs.push(Input::FromReader(Box::new(reader), None));
        self
    }

    /// Specify the syntax file which should be used (default: auto-detect)
    pub fn language(&mut self, language: &'a str) -> &mut Self {
        self.config.language = Some(language);
        self
    }

    /// The character width of the terminal (default: unlimited)
    pub fn term_width(&mut self, width: usize) -> &mut Self {
        self.config.term_width = width;
        self
    }

    /// The width of tab characters (default: None - do not turn tabs to spaces)
    pub fn tab_width(&mut self, tab_width: Option<usize>) -> &mut Self {
        self.config.tab_width = tab_width.unwrap_or(0);
        self
    }

    /// Whether or not the output should be colorized (default: true)
    pub fn colored_output(&mut self, yes: bool) -> &mut Self {
        self.config.colored_output = yes;
        self
    }

    /// Whether or not to output 24bit colors (default: true)
    pub fn true_color(&mut self, yes: bool) -> &mut Self {
        self.config.true_color = yes;
        self
    }

    /// Configure style elements like grid or  line numbers (default: "full" style)
    pub fn style_components(&mut self, components: StyleComponents) -> &mut Self {
        self.config.style_components = components;
        self
    }

    /// Text wrapping mode (default: do not wrap)
    pub fn wrapping_mode(&mut self, mode: WrappingMode) -> &mut Self {
        self.config.wrapping_mode = mode;
        self
    }

    /// Whether or not to use ANSI italics (default: off)
    pub fn use_italics(&mut self, yes: bool) -> &mut Self {
        self.config.use_italic_text = yes;
        self
    }

    /// If and how to use a pager (default: no paging)
    #[cfg(feature = "paging")]
    pub fn paging_mode(&mut self, mode: PagingMode) -> &mut Self {
        self.config.paging_mode = mode;
        self
    }

    /// Specify the command to start the pager (default: use "less")
    #[cfg(feature = "paging")]
    pub fn pager(&mut self, cmd: &'a str) -> &mut Self {
        self.config.pager = Some(cmd);
        self
    }

    /// Specify the lines that should be printed (default: all)
    pub fn line_ranges(&mut self, ranges: LineRanges) -> &mut Self {
        self.config.line_ranges = ranges;
        self
    }

    /// Specify which lines should be highlighted (default: none)
    pub fn highlighted_lines(&mut self, ranges: HighlightedLineRanges) -> &mut Self {
        self.config.highlighted_lines = ranges;
        self
    }

    /// Specify the highlighting theme
    pub fn theme(&mut self, theme: impl AsRef<str>) -> &mut Self {
        self.config.theme = theme.as_ref().to_owned();
        self
    }

    /// Specify custom file extension / file name to syntax mappings
    pub fn syntax_mapping(&mut self, mapping: SyntaxMapping<'a>) -> &mut Self {
        self.config.syntax_mapping = mapping;
        self
    }

    /// Pretty-print all specified inputs. This method will drain all stored inputs.
    /// If you want to call 'run' multiple times, you have to call the appropriate
    /// input_* methods again.
    pub fn run(&mut self) -> Result<bool> {
        let mut inputs: Vec<Input> = vec![];
        std::mem::swap(&mut inputs, &mut self.inputs);

        let controller = Controller::new(&self.config, &self.assets);
        controller.run(inputs)
    }
}