Skip to content

Commit e945ea5

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 e32e8e8 commit e945ea5

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
@@ -111,6 +111,9 @@ def after_suspend():
111111
window.__enter__()
112112
interrupting_refresh()
113113

114+
def get_top_usable_line():
115+
return window.top_usable_row
116+
114117
# global for easy introspection `from bpython.curtsies import repl`
115118
global repl
116119
with Repl(config=config,
@@ -126,9 +129,12 @@ def after_suspend():
126129
interactive=interactive,
127130
orig_tcattrs=input_generator.original_stty,
128131
on_suspend=on_suspend,
129-
after_suspend=after_suspend) as repl:
132+
after_suspend=after_suspend,
133+
get_top_usable_line=get_top_usable_line) as repl:
130134
repl.height, repl.width = window.t.height, window.t.width
131135

136+
repl.request_paint_to_pad_bottom = 10
137+
132138
def process_event(e):
133139
"""If None is passed in, just paint the screen"""
134140
try:

bpython/curtsiesfrontend/repl.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ def __init__(self,
246246
interactive=True,
247247
orig_tcattrs=None,
248248
on_suspend=lambda *args: None,
249-
after_suspend=lambda *args: None):
249+
after_suspend=lambda *args: None,
250+
get_top_usable_line=lambda: 0):
250251
"""
251252
locals_ is a mapping of locals to pass into the interpreter
252253
config is a bpython config.Struct with config attributes
@@ -266,6 +267,7 @@ def __init__(self,
266267
original terminal state, useful for shelling out with normal terminal
267268
on_suspend will be called on sigtstp
268269
after_suspend will be called when process foregrounded after suspend
270+
get_top_usable_line returns the top line of the terminal owned
269271
"""
270272

271273
logger.debug("starting init")
@@ -361,6 +363,7 @@ def smarter_request_reload(files_modified=()):
361363
self.orig_tcattrs = orig_tcattrs
362364
self.on_suspend = on_suspend
363365
self.after_suspend = after_suspend
366+
self.get_top_usable_line = get_top_usable_line
364367

365368
self.coderunner = CodeRunner(self.interp, self.request_refresh)
366369
self.stdout = FakeOutput(self.coderunner, self.send_to_stdout)
@@ -370,6 +373,8 @@ def smarter_request_reload(files_modified=()):
370373
# next paint should clear screen
371374
self.request_paint_to_clear_screen = False
372375

376+
self.request_paint_to_pad_bottom = 0
377+
373378
# offscreen command yields results different from scrollback bufffer
374379
self.inconsistent_history = False
375380

@@ -1125,6 +1130,10 @@ def paint(self, about_to_exit=False, user_quit=False):
11251130
if self.request_paint_to_clear_screen: # or show_status_bar and about_to_exit ?
11261131
self.request_paint_to_clear_screen = False
11271132
arr = FSArray(min_height + current_line_start_row, width)
1133+
elif self.request_paint_to_pad_bottom:
1134+
# min_height - 1 for startup banner with python version
1135+
arr = FSArray(min(self.request_paint_to_pad_bottom, min_height - 1), width)
1136+
self.request_paint_to_pad_bottom = 0
11281137
else:
11291138
arr = FSArray(0, width)
11301139
#TODO test case of current line filling up the whole screen (there aren't enough rows to show it)
@@ -1209,7 +1218,8 @@ def move_screen_up(current_line_start_row):
12091218
if self.list_win_visible and not self.coderunner.running:
12101219
logger.debug('infobox display code running')
12111220
visible_space_above = history.height
1212-
visible_space_below = min_height - current_line_end_row - 1
1221+
potential_space_below = min_height - current_line_end_row - 1
1222+
visible_space_below = potential_space_below - self.get_top_usable_line()
12131223

12141224
info_max_rows = max(visible_space_above, visible_space_below)
12151225
infobox = paint.paint_infobox(info_max_rows,
@@ -1219,12 +1229,16 @@ def move_screen_up(current_line_start_row):
12191229
self.current_match,
12201230
self.docstring,
12211231
self.config,
1222-
self.matches_iter.completer.format if self.matches_iter.completer else None)
1232+
self.matches_iter.completer.format
1233+
if self.matches_iter.completer
1234+
else None)
12231235

1224-
if visible_space_above >= infobox.height and self.config.curtsies_list_above:
1225-
arr[current_line_start_row - infobox.height:current_line_start_row, 0:infobox.width] = infobox
1226-
else:
1236+
if visible_space_below >= infobox.height or not self.config.curtsies_list_above:
1237+
if visible_space_below < infobox.height:
1238+
raise ValueError('whoops %r %r' % (visible_space_below, infobox.height))
12271239
arr[current_line_end_row + 1:current_line_end_row + 1 + infobox.height, 0:infobox.width] = infobox
1240+
else:
1241+
arr[current_line_start_row - infobox.height:current_line_start_row, 0:infobox.width] = infobox
12281242
logger.debug('slamming infobox of shape %r into arr of shape %r', infobox.shape, arr.shape)
12291243

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

0 commit comments

Comments
 (0)