@@ -32,8 +32,6 @@ mod tests;
32
32
mod storage;
33
33
use self :: storage:: Storage ;
34
34
35
- const MIN_INIT_SIZE : usize = 1_000 ;
36
-
37
35
/// Bidirection iterator
38
36
pub trait BidirectionalIterator : Iterator {
39
37
fn prev ( & mut self ) -> Option < Self :: Item > ;
@@ -62,7 +60,6 @@ impl<T: PartialEq> ::std::cmp::PartialEq for Grid<T> {
62
60
&& self . cols . eq ( & other. cols )
63
61
&& self . lines . eq ( & other. lines )
64
62
&& self . display_offset . eq ( & other. display_offset )
65
- && self . scroll_limit . eq ( & other. scroll_limit )
66
63
&& self . selection . eq ( & other. selection )
67
64
}
68
65
}
@@ -86,11 +83,11 @@ pub trait GridCell {
86
83
/// │ │
87
84
/// │ UNINITIALIZED │
88
85
/// │ │
89
- /// ├─────────────────────────┤ <-- raw.len()
86
+ /// ├─────────────────────────┤ <-- self. raw.inner .len()
90
87
/// │ │
91
88
/// │ RESIZE BUFFER │
92
89
/// │ │
93
- /// ├─────────────────────────┤ <-- scroll_limit + lines
90
+ /// ├─────────────────────────┤ <-- self.history_size() + lines
94
91
/// │ │
95
92
/// │ SCROLLUP REGION │
96
93
/// │ │
@@ -112,26 +109,24 @@ pub struct Grid<T> {
112
109
/// columns in that row.
113
110
raw : Storage < T > ,
114
111
115
- /// Number of columns
112
+ /// Number of columns.
116
113
cols : Column ,
117
114
118
115
/// Number of visible lines.
119
116
lines : Line ,
120
117
121
- /// Offset of displayed area
118
+ /// Offset of displayed area.
122
119
///
123
120
/// If the displayed region isn't at the bottom of the screen, it stays
124
121
/// stationary while more text is emitted. The scrolling implementation
125
122
/// updates this offset accordingly.
126
123
display_offset : usize ,
127
124
128
- /// An limit on how far back it's possible to scroll
129
- scroll_limit : usize ,
130
-
131
- /// Selected region
125
+ /// Selected region.
132
126
#[ serde( skip) ]
133
127
pub selection : Option < Selection > ,
134
128
129
+ /// Maximum number of lines in history.
135
130
max_scroll_limit : usize ,
136
131
}
137
132
@@ -147,15 +142,7 @@ pub enum Scroll {
147
142
impl < T : GridCell + PartialEq + Copy > Grid < T > {
148
143
pub fn new ( lines : Line , cols : Column , scrollback : usize , template : T ) -> Grid < T > {
149
144
let raw = Storage :: with_capacity ( lines, Row :: new ( cols, & template) ) ;
150
- Grid {
151
- raw,
152
- cols,
153
- lines,
154
- display_offset : 0 ,
155
- scroll_limit : 0 ,
156
- selection : None ,
157
- max_scroll_limit : scrollback,
158
- }
145
+ Grid { raw, cols, lines, display_offset : 0 , selection : None , max_scroll_limit : scrollback }
159
146
}
160
147
161
148
pub fn buffer_to_visible ( & self , point : impl Into < Point < usize > > ) -> Option < Point < usize > > {
@@ -179,28 +166,30 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
179
166
}
180
167
181
168
/// Update the size of the scrollback history
182
- pub fn update_history ( & mut self , history_size : usize , template : & T ) {
183
- self . raw . update_history ( history_size, Row :: new ( self . cols , & template) ) ;
169
+ pub fn update_history ( & mut self , history_size : usize ) {
170
+ let current_history_size = self . history_size ( ) ;
171
+ if current_history_size > history_size {
172
+ self . raw . shrink_lines ( current_history_size - history_size) ;
173
+ }
174
+ self . display_offset = min ( self . display_offset , history_size) ;
184
175
self . max_scroll_limit = history_size;
185
- self . scroll_limit = min ( self . scroll_limit , history_size) ;
186
- self . display_offset = min ( self . display_offset , self . scroll_limit ) ;
187
176
}
188
177
189
178
pub fn scroll_display ( & mut self , scroll : Scroll ) {
190
179
match scroll {
191
180
Scroll :: Lines ( count) => {
192
181
self . display_offset = min (
193
182
max ( ( self . display_offset as isize ) + count, 0isize ) as usize ,
194
- self . scroll_limit ,
183
+ self . history_size ( ) ,
195
184
) ;
196
185
} ,
197
186
Scroll :: PageUp => {
198
- self . display_offset = min ( self . display_offset + self . lines . 0 , self . scroll_limit ) ;
187
+ self . display_offset = min ( self . display_offset + self . lines . 0 , self . history_size ( ) ) ;
199
188
} ,
200
189
Scroll :: PageDown => {
201
190
self . display_offset -= min ( self . display_offset , self . lines . 0 ) ;
202
191
} ,
203
- Scroll :: Top => self . display_offset = self . scroll_limit ,
192
+ Scroll :: Top => self . display_offset = self . history_size ( ) ,
204
193
Scroll :: Bottom => self . display_offset = 0 ,
205
194
}
206
195
}
@@ -232,21 +221,17 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
232
221
}
233
222
234
223
fn increase_scroll_limit ( & mut self , count : usize , template : & T ) {
235
- self . scroll_limit = min ( self . scroll_limit + count, self . max_scroll_limit ) ;
236
-
237
- // Initialize new lines when the history buffer is smaller than the scroll limit
238
- let history_size = self . raw . len ( ) . saturating_sub ( * self . lines ) ;
239
- if history_size < self . scroll_limit {
240
- let new = min (
241
- max ( self . scroll_limit - history_size, MIN_INIT_SIZE ) ,
242
- self . max_scroll_limit - history_size,
243
- ) ;
244
- self . raw . initialize ( new, Row :: new ( self . cols , template) ) ;
224
+ let count = min ( count, self . max_scroll_limit - self . history_size ( ) ) ;
225
+ if count != 0 {
226
+ self . raw . initialize ( count, template, self . cols ) ;
245
227
}
246
228
}
247
229
248
230
fn decrease_scroll_limit ( & mut self , count : usize ) {
249
- self . scroll_limit = self . scroll_limit . saturating_sub ( count) ;
231
+ let count = min ( count, self . history_size ( ) ) ;
232
+ if count != 0 {
233
+ self . raw . shrink_lines ( min ( count, self . history_size ( ) ) ) ;
234
+ }
250
235
}
251
236
252
237
/// Add lines to the visible area
@@ -262,12 +247,12 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
262
247
self . lines = new_line_count;
263
248
264
249
// Move existing lines up if there is no scrollback to fill new lines
265
- if lines_added . 0 > self . scroll_limit {
266
- let scroll_lines = lines_added - self . scroll_limit ;
267
- self . scroll_up ( & ( Line ( 0 ) ..new_line_count) , scroll_lines , template) ;
250
+ let history_size = self . history_size ( ) ;
251
+ if lines_added. 0 > history_size {
252
+ self . scroll_up ( & ( Line ( 0 ) ..new_line_count) , lines_added - history_size , template) ;
268
253
}
269
254
270
- self . scroll_limit = self . scroll_limit . saturating_sub ( * lines_added) ;
255
+ self . decrease_scroll_limit ( * lines_added) ;
271
256
self . display_offset = self . display_offset . saturating_sub ( * lines_added) ;
272
257
}
273
258
@@ -326,22 +311,13 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
326
311
last_row. append ( & mut cells) ;
327
312
328
313
if row. is_empty ( ) {
329
- let raw_len = i + 1 + reversed. len ( ) ;
330
- if raw_len < self . lines . 0 || self . scroll_limit == 0 {
314
+ if i + reversed. len ( ) < self . lines . 0 {
331
315
// Add new line and move lines up if we can't pull from history
332
316
cursor_pos. line = Line ( cursor_pos. line . saturating_sub ( 1 ) ) ;
333
317
new_empty_lines += 1 ;
334
- } else {
335
- // Make sure viewport doesn't move if line is outside of the visible
336
- // area
337
- if i < self . display_offset {
338
- self . display_offset = self . display_offset . saturating_sub ( 1 ) ;
339
- }
340
-
341
- // Remove one line from scrollback, since we just moved it to the
342
- // viewport
343
- self . scroll_limit = self . scroll_limit . saturating_sub ( 1 ) ;
344
- self . display_offset = min ( self . display_offset , self . scroll_limit ) ;
318
+ } else if i < self . display_offset {
319
+ // Keep viewport in place if line is outside of the visible area
320
+ self . display_offset = self . display_offset . saturating_sub ( 1 ) ;
345
321
}
346
322
347
323
// Don't push line into the new buffer
@@ -368,6 +344,7 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
368
344
369
345
self . raw . replace_inner ( new_raw) ;
370
346
347
+ self . display_offset = min ( self . display_offset , self . history_size ( ) ) ;
371
348
self . cols = cols;
372
349
}
373
350
@@ -450,9 +427,6 @@ impl<T: GridCell + PartialEq + Copy> Grid<T> {
450
427
wrapped. append ( & mut vec ! [ * template; cols. 0 - occ] ) ;
451
428
}
452
429
row = Row :: from_vec ( wrapped, occ) ;
453
-
454
- // Increase scrollback history
455
- self . scroll_limit = min ( self . scroll_limit + 1 , self . max_scroll_limit ) ;
456
430
}
457
431
}
458
432
}
@@ -643,6 +617,7 @@ impl<T> Grid<T> {
643
617
self . lines
644
618
}
645
619
620
+ #[ inline]
646
621
pub fn display_iter ( & self ) -> DisplayIter < ' _ , T > {
647
622
DisplayIter :: new ( self )
648
623
}
@@ -652,16 +627,10 @@ impl<T> Grid<T> {
652
627
self . cols
653
628
}
654
629
630
+ #[ inline]
655
631
pub fn clear_history ( & mut self ) {
656
632
// Explicitly purge all lines from history
657
- let shrinkage = self . raw . len ( ) - self . lines . 0 ;
658
- self . raw . shrink_lines ( shrinkage) ;
659
- self . scroll_limit = 0 ;
660
- }
661
-
662
- #[ inline]
663
- pub fn scroll_limit ( & self ) -> usize {
664
- self . scroll_limit
633
+ self . raw . shrink_lines ( self . history_size ( ) ) ;
665
634
}
666
635
667
636
/// Total number of lines in the buffer, this includes scrollback + visible lines
@@ -672,23 +641,29 @@ impl<T> Grid<T> {
672
641
673
642
#[ inline]
674
643
pub fn history_size ( & self ) -> usize {
675
- self . raw . len ( ) . saturating_sub ( * self . lines )
644
+ self . raw . len ( ) - * self . lines
676
645
}
677
646
678
647
/// This is used only for initializing after loading ref-tests
648
+ #[ inline]
679
649
pub fn initialize_all ( & mut self , template : & T )
680
650
where
681
651
T : Copy + GridCell ,
682
652
{
683
- let history_size = self . raw . len ( ) . saturating_sub ( * self . lines ) ;
684
- self . raw . initialize ( self . max_scroll_limit - history_size, Row :: new ( self . cols , template) ) ;
653
+ // Remove all cached lines to clear them of any content
654
+ self . truncate ( ) ;
655
+
656
+ // Initialize everything with empty new lines
657
+ self . raw . initialize ( self . max_scroll_limit - self . history_size ( ) , template, self . cols ) ;
685
658
}
686
659
687
660
/// This is used only for truncating before saving ref-tests
661
+ #[ inline]
688
662
pub fn truncate ( & mut self ) {
689
663
self . raw . truncate ( ) ;
690
664
}
691
665
666
+ #[ inline]
692
667
pub fn iter_from ( & self , point : Point < usize > ) -> GridIterator < ' _ , T > {
693
668
GridIterator { grid : self , cur : point }
694
669
}
0 commit comments