1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. |
4 | // |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
8 | // option. This file may not be copied, modified, or distributed |
9 | // except according to those terms. |
10 | |
11 | // Code for creating styled buffers |
12 | |
13 | use snippet::{Style, StyledString}; |
14 | |
15 | #[derive (Debug)] |
16 | pub struct StyledBuffer { |
17 | text: Vec<Vec<char>>, |
18 | styles: Vec<Vec<Style>>, |
19 | } |
20 | |
21 | impl StyledBuffer { |
22 | pub fn new() -> StyledBuffer { |
23 | StyledBuffer { |
24 | text: vec![], |
25 | styles: vec![], |
26 | } |
27 | } |
28 | |
29 | pub fn copy_tabs(&mut self, row: usize) { |
30 | if row < self.text.len() { |
31 | for i in row + 1..self.text.len() { |
32 | for j in 0..self.text[i].len() { |
33 | if self.text[row].len() > j && self.text[row][j] == ' \t' && |
34 | self.text[i][j] == ' ' { |
35 | self.text[i][j] = ' \t' ; |
36 | } |
37 | } |
38 | } |
39 | } |
40 | } |
41 | |
42 | pub fn render(&mut self) -> Vec<Vec<StyledString>> { |
43 | let mut output: Vec<Vec<StyledString>> = vec![]; |
44 | let mut styled_vec: Vec<StyledString> = vec![]; |
45 | |
46 | // before we render, do a little patch-up work to support tabs |
47 | self.copy_tabs(3); |
48 | |
49 | for (row, row_style) in self.text.iter().zip(&self.styles) { |
50 | let mut current_style = Style::NoStyle; |
51 | let mut current_text = String::new(); |
52 | |
53 | for (&c, &s) in row.iter().zip(row_style) { |
54 | if s != current_style { |
55 | if !current_text.is_empty() { |
56 | styled_vec.push(StyledString { |
57 | text: current_text, |
58 | style: current_style, |
59 | }); |
60 | } |
61 | current_style = s; |
62 | current_text = String::new(); |
63 | } |
64 | current_text.push(c); |
65 | } |
66 | if !current_text.is_empty() { |
67 | styled_vec.push(StyledString { |
68 | text: current_text, |
69 | style: current_style, |
70 | }); |
71 | } |
72 | |
73 | // We're done with the row, push and keep going |
74 | output.push(styled_vec); |
75 | |
76 | styled_vec = vec![]; |
77 | } |
78 | |
79 | output |
80 | } |
81 | |
82 | fn ensure_lines(&mut self, line: usize) { |
83 | while line >= self.text.len() { |
84 | self.text.push(vec![]); |
85 | self.styles.push(vec![]); |
86 | } |
87 | } |
88 | |
89 | pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { |
90 | self.ensure_lines(line); |
91 | if col < self.text[line].len() { |
92 | self.text[line][col] = chr; |
93 | self.styles[line][col] = style; |
94 | } else { |
95 | let mut i = self.text[line].len(); |
96 | while i < col { |
97 | self.text[line].push(' ' ); |
98 | self.styles[line].push(Style::NoStyle); |
99 | i += 1; |
100 | } |
101 | self.text[line].push(chr); |
102 | self.styles[line].push(style); |
103 | } |
104 | } |
105 | |
106 | pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) { |
107 | let mut n = col; |
108 | for c in string.chars() { |
109 | self.putc(line, n, c, style); |
110 | n += 1; |
111 | } |
112 | } |
113 | |
114 | pub fn prepend(&mut self, line: usize, string: &str, style: Style) { |
115 | self.ensure_lines(line); |
116 | let string_len = string.len(); |
117 | |
118 | // Push the old content over to make room for new content |
119 | for _ in 0..string_len { |
120 | self.styles[line].insert(0, Style::NoStyle); |
121 | self.text[line].insert(0, ' ' ); |
122 | } |
123 | |
124 | self.puts(line, 0, string, style); |
125 | } |
126 | |
127 | pub fn append(&mut self, line: usize, string: &str, style: Style) { |
128 | if line >= self.text.len() { |
129 | self.puts(line, 0, string, style); |
130 | } else { |
131 | let col = self.text[line].len(); |
132 | self.puts(line, col, string, style); |
133 | } |
134 | } |
135 | |
136 | pub fn num_lines(&self) -> usize { |
137 | self.text.len() |
138 | } |
139 | } |
140 | |