on 5f6e310 help sign in
bat/src/decorations.rs
158 lines 4.3 kB history raw
1#[cfg(feature = "git")]
2use crate::diff::LineChange;
3use crate::printer::{Colors, InteractivePrinter};
4use ansi_term::Style;
6#[derive(Debug, Clone)]
7pub struct DecorationText {
8 pub width: usize,
9 pub text: String,
12pub trait Decoration {
13 fn generate(
14 &self,
15 line_number: usize,
16 continuation: bool,
17 printer: &InteractivePrinter,
18 ) -> DecorationText;
19 fn width(&self) -> usize;
22pub struct LineNumberDecoration {
23 color: Style,
24 cached_wrap: DecorationText,
25 cached_wrap_invalid_at: usize,
28impl LineNumberDecoration {
29 pub fn new(colors: &Colors) -> Self {
30 LineNumberDecoration {
31 color: colors.line_number,
32 cached_wrap_invalid_at: 10000,
33 cached_wrap: DecorationText {
34 text: colors.line_number.paint(" ".repeat(4)).to_string(),
35 width: 4,
36 },
37 }
38 }
41impl Decoration for LineNumberDecoration {
42 fn generate(
43 &self,
44 line_number: usize,
45 continuation: bool,
46 _printer: &InteractivePrinter,
47 ) -> DecorationText {
48 if continuation {
49 if line_number > self.cached_wrap_invalid_at {
50 let new_width = self.cached_wrap.width + 1;
51 return DecorationText {
52 text: self.color.paint(" ".repeat(new_width)).to_string(),
53 width: new_width,
54 };
55 }
57 self.cached_wrap.clone()
58 } else {
59 let plain: String = format!("{:4}", line_number);
60 DecorationText {
61 width: plain.len(),
62 text: self.color.paint(plain).to_string(),
63 }
64 }
65 }
67 fn width(&self) -> usize {
68 4
69 }
72#[cfg(feature = "git")]
73pub struct LineChangesDecoration {
74 cached_none: DecorationText,
75 cached_added: DecorationText,
76 cached_removed_above: DecorationText,
77 cached_removed_below: DecorationText,
78 cached_modified: DecorationText,
81#[cfg(feature = "git")]
82impl LineChangesDecoration {
83 #[inline]
84 fn generate_cached(style: Style, text: &str) -> DecorationText {
85 DecorationText {
86 text: style.paint(text).to_string(),
87 width: text.chars().count(),
88 }
89 }
91 pub fn new(colors: &Colors) -> Self {
92 LineChangesDecoration {
93 cached_none: Self::generate_cached(Style::default(), " "),
94 cached_added: Self::generate_cached(colors.git_added, "+"),
95 cached_removed_above: Self::generate_cached(colors.git_removed, "‾"),
96 cached_removed_below: Self::generate_cached(colors.git_removed, "_"),
97 cached_modified: Self::generate_cached(colors.git_modified, "~"),
98 }
99 }
102#[cfg(feature = "git")]
103impl Decoration for LineChangesDecoration {
104 fn generate(
105 &self,
106 line_number: usize,
107 continuation: bool,
108 printer: &InteractivePrinter,
109 ) -> DecorationText {
110 if !continuation {
111 if let Some(ref changes) = printer.line_changes {
112 return match changes.get(&(line_number as u32)) {
113 Some(&LineChange::Added) => self.cached_added.clone(),
114 Some(&LineChange::RemovedAbove) => self.cached_removed_above.clone(),
115 Some(&LineChange::RemovedBelow) => self.cached_removed_below.clone(),
116 Some(&LineChange::Modified) => self.cached_modified.clone(),
117 _ => self.cached_none.clone(),
118 };
119 }
120 }
122 self.cached_none.clone()
123 }
125 fn width(&self) -> usize {
126 self.cached_none.width
127 }
130pub struct GridBorderDecoration {
131 cached: DecorationText,
134impl GridBorderDecoration {
135 pub fn new(colors: &Colors) -> Self {
136 GridBorderDecoration {
137 cached: DecorationText {
138 text: colors.grid.paint("│").to_string(),
139 width: 1,
140 },
141 }
142 }
145impl Decoration for GridBorderDecoration {
146 fn generate(
147 &self,
148 _line_number: usize,
149 _continuation: bool,
150 _printer: &InteractivePrinter,
151 ) -> DecorationText {
152 self.cached.clone()
153 }
155 fn width(&self) -> usize {
156 self.cached.width
157 }