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