on 2eee685 help sign in
bat/src/decorations.rs
154 lines 4.2 kB history raw
1use ansi_term::Style;
2use diff::LineChange;
3use printer::Printer;
4use Colors;
6#[derive(Clone)]
7pub struct DecorationText {
8 pub width: usize,
9 pub text: String,
12pub trait Decoration {
13 fn generate(&self, line_number: usize, continuation: bool, printer: &Printer)
14 -> DecorationText;
15 fn width(&self) -> usize;
18// Line number decoration.
19pub struct LineNumberDecoration {
20 color: Style,
21 cached_wrap: DecorationText,
22 cached_wrap_invalid_at: usize,
25impl LineNumberDecoration {
26 pub fn new(colors: &Colors) -> Self {
27 LineNumberDecoration {
28 color: colors.line_number,
29 cached_wrap_invalid_at: 10000,
30 cached_wrap: DecorationText {
31 text: colors.line_number.paint(" ".repeat(4)).to_string(),
32 width: 4,
33 },
34 }
35 }
38impl Decoration for LineNumberDecoration {
39 fn generate(
40 &self,
41 line_number: usize,
42 continuation: bool,
43 _printer: &Printer,
44 ) -> DecorationText {
45 if continuation {
46 if line_number > self.cached_wrap_invalid_at {
47 let new_width = self.cached_wrap.width + 1;
48 return DecorationText {
49 text: self.color.paint(" ".repeat(new_width)).to_string(),
50 width: new_width,
51 };
52 }
54 self.cached_wrap.clone()
55 } else {
56 let plain: String = format!("{:4}", line_number);
57 DecorationText {
58 width: plain.len(),
59 text: self.color.paint(plain).to_string(),
60 }
61 }
62 }
64 fn width(&self) -> usize {
65 4
66 }
69// Line changes decoration.
70pub struct LineChangesDecoration {
71 cached_none: DecorationText,
72 cached_added: DecorationText,
73 cached_removed_above: DecorationText,
74 cached_removed_below: DecorationText,
75 cached_modified: DecorationText,
78impl LineChangesDecoration {
79 #[inline]
80 fn generate_cached(style: Style, text: &str) -> DecorationText {
81 DecorationText {
82 text: style.paint(text).to_string(),
83 width: text.chars().count(),
84 }
85 }
87 pub fn new(colors: &Colors) -> Self {
88 LineChangesDecoration {
89 cached_none: Self::generate_cached(Style::default(), " "),
90 cached_added: Self::generate_cached(colors.git_added, "+"),
91 cached_removed_above: Self::generate_cached(colors.git_removed, "‾"),
92 cached_removed_below: Self::generate_cached(colors.git_removed, "_"),
93 cached_modified: Self::generate_cached(colors.git_modified, "~"),
94 }
95 }
98impl Decoration for LineChangesDecoration {
99 fn generate(
100 &self,
101 line_number: usize,
102 continuation: bool,
103 printer: &Printer,
104 ) -> DecorationText {
105 if !continuation {
106 if let Some(ref changes) = printer.line_changes {
107 return match changes.get(&(line_number as u32)) {
108 Some(&LineChange::Added) => self.cached_added.clone(),
109 Some(&LineChange::RemovedAbove) => self.cached_removed_above.clone(),
110 Some(&LineChange::RemovedBelow) => self.cached_removed_below.clone(),
111 Some(&LineChange::Modified) => self.cached_modified.clone(),
112 _ => self.cached_none.clone(),
113 };
114 }
115 }
117 self.cached_none.clone()
118 }
120 fn width(&self) -> usize {
121 self.cached_none.width
122 }
125// Grid border decoration.
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: &Printer,
147 ) -> DecorationText {
148 self.cached.clone()
149 }
151 fn width(&self) -> usize {
152 self.cached.width
153 }