1
1
// Code for creating styled buffers
2
2
3
3
use crate :: snippet:: { Style , StyledString } ;
4
- use std:: iter;
5
4
6
5
#[ derive( Debug ) ]
7
6
pub struct StyledBuffer {
8
- text : Vec < Vec < char > > ,
9
- styles : Vec < Vec < Style > > ,
7
+ text : Vec < Vec < StyledChar > > ,
8
+ }
9
+
10
+ #[ derive( Debug ) ]
11
+ struct StyledChar {
12
+ chr : char ,
13
+ style : Style ,
14
+ }
15
+
16
+ impl StyledChar {
17
+ fn new ( chr : char , style : Style ) -> Self {
18
+ StyledChar { chr, style }
19
+ }
10
20
}
11
21
12
22
impl StyledBuffer {
13
23
pub fn new ( ) -> StyledBuffer {
14
- StyledBuffer { text : vec ! [ ] , styles : vec ! [ ] }
24
+ StyledBuffer { text : vec ! [ ] }
15
25
}
16
26
17
27
pub fn render ( & self ) -> Vec < Vec < StyledString > > {
18
28
// Tabs are assumed to have been replaced by spaces in calling code.
19
- debug_assert ! ( self . text. iter( ) . all( |r| !r. contains ( & '\t' ) ) ) ;
29
+ debug_assert ! ( self . text. iter( ) . all( |r| !r. iter ( ) . any ( |sc| sc . chr == '\t' ) ) ) ;
20
30
21
31
let mut output: Vec < Vec < StyledString > > = vec ! [ ] ;
22
32
let mut styled_vec: Vec < StyledString > = vec ! [ ] ;
23
33
24
- for ( row , row_style ) in iter :: zip ( & self . text , & self . styles ) {
34
+ for styled_row in & self . text {
25
35
let mut current_style = Style :: NoStyle ;
26
36
let mut current_text = String :: new ( ) ;
27
37
28
- for ( & c , & s ) in iter :: zip ( row , row_style ) {
29
- if s != current_style {
38
+ for sc in styled_row {
39
+ if sc . style != current_style {
30
40
if !current_text. is_empty ( ) {
31
41
styled_vec. push ( StyledString { text : current_text, style : current_style } ) ;
32
42
}
33
- current_style = s ;
43
+ current_style = sc . style ;
34
44
current_text = String :: new ( ) ;
35
45
}
36
- current_text. push ( c ) ;
46
+ current_text. push ( sc . chr ) ;
37
47
}
38
48
if !current_text. is_empty ( ) {
39
49
styled_vec. push ( StyledString { text : current_text, style : current_style } ) ;
@@ -51,24 +61,20 @@ impl StyledBuffer {
51
61
fn ensure_lines ( & mut self , line : usize ) {
52
62
while line >= self . text . len ( ) {
53
63
self . text . push ( vec ! [ ] ) ;
54
- self . styles . push ( vec ! [ ] ) ;
55
64
}
56
65
}
57
66
58
67
pub fn putc ( & mut self , line : usize , col : usize , chr : char , style : Style ) {
59
68
self . ensure_lines ( line) ;
60
69
if col < self . text [ line] . len ( ) {
61
- self . text [ line] [ col] = chr;
62
- self . styles [ line] [ col] = style;
70
+ self . text [ line] [ col] = StyledChar :: new ( chr, style) ;
63
71
} else {
64
72
let mut i = self . text [ line] . len ( ) ;
65
73
while i < col {
66
- self . text [ line] . push ( ' ' ) ;
67
- self . styles [ line] . push ( Style :: NoStyle ) ;
74
+ self . text [ line] . push ( StyledChar :: new ( ' ' , Style :: NoStyle ) ) ;
68
75
i += 1 ;
69
76
}
70
- self . text [ line] . push ( chr) ;
71
- self . styles [ line] . push ( style) ;
77
+ self . text [ line] . push ( StyledChar :: new ( chr, style) ) ;
72
78
}
73
79
}
74
80
@@ -86,8 +92,7 @@ impl StyledBuffer {
86
92
87
93
// Push the old content over to make room for new content
88
94
for _ in 0 ..string_len {
89
- self . styles [ line] . insert ( 0 , Style :: NoStyle ) ;
90
- self . text [ line] . insert ( 0 , ' ' ) ;
95
+ self . text [ line] . insert ( 0 , StyledChar :: new ( ' ' , Style :: NoStyle ) ) ;
91
96
}
92
97
93
98
self . puts ( line, 0 , string, style) ;
@@ -120,8 +125,8 @@ impl StyledBuffer {
120
125
}
121
126
122
127
pub fn set_style ( & mut self , line : usize , col : usize , style : Style , overwrite : bool ) {
123
- if let Some ( ref mut line) = self . styles . get_mut ( line) {
124
- if let Some ( s ) = line. get_mut ( col) {
128
+ if let Some ( ref mut line) = self . text . get_mut ( line) {
129
+ if let Some ( StyledChar { style : s , .. } ) = line. get_mut ( col) {
125
130
if * s == Style :: NoStyle || * s == Style :: Quotation || overwrite {
126
131
* s = style;
127
132
}
0 commit comments