1 // Code for creating styled buffers
3 use crate::snippet::{Style, StyledString};
6 pub struct StyledBuffer {
8 styles: Vec<Vec<Style>>,
12 pub fn new() -> StyledBuffer {
13 StyledBuffer { text: vec![], styles: vec![] }
16 pub fn render(&self) -> Vec<Vec<StyledString>> {
17 // Tabs are assumed to have been replaced by spaces in calling code.
18 debug_assert!(self.text.iter().all(|r| !r.contains(&'\t')));
20 let mut output: Vec<Vec<StyledString>> = vec![];
21 let mut styled_vec: Vec<StyledString> = vec![];
23 for (row, row_style) in self.text.iter().zip(&self.styles) {
24 let mut current_style = Style::NoStyle;
25 let mut current_text = String::new();
27 for (&c, &s) in row.iter().zip(row_style) {
28 if s != current_style {
29 if !current_text.is_empty() {
30 styled_vec.push(StyledString { text: current_text, style: current_style });
33 current_text = String::new();
37 if !current_text.is_empty() {
38 styled_vec.push(StyledString { text: current_text, style: current_style });
41 // We're done with the row, push and keep going
42 output.push(styled_vec);
50 fn ensure_lines(&mut self, line: usize) {
51 while line >= self.text.len() {
52 self.text.push(vec![]);
53 self.styles.push(vec![]);
57 pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
58 self.ensure_lines(line);
59 if col < self.text[line].len() {
60 self.text[line][col] = chr;
61 self.styles[line][col] = style;
63 let mut i = self.text[line].len();
65 self.text[line].push(' ');
66 self.styles[line].push(Style::NoStyle);
69 self.text[line].push(chr);
70 self.styles[line].push(style);
74 pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
76 for c in string.chars() {
77 self.putc(line, n, c, style);
82 pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
83 self.ensure_lines(line);
84 let string_len = string.chars().count();
86 // Push the old content over to make room for new content
87 for _ in 0..string_len {
88 self.styles[line].insert(0, Style::NoStyle);
89 self.text[line].insert(0, ' ');
92 self.puts(line, 0, string, style);
95 pub fn append(&mut self, line: usize, string: &str, style: Style) {
96 if line >= self.text.len() {
97 self.puts(line, 0, string, style);
99 let col = self.text[line].len();
100 self.puts(line, col, string, style);
104 pub fn num_lines(&self) -> usize {
108 pub fn set_style_range(
116 for col in col_start..col_end {
117 self.set_style(line, col, style, overwrite);
121 pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
122 if let Some(ref mut line) = self.styles.get_mut(line) {
123 if let Some(s) = line.get_mut(col) {
124 if *s == Style::NoStyle || *s == Style::Quotation || overwrite {