11use crate :: ansi:: Color ;
22use std:: cell:: RefCell ;
33use std:: collections:: HashMap ;
4+ use std:: collections:: VecDeque ;
45
56pub struct Renderer {
67 pub name : String ,
@@ -11,7 +12,7 @@ pub struct Renderer {
1112 pub foreground : Color ,
1213 pub background : Color ,
1314 current_row : usize ,
14- rows : Vec < Row > ,
15+ rows : VecDeque < Row > ,
1516 styles : Styles ,
1617}
1718
@@ -112,7 +113,7 @@ impl Renderer {
112113 foreground : Color :: bright_white ( ) ,
113114 background : Color :: black ( ) ,
114115 current_row : 0 ,
115- rows : vec ! [ Row :: new( ) ] ,
116+ rows : vec ! [ Row :: new( ) ] . into ( ) ,
116117 styles : Styles :: default ( ) ,
117118 }
118119 }
@@ -152,7 +153,7 @@ impl Renderer {
152153 pub fn linefeed ( & mut self ) {
153154 self . current_row += 1 ;
154155 if self . current_row == self . rows . len ( ) {
155- self . rows . push ( Row :: new ( ) ) ;
156+ self . rows . push_back ( Row :: new ( ) ) ;
156157 }
157158 }
158159
@@ -185,7 +186,7 @@ impl Renderer {
185186 pub fn handle_move ( & mut self , row : u16 , col : u16 ) {
186187 self . current_row = row as usize ;
187188 while self . current_row >= self . rows . len ( ) {
188- self . rows . push ( Row :: new ( ) ) ;
189+ self . rows . push_back ( Row :: new ( ) ) ;
189190 }
190191 self . set_column ( col) ;
191192 }
@@ -197,7 +198,7 @@ impl Renderer {
197198 pub fn move_down_by ( & mut self , cells : u16 ) {
198199 self . current_row += cells as usize ;
199200 while self . current_row >= self . rows . len ( ) {
200- self . rows . push ( Row :: new ( ) ) ;
201+ self . rows . push_back ( Row :: new ( ) ) ;
201202 }
202203 }
203204
@@ -219,7 +220,18 @@ impl Renderer {
219220 let _ = & row. cells [ ..row. position ] ;
220221 }
221222
222- pub fn emit_html < W : std:: io:: Write > ( & self , mut out : W ) -> std:: io:: Result < ( ) > {
223+ pub fn pop_completed_row ( & mut self ) -> Option < Vec < u8 > > {
224+ if self . rows . len ( ) > 64 {
225+ self . remove_oldest_row ( )
226+ } else {
227+ None
228+ }
229+ }
230+
231+ pub fn remove_oldest_row ( & mut self ) -> Option < Vec < u8 > > {
232+ use std:: io:: Write ;
233+ let mut out = Vec :: new ( ) ;
234+
223235 let mut prev = Cell {
224236 text : ' ' ,
225237 foreground : Color :: bright_white ( ) ,
@@ -230,32 +242,36 @@ impl Renderer {
230242 dim : false ,
231243 } ;
232244
233- out. write_all ( b"<span>" ) ?;
234-
235- for row in & self . rows [ ..self . current_row ] {
236- let row = & * row;
237- for cell in & row. cells {
238- // Terminal applications will often reset the style right after some formatted text
239- // then write some whitespace then set it to something again.
240- // So we only apply style changes if the cell is nonempty. This is a ~50% savings
241- // in emitted HTML.
242- if cell. text != ' ' {
243- if cell. bold != prev. bold || cell. foreground != prev. foreground {
244- self . styles . with ( cell. foreground , cell. bold , |class| {
245+ out. extend ( b"<span>" ) ;
246+
247+ let row = self . rows . pop_front ( ) ?;
248+ self . current_row = self . current_row . saturating_sub ( 1 ) ;
249+
250+ for cell in & row. cells {
251+ // Terminal applications will often reset the style right after some formatted text
252+ // then write some whitespace then set it to something again.
253+ // So we only apply style changes if the cell is nonempty. This is a ~50% savings
254+ // in emitted HTML.
255+ if cell. text != ' ' {
256+ if cell. bold != prev. bold || cell. foreground != prev. foreground {
257+ self . styles
258+ . with ( cell. foreground , cell. bold , |class| {
245259 write ! ( out, "</span><span class='{}'>" , class)
246- } ) ?;
247- }
248- prev = cell. clone ( ) ;
249- }
250- match cell. text {
251- '<' => out. write_all ( b"<" ) ?,
252- '>' => out. write_all ( b">" ) ?,
253- c => write ! ( out, "{}" , c) ?,
260+ } )
261+ . unwrap ( ) ;
254262 }
263+ prev = cell. clone ( ) ;
264+ }
265+ match cell. text {
266+ '<' => out. extend ( b"<" ) ,
267+ '>' => out. extend ( b">" ) ,
268+ c => write ! ( out, "{}" , c) . unwrap ( ) ,
255269 }
256- out. write_all ( & [ b'\n' ] ) ?;
257270 }
258- out. write_all ( b"</span>" )
271+ out. extend ( & [ b'\n' ] ) ;
272+ out. extend ( b"</span>" ) ;
273+
274+ Some ( out)
259275 }
260276
261277 pub fn emit_css < W : std:: io:: Write > ( & self , mut out : W ) -> std:: io:: Result < ( ) > {
@@ -271,12 +287,4 @@ impl Renderer {
271287
272288 Ok ( ( ) )
273289 }
274-
275- /*
276- pub fn clear(&mut self) {
277- self.rows.clear();
278- self.rows.push(Row::new());
279- self.current_row = 0;
280- }
281- */
282290}
0 commit comments