@@ -311,7 +311,8 @@ def __init__(self,
311
311
interactive = True ,
312
312
orig_tcattrs = None ,
313
313
on_suspend = lambda * args : None ,
314
- after_suspend = lambda * args : None ):
314
+ after_suspend = lambda * args : None ,
315
+ get_top_usable_line = lambda : 0 ):
315
316
"""
316
317
locals_ is a mapping of locals to pass into the interpreter
317
318
config is a bpython config.Struct with config attributes
@@ -331,6 +332,7 @@ def __init__(self,
331
332
original terminal state, useful for shelling out with normal terminal
332
333
on_suspend will be called on sigtstp
333
334
after_suspend will be called when process foregrounded after suspend
335
+ get_top_usable_line returns the top line of the terminal owned
334
336
"""
335
337
336
338
logger .debug ("starting init" )
@@ -425,6 +427,7 @@ def smarter_request_reload(files_modified=()):
425
427
self .orig_tcattrs = orig_tcattrs
426
428
self .on_suspend = on_suspend
427
429
self .after_suspend = after_suspend
430
+ self .get_top_usable_line = get_top_usable_line
428
431
429
432
self .coderunner = CodeRunner (self .interp , self .request_refresh )
430
433
self .stdout = FakeOutput (self .coderunner , self .send_to_stdout )
@@ -434,6 +437,8 @@ def smarter_request_reload(files_modified=()):
434
437
# next paint should clear screen
435
438
self .request_paint_to_clear_screen = False
436
439
440
+ self .request_paint_to_pad_bottom = 0
441
+
437
442
# offscreen command yields results different from scrollback bufffer
438
443
self .inconsistent_history = False
439
444
@@ -1202,6 +1207,10 @@ def paint(self, about_to_exit=False, user_quit=False):
1202
1207
if self .request_paint_to_clear_screen : # or show_status_bar and about_to_exit ?
1203
1208
self .request_paint_to_clear_screen = False
1204
1209
arr = FSArray (min_height + current_line_start_row , width )
1210
+ elif self .request_paint_to_pad_bottom :
1211
+ # min_height - 1 for startup banner with python version
1212
+ arr = FSArray (min (self .request_paint_to_pad_bottom , min_height - 1 ), width )
1213
+ self .request_paint_to_pad_bottom = 0
1205
1214
else :
1206
1215
arr = FSArray (0 , width )
1207
1216
# TODO test case of current line filling up the whole screen (there
@@ -1298,7 +1307,8 @@ def move_screen_up(current_line_start_row):
1298
1307
if self .list_win_visible and not self .coderunner .running :
1299
1308
logger .debug ('infobox display code running' )
1300
1309
visible_space_above = history .height
1301
- visible_space_below = min_height - current_line_end_row - 1
1310
+ potential_space_below = min_height - current_line_end_row - 1
1311
+ visible_space_below = potential_space_below - self .get_top_usable_line ()
1302
1312
1303
1313
info_max_rows = max (visible_space_above , visible_space_below )
1304
1314
infobox = paint .paint_infobox (info_max_rows ,
@@ -1309,12 +1319,16 @@ def move_screen_up(current_line_start_row):
1309
1319
self .current_match ,
1310
1320
self .docstring ,
1311
1321
self .config ,
1312
- self .matches_iter .completer .format if self .matches_iter .completer else None )
1322
+ self .matches_iter .completer .format
1323
+ if self .matches_iter .completer
1324
+ else None )
1313
1325
1314
- if visible_space_above >= infobox .height and self .config .curtsies_list_above :
1315
- arr [ current_line_start_row - infobox .height :current_line_start_row , 0 : infobox . width ] = infobox
1316
- else :
1326
+ if visible_space_below >= infobox .height or not self .config .curtsies_list_above :
1327
+ if visible_space_below < infobox .height :
1328
+ raise ValueError ( 'whoops %r %r' % ( visible_space_below , infobox . height ))
1317
1329
arr [current_line_end_row + 1 :current_line_end_row + 1 + infobox .height , 0 :infobox .width ] = infobox
1330
+ else :
1331
+ arr [current_line_start_row - infobox .height :current_line_start_row , 0 :infobox .width ] = infobox
1318
1332
logger .debug ('slamming infobox of shape %r into arr of shape %r' , infobox .shape , arr .shape )
1319
1333
1320
1334
logger .debug ('about to exit: %r' , about_to_exit )
0 commit comments