Skip to content

Commit f83e3eb

Browse files
mitigate jarring scroll up on completion
-max completion box size calculated from space on screen -prefer displaying box below, but if scroll require display above -scroll down 10 lines on startup
1 parent afec99d commit f83e3eb

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

bpython/curtsies.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ def after_suspend():
158158
window.__enter__()
159159
interrupting_refresh()
160160

161+
def get_top_usable_line():
162+
return window.top_usable_row
163+
161164
# global for easy introspection `from bpython.curtsies import repl`
162165
global repl
163166
with Repl(config=config,
@@ -173,9 +176,12 @@ def after_suspend():
173176
interactive=interactive,
174177
orig_tcattrs=input_generator.original_stty,
175178
on_suspend=on_suspend,
176-
after_suspend=after_suspend) as repl:
179+
after_suspend=after_suspend,
180+
get_top_usable_line=get_top_usable_line) as repl:
177181
repl.height, repl.width = window.t.height, window.t.width
178182

183+
repl.request_paint_to_pad_bottom = 10
184+
179185
def process_event(e):
180186
"""If None is passed in, just paint the screen"""
181187
try:

bpython/curtsiesfrontend/repl.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ def __init__(self,
311311
interactive=True,
312312
orig_tcattrs=None,
313313
on_suspend=lambda *args: None,
314-
after_suspend=lambda *args: None):
314+
after_suspend=lambda *args: None,
315+
get_top_usable_line=lambda: 0):
315316
"""
316317
locals_ is a mapping of locals to pass into the interpreter
317318
config is a bpython config.Struct with config attributes
@@ -331,6 +332,7 @@ def __init__(self,
331332
original terminal state, useful for shelling out with normal terminal
332333
on_suspend will be called on sigtstp
333334
after_suspend will be called when process foregrounded after suspend
335+
get_top_usable_line returns the top line of the terminal owned
334336
"""
335337

336338
logger.debug("starting init")
@@ -425,6 +427,7 @@ def smarter_request_reload(files_modified=()):
425427
self.orig_tcattrs = orig_tcattrs
426428
self.on_suspend = on_suspend
427429
self.after_suspend = after_suspend
430+
self.get_top_usable_line = get_top_usable_line
428431

429432
self.coderunner = CodeRunner(self.interp, self.request_refresh)
430433
self.stdout = FakeOutput(self.coderunner, self.send_to_stdout)
@@ -434,6 +437,8 @@ def smarter_request_reload(files_modified=()):
434437
# next paint should clear screen
435438
self.request_paint_to_clear_screen = False
436439

440+
self.request_paint_to_pad_bottom = 0
441+
437442
# offscreen command yields results different from scrollback bufffer
438443
self.inconsistent_history = False
439444

@@ -1202,6 +1207,10 @@ def paint(self, about_to_exit=False, user_quit=False):
12021207
if self.request_paint_to_clear_screen: # or show_status_bar and about_to_exit ?
12031208
self.request_paint_to_clear_screen = False
12041209
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
12051214
else:
12061215
arr = FSArray(0, width)
12071216
# TODO test case of current line filling up the whole screen (there
@@ -1298,7 +1307,8 @@ def move_screen_up(current_line_start_row):
12981307
if self.list_win_visible and not self.coderunner.running:
12991308
logger.debug('infobox display code running')
13001309
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()
13021312

13031313
info_max_rows = max(visible_space_above, visible_space_below)
13041314
infobox = paint.paint_infobox(info_max_rows,
@@ -1309,12 +1319,16 @@ def move_screen_up(current_line_start_row):
13091319
self.current_match,
13101320
self.docstring,
13111321
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)
13131325

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))
13171329
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
13181332
logger.debug('slamming infobox of shape %r into arr of shape %r', infobox.shape, arr.shape)
13191333

13201334
logger.debug('about to exit: %r', about_to_exit)

0 commit comments

Comments
 (0)