on master help sign in
Rename output component to 'style compinent', move wrap to separate module
84ba323sharkdp
examples/simple.rs+5−5
@@ -3,7 +3,7 @@ use bat::{
3 config::Config,
3 config::Config,
4 controller::Controller,
4 controller::Controller,
5 inputfile::InputFile,
5 inputfile::InputFile,
6− style::{OutputComponent, OutputComponents},
6+ style::{StyleComponent, StyleComponents},
7};
7};
8use console::Term;
8use console::Term;
9use std::process;
9use std::process;
@@ -20,10 +20,10 @@ fn main() {
20 term_width: Term::stdout().size().1 as usize,
20 term_width: Term::stdout().size().1 as usize,
21 colored_output: true,
21 colored_output: true,
22 true_color: true,
22 true_color: true,
23− output_components: OutputComponents::new(&[
23+ style_components: StyleComponents::new(&[
24− OutputComponent::Header,
24+ StyleComponent::Header,
25− OutputComponent::Grid,
25+ StyleComponent::Grid,
26− OutputComponent::Numbers,
26+ StyleComponent::Numbers,
27 ]),
27 ]),
28 files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
28 files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
29 theme: "1337".into(),
29 theme: "1337".into(),
src/bin/bat/app.rs+15−14
@@ -22,8 +22,9 @@ use bat::{
22 errors::*,
22 errors::*,
23 inputfile::InputFile,
23 inputfile::InputFile,
24 line_range::{HighlightedLineRanges, LineRange, LineRanges},
24 line_range::{HighlightedLineRanges, LineRange, LineRanges},
25− style::{OutputComponent, OutputComponents, OutputWrap},
25+ style::{StyleComponent, StyleComponents},
26 syntax_mapping::SyntaxMapping,
26 syntax_mapping::SyntaxMapping,
27+ wrap::OutputWrap,
27};
28};
28
29
29fn is_truecolor_terminal() -> bool {
30fn is_truecolor_terminal() -> bool {
@@ -79,7 +80,7 @@ impl App {
79
80
80 pub fn config(&self) -> Result<Config> {
81 pub fn config(&self) -> Result<Config> {
81 let files = self.files();
82 let files = self.files();
82− let output_components = self.output_components()?;
83+ let style_components = self.style_components()?;
83
84
84 let paging_mode = match self.matches.value_of("paging") {
85 let paging_mode = match self.matches.value_of("paging") {
85 Some("always") => PagingMode::Always,
86 Some("always") => PagingMode::Always,
@@ -152,7 +153,7 @@ impl App {
152 Some("character") => OutputWrap::Character,
153 Some("character") => OutputWrap::Character,
153 Some("never") => OutputWrap::None,
154 Some("never") => OutputWrap::None,
154 Some("auto") | _ => {
155 Some("auto") | _ => {
155− if output_components.plain() {
156+ if style_components.plain() {
156 OutputWrap::None
157 OutputWrap::None
157 } else {
158 } else {
158 OutputWrap::Character
159 OutputWrap::Character
@@ -182,7 +183,7 @@ impl App {
182 .or_else(|| env::var("BAT_TABS").ok())
183 .or_else(|| env::var("BAT_TABS").ok())
183 .and_then(|t| t.parse().ok())
184 .and_then(|t| t.parse().ok())
184 .unwrap_or(
185 .unwrap_or(
185− if output_components.plain() && paging_mode == PagingMode::Never {
186+ if style_components.plain() && paging_mode == PagingMode::Never {
186 0
187 0
187 } else {
188 } else {
188 4
189 4
@@ -208,7 +209,7 @@ impl App {
208 .transpose()?
209 .transpose()?
209 .map(LineRanges::from)
210 .map(LineRanges::from)
210 .unwrap_or_default(),
211 .unwrap_or_default(),
211− output_components,
212+ style_components,
212 syntax_mapping,
213 syntax_mapping,
213 pager: self.matches.value_of("pager"),
214 pager: self.matches.value_of("pager"),
214 use_italic_text: match self.matches.value_of("italic-text") {
215 use_italic_text: match self.matches.value_of("italic-text") {
@@ -243,23 +244,23 @@ impl App {
243 .unwrap_or_else(|| vec![InputFile::StdIn])
244 .unwrap_or_else(|| vec![InputFile::StdIn])
244 }
245 }
245
246
246− fn output_components(&self) -> Result<OutputComponents> {
247+ fn style_components(&self) -> Result<StyleComponents> {
247 let matches = &self.matches;
248 let matches = &self.matches;
248− Ok(OutputComponents(
249+ Ok(StyleComponents(
249 if matches.value_of("decorations") == Some("never") {
250 if matches.value_of("decorations") == Some("never") {
250 HashSet::new()
251 HashSet::new()
251 } else if matches.is_present("number") {
252 } else if matches.is_present("number") {
252− [OutputComponent::Numbers].iter().cloned().collect()
253+ [StyleComponent::Numbers].iter().cloned().collect()
253 } else if matches.is_present("plain") {
254 } else if matches.is_present("plain") {
254− [OutputComponent::Plain].iter().cloned().collect()
255+ [StyleComponent::Plain].iter().cloned().collect()
255 } else {
256 } else {
256− let env_style_components: Option<Vec<OutputComponent>> = env::var("BAT_STYLE")
257+ let env_style_components: Option<Vec<StyleComponent>> = env::var("BAT_STYLE")
257 .ok()
258 .ok()
258 .map(|style_str| {
259 .map(|style_str| {
259 style_str
260 style_str
260 .split(',')
261 .split(',')
261− .map(|x| OutputComponent::from_str(&x))
262+ .map(|x| StyleComponent::from_str(&x))
262− .collect::<Result<Vec<OutputComponent>>>()
263+ .collect::<Result<Vec<StyleComponent>>>()
263 })
264 })
264 .transpose()?;
265 .transpose()?;
265
266
@@ -268,12 +269,12 @@ impl App {
268 .map(|styles| {
269 .map(|styles| {
269 styles
270 styles
270 .split(',')
271 .split(',')
271− .map(|style| style.parse::<OutputComponent>())
272+ .map(|style| style.parse::<StyleComponent>())
272 .filter_map(|style| style.ok())
273 .filter_map(|style| style.ok())
273 .collect::<Vec<_>>()
274 .collect::<Vec<_>>()
274 })
275 })
275 .or(env_style_components)
276 .or(env_style_components)
276− .unwrap_or_else(|| vec![OutputComponent::Full])
277+ .unwrap_or_else(|| vec![StyleComponent::Full])
277 .into_iter()
278 .into_iter()
278 .map(|style| style.components(self.interactive_output))
279 .map(|style| style.components(self.interactive_output))
279 .fold(HashSet::new(), |mut acc, components| {
280 .fold(HashSet::new(), |mut acc, components| {
src/bin/bat/main.rs+3−3
@@ -32,7 +32,7 @@ use bat::{
32 config::Config,
32 config::Config,
33 errors::*,
33 errors::*,
34 inputfile::InputFile,
34 inputfile::InputFile,
35− style::{OutputComponent, OutputComponents},
35+ style::{StyleComponent, StyleComponents},
36};
36};
37
37
38fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
38fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
@@ -123,9 +123,9 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
123 let assets = assets_from_cache_or_binary();
123 let assets = assets_from_cache_or_binary();
124 let mut config = cfg.clone();
124 let mut config = cfg.clone();
125 let mut style = HashSet::new();
125 let mut style = HashSet::new();
126− style.insert(OutputComponent::Plain);
126+ style.insert(StyleComponent::Plain);
127 config.files = vec![InputFile::ThemePreviewFile];
127 config.files = vec![InputFile::ThemePreviewFile];
128− config.output_components = OutputComponents(style);
128+ config.style_components = StyleComponents(style);
129
129
130 let stdout = io::stdout();
130 let stdout = io::stdout();
131 let mut stdout = stdout.lock();
131 let mut stdout = stdout.lock();
src/config.rs+3−2
@@ -1,7 +1,8 @@
1use crate::inputfile::InputFile;
1use crate::inputfile::InputFile;
2use crate::line_range::{HighlightedLineRanges, LineRanges};
2use crate::line_range::{HighlightedLineRanges, LineRanges};
3−use crate::style::{OutputComponents, OutputWrap};
3+use crate::style::StyleComponents;
4use crate::syntax_mapping::SyntaxMapping;
4use crate::syntax_mapping::SyntaxMapping;
5+use crate::wrap::OutputWrap;
5
6
6#[derive(Debug, Clone, Copy, PartialEq)]
7#[derive(Debug, Clone, Copy, PartialEq)]
7pub enum PagingMode {
8pub enum PagingMode {
@@ -44,7 +45,7 @@ pub struct Config<'a> {
44 pub true_color: bool,
45 pub true_color: bool,
45
46
46 /// Style elements (grid, line numbers, ...)
47 /// Style elements (grid, line numbers, ...)
47− pub output_components: OutputComponents,
48+ pub style_components: StyleComponents,
48
49
49 /// Text wrapping mode
50 /// Text wrapping mode
50 pub output_wrap: OutputWrap,
51 pub output_wrap: OutputWrap,
src/controller.rs+2−2
@@ -83,7 +83,7 @@ impl<'b> Controller<'b> {
83 writer: &mut dyn Write,
83 writer: &mut dyn Write,
84 input_file: InputFile<'a>,
84 input_file: InputFile<'a>,
85 ) -> Result<()> {
85 ) -> Result<()> {
86− if !reader.first_line.is_empty() || self.config.output_components.header() {
86+ if !reader.first_line.is_empty() || self.config.style_components.header() {
87 printer.print_header(writer, input_file)?;
87 printer.print_header(writer, input_file)?;
88 }
88 }
89
89
@@ -118,7 +118,7 @@ impl<'b> Controller<'b> {
118 }
118 }
119
119
120 RangeCheckResult::InRange => {
120 RangeCheckResult::InRange => {
121− if self.config.output_components.snip() {
121+ if self.config.style_components.snip() {
122 if first_range {
122 if first_range {
123 first_range = false;
123 first_range = false;
124 mid_range = true;
124 mid_range = true;
src/lib.rs+1
@@ -27,3 +27,4 @@ mod printer;
27pub mod style;
27pub mod style;
28pub mod syntax_mapping;
28pub mod syntax_mapping;
29mod terminal;
29mod terminal;
30+pub mod wrap;
src/printer.rs+11−11
@@ -30,8 +30,8 @@ use crate::errors::*;
30use crate::inputfile::{InputFile, InputFileReader};
30use crate::inputfile::{InputFile, InputFileReader};
31use crate::line_range::RangeCheckResult;
31use crate::line_range::RangeCheckResult;
32use crate::preprocessor::{expand_tabs, replace_nonprintable};
32use crate::preprocessor::{expand_tabs, replace_nonprintable};
33−use crate::style::OutputWrap;
34use crate::terminal::{as_terminal_escaped, to_ansi_color};
33use crate::terminal::{as_terminal_escaped, to_ansi_color};
34+use crate::wrap::OutputWrap;
35
35
36pub trait Printer {
36pub trait Printer {
37 fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
37 fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
@@ -116,11 +116,11 @@ impl<'a> InteractivePrinter<'a> {
116 // Create decorations.
116 // Create decorations.
117 let mut decorations: Vec<Box<dyn Decoration>> = Vec::new();
117 let mut decorations: Vec<Box<dyn Decoration>> = Vec::new();
118
118
119− if config.output_components.numbers() {
119+ if config.style_components.numbers() {
120 decorations.push(Box::new(LineNumberDecoration::new(&colors)));
120 decorations.push(Box::new(LineNumberDecoration::new(&colors)));
121 }
121 }
122
122
123− if config.output_components.changes() {
123+ if config.style_components.changes() {
124 decorations.push(Box::new(LineChangesDecoration::new(&colors)));
124 decorations.push(Box::new(LineChangesDecoration::new(&colors)));
125 }
125 }
126
126
@@ -130,7 +130,7 @@ impl<'a> InteractivePrinter<'a> {
130 // The grid border decoration isn't added until after the panel_width calculation, since the
130 // The grid border decoration isn't added until after the panel_width calculation, since the
131 // print_horizontal_line, print_header, and print_footer functions all assume the panel
131 // print_horizontal_line, print_header, and print_footer functions all assume the panel
132 // width is without the grid border.
132 // width is without the grid border.
133− if config.output_components.grid() && !decorations.is_empty() {
133+ if config.style_components.grid() && !decorations.is_empty() {
134 decorations.push(Box::new(GridBorderDecoration::new(&colors)));
134 decorations.push(Box::new(GridBorderDecoration::new(&colors)));
135 }
135 }
136
136
@@ -152,7 +152,7 @@ impl<'a> InteractivePrinter<'a> {
152 None
152 None
153 } else {
153 } else {
154 // Get the Git modifications
154 // Get the Git modifications
155− line_changes = if config.output_components.changes() {
155+ line_changes = if config.style_components.changes() {
156 match file {
156 match file {
157 InputFile::Ordinary(filename) => get_git_diff(filename),
157 InputFile::Ordinary(filename) => get_git_diff(filename),
158 _ => None,
158 _ => None,
@@ -206,7 +206,7 @@ impl<'a> InteractivePrinter<'a> {
206 text_truncated,
206 text_truncated,
207 " ".repeat(self.panel_width - 1 - text_truncated.len())
207 " ".repeat(self.panel_width - 1 - text_truncated.len())
208 );
208 );
209− if self.config.output_components.grid() {
209+ if self.config.style_components.grid() {
210 format!("{} │ ", text_filled)
210 format!("{} │ ", text_filled)
211 } else {
211 } else {
212 format!("{}", text_filled)
212 format!("{}", text_filled)
@@ -225,7 +225,7 @@ impl<'a> InteractivePrinter<'a> {
225
225
226impl<'a> Printer for InteractivePrinter<'a> {
226impl<'a> Printer for InteractivePrinter<'a> {
227 fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()> {
227 fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()> {
228− if !self.config.output_components.header() {
228+ if !self.config.style_components.header() {
229 if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
229 if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
230 let input = match file {
230 let input = match file {
231 InputFile::Ordinary(filename) => {
231 InputFile::Ordinary(filename) => {
@@ -243,14 +243,14 @@ impl<'a> Printer for InteractivePrinter<'a> {
243 input
243 input
244 )?;
244 )?;
245 } else {
245 } else {
246− if self.config.output_components.grid() {
246+ if self.config.style_components.grid() {
247 self.print_horizontal_line(handle, '┬')?;
247 self.print_horizontal_line(handle, '┬')?;
248 }
248 }
249 }
249 }
250 return Ok(());
250 return Ok(());
251 }
251 }
252
252
253− if self.config.output_components.grid() {
253+ if self.config.style_components.grid() {
254 self.print_horizontal_line(handle, '┬')?;
254 self.print_horizontal_line(handle, '┬')?;
255
255
256 write!(
256 write!(
@@ -286,7 +286,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
286 mode
286 mode
287 )?;
287 )?;
288
288
289− if self.config.output_components.grid() {
289+ if self.config.style_components.grid() {
290 if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
290 if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
291 self.print_horizontal_line(handle, '┼')?;
291 self.print_horizontal_line(handle, '┼')?;
292 } else {
292 } else {
@@ -298,7 +298,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
298 }
298 }
299
299
300 fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()> {
300 fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()> {
301− if self.config.output_components.grid()
301+ if self.config.style_components.grid()
302 && (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
302 && (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
303 {
303 {
304 self.print_horizontal_line(handle, '┴')
304 self.print_horizontal_line(handle, '┴')
src/style.rs+37−49
@@ -4,7 +4,7 @@ use std::str::FromStr;
4use crate::errors::*;
4use crate::errors::*;
5
5
6#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
6#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
7−pub enum OutputComponent {
7+pub enum StyleComponent {
8 Auto,
8 Auto,
9 Changes,
9 Changes,
10 Grid,
10 Grid,
@@ -15,92 +15,80 @@ pub enum OutputComponent {
15 Plain,
15 Plain,
16}
16}
17
17
18−#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
18+impl StyleComponent {
19−pub enum OutputWrap {
20− Character,
21− None,
22−}
23−
24−impl Default for OutputWrap {
25− fn default() -> Self {
26− OutputWrap::None
27− }
28−}
29−
30−impl OutputComponent {
31− pub fn components(self, interactive_terminal: bool) -> &'static [OutputComponent] {
19+ pub fn components(self, interactive_terminal: bool) -> &'static [StyleComponent] {
32 match self {
20 match self {
33− OutputComponent::Auto => {
21+ StyleComponent::Auto => {
34 if interactive_terminal {
22 if interactive_terminal {
35− OutputComponent::Full.components(interactive_terminal)
23+ StyleComponent::Full.components(interactive_terminal)
36 } else {
24 } else {
37− OutputComponent::Plain.components(interactive_terminal)
25+ StyleComponent::Plain.components(interactive_terminal)
38 }
26 }
39 }
27 }
40− OutputComponent::Changes => &[OutputComponent::Changes],
28+ StyleComponent::Changes => &[StyleComponent::Changes],
41− OutputComponent::Grid => &[OutputComponent::Grid],
29+ StyleComponent::Grid => &[StyleComponent::Grid],
42− OutputComponent::Header => &[OutputComponent::Header],
30+ StyleComponent::Header => &[StyleComponent::Header],
43− OutputComponent::Numbers => &[OutputComponent::Numbers],
31+ StyleComponent::Numbers => &[StyleComponent::Numbers],
44− OutputComponent::Snip => &[OutputComponent::Snip],
32+ StyleComponent::Snip => &[StyleComponent::Snip],
45− OutputComponent::Full => &[
33+ StyleComponent::Full => &[
46− OutputComponent::Changes,
34+ StyleComponent::Changes,
47− OutputComponent::Grid,
35+ StyleComponent::Grid,
48− OutputComponent::Header,
36+ StyleComponent::Header,
49− OutputComponent::Numbers,
37+ StyleComponent::Numbers,
50− OutputComponent::Snip,
38+ StyleComponent::Snip,
51 ],
39 ],
52− OutputComponent::Plain => &[],
40+ StyleComponent::Plain => &[],
53 }
41 }
54 }
42 }
55}
43}
56
44
57−impl FromStr for OutputComponent {
45+impl FromStr for StyleComponent {
58 type Err = Error;
46 type Err = Error;
59
47
60 fn from_str(s: &str) -> Result<Self> {
48 fn from_str(s: &str) -> Result<Self> {
61 match s {
49 match s {
62− "auto" => Ok(OutputComponent::Auto),
50+ "auto" => Ok(StyleComponent::Auto),
63− "changes" => Ok(OutputComponent::Changes),
51+ "changes" => Ok(StyleComponent::Changes),
64− "grid" => Ok(OutputComponent::Grid),
52+ "grid" => Ok(StyleComponent::Grid),
65− "header" => Ok(OutputComponent::Header),
53+ "header" => Ok(StyleComponent::Header),
66− "numbers" => Ok(OutputComponent::Numbers),
54+ "numbers" => Ok(StyleComponent::Numbers),
67− "snip" => Ok(OutputComponent::Snip),
55+ "snip" => Ok(StyleComponent::Snip),
68− "full" => Ok(OutputComponent::Full),
56+ "full" => Ok(StyleComponent::Full),
69− "plain" => Ok(OutputComponent::Plain),
57+ "plain" => Ok(StyleComponent::Plain),
70 _ => Err(format!("Unknown style '{}'", s).into()),
58 _ => Err(format!("Unknown style '{}'", s).into()),
71 }
59 }
72 }
60 }
73}
61}
74
62
75#[derive(Debug, Clone, Default)]
63#[derive(Debug, Clone, Default)]
76−pub struct OutputComponents(pub HashSet<OutputComponent>);
64+pub struct StyleComponents(pub HashSet<StyleComponent>);
77
65
78−impl OutputComponents {
66+impl StyleComponents {
79− pub fn new(components: &[OutputComponent]) -> OutputComponents {
67+ pub fn new(components: &[StyleComponent]) -> StyleComponents {
80− OutputComponents(components.iter().cloned().collect())
68+ StyleComponents(components.iter().cloned().collect())
81 }
69 }
82
70
83 pub fn changes(&self) -> bool {
71 pub fn changes(&self) -> bool {
84− self.0.contains(&OutputComponent::Changes)
72+ self.0.contains(&StyleComponent::Changes)
85 }
73 }
86
74
87 pub fn grid(&self) -> bool {
75 pub fn grid(&self) -> bool {
88− self.0.contains(&OutputComponent::Grid)
76+ self.0.contains(&StyleComponent::Grid)
89 }
77 }
90
78
91 pub fn header(&self) -> bool {
79 pub fn header(&self) -> bool {
92− self.0.contains(&OutputComponent::Header)
80+ self.0.contains(&StyleComponent::Header)
93 }
81 }
94
82
95 pub fn numbers(&self) -> bool {
83 pub fn numbers(&self) -> bool {
96− self.0.contains(&OutputComponent::Numbers)
84+ self.0.contains(&StyleComponent::Numbers)
97 }
85 }
98
86
99 pub fn snip(&self) -> bool {
87 pub fn snip(&self) -> bool {
100− self.0.contains(&OutputComponent::Snip)
88+ self.0.contains(&StyleComponent::Snip)
101 }
89 }
102
90
103 pub fn plain(&self) -> bool {
91 pub fn plain(&self) -> bool {
104− self.0.iter().all(|c| c == &OutputComponent::Plain)
92+ self.0.iter().all(|c| c == &StyleComponent::Plain)
105 }
93 }
106}
94}
src/wrap.rsnew file+11
@@ -0,0 +1,11 @@
1+#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
2+pub enum OutputWrap {
3+ Character,
4+ None,
5+}
6+
7+impl Default for OutputWrap {
8+ fn default() -> Self {
9+ OutputWrap::None
10+ }
11+}