Skip to content

Commit cbe01ab

Browse files
Fixed rewind interaction with stdout/err
still need to fix stdin.readline --HG-- branch : scroll-frontend extra : amend_source : 78e141e4c2f5230264d7fd6017b5afec667a49af
1 parent 7b04297 commit cbe01ab

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

bpython/scroll.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ def main(args=None, locals_=None, banner=None):
2020

2121
with TerminalController() as tc:
2222
with Terminal(tc, keep_last_line=True, hide_cursor=False) as term:
23-
with Repl(config=config, locals_=locals_, stuff_a_refresh_request=tc.stuff_a_refresh_request, banner=banner) as repl:
23+
with Repl(config=config,
24+
locals_=locals_,
25+
stuff_a_refresh_request=tc.stuff_a_refresh_request,
26+
banner=banner) as repl:
2427
rows, columns = tc.get_screen_size()
2528
repl.width = columns
2629
repl.height = rows

bpython/scrollfrontend/repl.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#TODO use events instead of length-one queues for interthread communication
4444

4545
#TODO raw_input should be bytes in python2
46+
#TODO check py3 compatibility
4647

4748

4849
from bpython.keys import cli_key_dispatch as key_dispatch
@@ -145,7 +146,12 @@ def __init__(self, locals_=None, config=None, stuff_a_refresh_request=lambda: No
145146
self.cursor_offset_in_line = 0 # from the left, 0 means first char
146147
self.done = True
147148

148-
self.coderunner = CodeRunner(self.interp, stuff_a_refresh_request)
149+
def request_refresh():
150+
self.refresh_requests += 1
151+
stuff_a_refresh_request()
152+
self.refresh_requests = 0
153+
self.stuff_a_refresh_request = request_refresh
154+
self.coderunner = CodeRunner(self.interp, request_refresh)
149155
self.stdout = FakeOutput(self.coderunner, self.send_to_stdout)
150156
self.stderr = FakeOutput(self.coderunner, self.send_to_stderr)
151157
self.stdin = FakeStdin(self.coderunner, self)
@@ -154,6 +160,7 @@ def __init__(self, locals_=None, config=None, stuff_a_refresh_request=lambda: No
154160
self.request_paint_to_clear_screen = False
155161
self.last_events = [None] * 50
156162
self.presentation_mode = False
163+
self.reevaluating = False
157164

158165
self.width = None # will both be set by a window resize event
159166
self.height = None
@@ -195,7 +202,13 @@ def process_event(self, e):
195202

196203
logging.debug("processing event %r", e)
197204
if isinstance(e, events.RefreshRequestEvent):
198-
self.run_code_and_maybe_finish()
205+
assert self.refresh_requests > 0
206+
self.refresh_requests -= 1
207+
assert self.coderunner.code_is_waiting or self.reevaluating
208+
if self.coderunner.code_is_waiting:
209+
self.run_code_and_maybe_finish()
210+
if self.refresh_requests == 0 and self.reevaluating:
211+
self.reevaluate()
199212
return
200213
self.last_events.append(e)
201214
self.last_events.pop(0)
@@ -263,7 +276,6 @@ def process_event(self, e):
263276
self.on_tab(back=True)
264277
elif e in ('',) + key_dispatch[self.config.undo_key]:
265278
self.undo()
266-
self.update_completion()
267279
elif e in ('\x13',) + key_dispatch[self.config.save_key]: # ctrl-s for save
268280
t = threading.Thread(target=self.write2file)
269281
t.daemon = True
@@ -740,6 +752,15 @@ def reprint_line(self, lineno, tokens):
740752
self.display_buffer[lineno] = bpythonparse(format(tokens, self.formatter))
741753
def reevaluate(self, insert_into_history=False):
742754
"""bpython.Repl.undo calls this"""
755+
#TODO This almost works, but events are necessary to keep it going!
756+
if not self.reevaluating:
757+
self.reevaluating = self.reevaluation_generator(insert_into_history=insert_into_history)
758+
try:
759+
self.reevaluating.next()
760+
except StopIteration:
761+
self.reevaluating = False
762+
763+
def reevaluation_generator(self, insert_into_history):
743764
#TODO other implementations have a enter no-history method, could do
744765
# that instead of clearing history and getting it rewritten
745766
old_logical_lines = self.history
@@ -748,6 +769,7 @@ def reevaluate(self, insert_into_history=False):
748769

749770
self.done = True # this keeps the first prompt correct
750771
self.interp = code.InteractiveInterpreter()
772+
self.coderunner.interp = self.interp
751773
self.completer = Autocomplete(self.interp.locals, self.config)
752774
self.completer.autocomplete_mode = 'simple'
753775
self.buffer = []
@@ -757,8 +779,14 @@ def reevaluate(self, insert_into_history=False):
757779
for line in old_logical_lines:
758780
self._current_line = line
759781
self.on_enter(insert_into_history=insert_into_history)
782+
if self.refresh_requests > 0:
783+
yield line # use up remaining refresh requests
784+
else:
785+
self.stuff_a_refresh_request()
786+
yield line
760787
self.cursor_offset_in_line = 0
761788
self._current_line = ''
789+
762790
def getstdout(self):
763791
lines = self.lines_for_display + [self.current_line_formatted]
764792
s = '\n'.join([x.s if isinstance(x, FmtStr) else x

0 commit comments

Comments
 (0)