@@ -17,6 +17,7 @@ use crate::tty::{Renderer, Term, Terminal};
17
17
use crate :: undo:: Changeset ;
18
18
use crate :: validate:: { ValidationContext , ValidationResult } ;
19
19
use crate :: KillRing ;
20
+ use RefreshKind :: All ;
20
21
21
22
/// Represent the state during line editing.
22
23
/// Implement rendering.
@@ -41,6 +42,15 @@ enum Info<'m> {
41
42
Msg ( Option < & ' m str > ) ,
42
43
}
43
44
45
+ /// Refresh kind
46
+ #[ derive( PartialEq ) ]
47
+ pub enum RefreshKind {
48
+ // Do not clear old rows and keep current layout
49
+ Min ,
50
+ // Clear old rows + layout
51
+ All ,
52
+ }
53
+
44
54
impl < ' out , ' prompt , H : Helper > State < ' out , ' prompt , H > {
45
55
pub fn new (
46
56
out : & ' out mut <Terminal as Term >:: Writer ,
@@ -136,8 +146,7 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
136
146
return Ok ( ( ) ) ;
137
147
}
138
148
if self . highlight_char ( kind) {
139
- let prompt_size = self . prompt_size ;
140
- self . refresh ( self . prompt , prompt_size, true , Info :: NoHint ) ?;
149
+ self . refresh ( self . prompt , self . prompt_size , true , All , Info :: NoHint ) ?;
141
150
} else {
142
151
self . out . move_cursor ( self . layout . cursor , cursor) ?;
143
152
self . layout . prompt_size = self . prompt_size ;
@@ -161,11 +170,16 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
161
170
self . out . move_cursor_at_leftmost ( rdr)
162
171
}
163
172
173
+ pub fn repaint ( & mut self , kind : RefreshKind ) -> Result < ( ) > {
174
+ self . refresh ( self . prompt , self . prompt_size , true , kind, Info :: Hint )
175
+ }
176
+
164
177
fn refresh (
165
178
& mut self ,
166
179
prompt : & str ,
167
180
prompt_size : Position ,
168
181
default_prompt : bool ,
182
+ kind : RefreshKind ,
169
183
info : Info < ' _ > ,
170
184
) -> Result < ( ) > {
171
185
let info = match info {
@@ -179,21 +193,26 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
179
193
None
180
194
} ;
181
195
182
- let new_layout = self
183
- . out
184
- . compute_layout ( prompt_size, default_prompt, & self . line , info) ;
196
+ if kind == RefreshKind :: Min {
197
+ self . out
198
+ . refresh_line ( prompt, & self . line , info, None , & self . layout , highlighter) ?;
199
+ } else {
200
+ let new_layout = self
201
+ . out
202
+ . compute_layout ( prompt_size, default_prompt, & self . line , info) ;
185
203
186
- debug ! ( target: "rustyline" , "old layout: {:?}" , self . layout) ;
187
- debug ! ( target: "rustyline" , "new layout: {new_layout:?}" ) ;
188
- self . out . refresh_line (
189
- prompt,
190
- & self . line ,
191
- info,
192
- & self . layout ,
193
- & new_layout,
194
- highlighter,
195
- ) ?;
196
- self . layout = new_layout;
204
+ debug ! ( target: "rustyline" , "old layout: {:?}" , self . layout) ;
205
+ debug ! ( target: "rustyline" , "new layout: {new_layout:?}" ) ;
206
+ self . out . refresh_line (
207
+ prompt,
208
+ & self . line ,
209
+ info,
210
+ Some ( & self . layout ) ,
211
+ & new_layout,
212
+ highlighter,
213
+ ) ?;
214
+ self . layout = new_layout;
215
+ }
197
216
198
217
Ok ( ( ) )
199
218
}
@@ -270,20 +289,20 @@ impl<H: Helper> Refresher for State<'_, '_, H> {
270
289
fn refresh_line ( & mut self ) -> Result < ( ) > {
271
290
self . hint ( ) ;
272
291
self . highlight_char ( CmdKind :: Other ) ;
273
- self . refresh ( self . prompt , self . prompt_size , true , Info :: Hint )
292
+ self . repaint ( All )
274
293
}
275
294
276
295
fn refresh_line_with_msg ( & mut self , msg : Option < & str > , kind : CmdKind ) -> Result < ( ) > {
277
296
self . hint = None ;
278
297
self . highlight_char ( kind) ;
279
- self . refresh ( self . prompt , self . prompt_size , true , Info :: Msg ( msg) )
298
+ self . refresh ( self . prompt , self . prompt_size , true , All , Info :: Msg ( msg) )
280
299
}
281
300
282
301
fn refresh_prompt_and_line ( & mut self , prompt : & str ) -> Result < ( ) > {
283
302
let prompt_size = self . out . calculate_position ( prompt, Position :: default ( ) ) ;
284
303
self . hint ( ) ;
285
304
self . highlight_char ( CmdKind :: Other ) ;
286
- self . refresh ( prompt, prompt_size, false , Info :: Hint )
305
+ self . refresh ( prompt, prompt_size, false , All , Info :: Hint )
287
306
}
288
307
289
308
fn doing_insert ( & mut self ) {
@@ -321,13 +340,11 @@ impl<H: Helper> Refresher for State<'_, '_, H> {
321
340
fn external_print ( & mut self , msg : String ) -> Result < ( ) > {
322
341
self . out . begin_synchronized_update ( ) ?;
323
342
self . out . clear_rows ( & self . layout ) ?;
324
- self . layout . end . row = 0 ;
325
- self . layout . cursor . row = 0 ;
326
343
self . out . write_and_flush ( msg. as_str ( ) ) ?;
327
344
if !msg. ends_with ( '\n' ) {
328
345
self . out . write_and_flush ( "\n " ) ?;
329
346
}
330
- self . refresh_line ( ) ?;
347
+ self . repaint ( RefreshKind :: Min ) ?;
331
348
self . out . end_synchronized_update ( )
332
349
}
333
350
}
@@ -374,7 +391,7 @@ impl<H: Helper> State<'_, '_, H> {
374
391
let bits = ch. encode_utf8 ( & mut self . byte_buffer ) ;
375
392
self . out . write_and_flush ( bits)
376
393
} else {
377
- self . refresh ( self . prompt , self . prompt_size , true , Info :: Hint )
394
+ self . repaint ( All )
378
395
}
379
396
} else {
380
397
self . refresh_line ( )
@@ -584,7 +601,7 @@ impl<H: Helper> State<'_, '_, H> {
584
601
debug_assert_eq ! ( self . layout. cursor, self . layout. end) ;
585
602
self . out . clear_to_eol ( )
586
603
} else {
587
- self . refresh ( self . prompt , self . prompt_size , true , Info :: Hint )
604
+ self . repaint ( All )
588
605
}
589
606
} else {
590
607
Ok ( ( ) )
@@ -638,7 +655,7 @@ impl<H: Helper> State<'_, '_, H> {
638
655
}
639
656
}
640
657
641
- /// Moves the cursor to the same column in the line above
658
+ /// Moves the cursor to the same column in the line below
642
659
pub fn edit_move_line_down ( & mut self , n : RepeatCount ) -> Result < bool > {
643
660
if self . line . move_to_line_down ( n, & self . layout ) {
644
661
self . move_cursor ( CmdKind :: MoveCursor ) ?;
0 commit comments