Skip to content

Commit 4a43c11

Browse files
first pass at suspending
Doesn't put the cursor back very well at all, but since we're going to have no idea what has happened while Python was suspended there's probably not much we can do.
1 parent 9fa5e7e commit 4a43c11

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

bpython/curtsies.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ def event_or_refresh(timeout=None):
9999
if starttime + timeout < time.time() or e is not None:
100100
yield e
101101

102+
def on_suspend():
103+
window.__exit__(None, None, None)
104+
input_generator.__exit__(None, None, None)
105+
106+
def after_suspend():
107+
input_generator.__enter__()
108+
window.__enter__()
109+
102110
global repl # global for easy introspection `from bpython.curtsies import repl`
103111
with Repl(config=config,
104112
locals_=locals_,
@@ -109,7 +117,9 @@ def event_or_refresh(timeout=None):
109117
banner=banner,
110118
interp=interp,
111119
interactive=interactive,
112-
orig_tcattrs=input_generator.original_stty) as repl:
120+
orig_tcattrs=input_generator.original_stty,
121+
on_suspend=on_suspend,
122+
after_suspend=after_suspend) as repl:
113123
repl.height, repl.width = window.t.height, window.t.width
114124

115125
def process_event(e):

bpython/curtsiesfrontend/repl.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ def __init__(self,
219219
banner=None,
220220
interp=None,
221221
interactive=True,
222-
orig_tcattrs=None):
222+
orig_tcattrs=None,
223+
on_suspend=lambda *args: None,
224+
after_suspend=lambda *args: None):
223225
"""
224226
locals_ is a mapping of locals to pass into the interpreter
225227
config is a bpython config.Struct with config attributes
@@ -298,6 +300,8 @@ def smarter_request_reload(desc):
298300
# because there wasn't room to display everything
299301
self._cursor_offset = 0 # from the left, 0 means first char
300302
self.orig_tcattrs = orig_tcattrs # useful for shelling out with normal terminal
303+
self.on_suspend = on_suspend
304+
self.after_suspend = after_suspend
301305

302306
self.coderunner = CodeRunner(self.interp, self.request_refresh)
303307
self.stdout = FakeOutput(self.coderunner, self.send_to_stdout)
@@ -335,7 +339,9 @@ def __enter__(self):
335339
sys.stderr = self.stderr
336340
sys.stdin = self.stdin
337341
self.orig_sigwinch_handler = signal.getsignal(signal.SIGWINCH)
342+
self.orig_sigtstp_handler = signal.getsignal(signal.SIGTSTP)
338343
signal.signal(signal.SIGWINCH, self.sigwinch_handler)
344+
signal.signal(signal.SIGTSTP, self.sigtstp_handler)
339345

340346
self.orig_import = __builtins__['__import__']
341347
if self.watcher:
@@ -369,6 +375,7 @@ def __exit__(self, *args):
369375
sys.stdout = self.orig_stdout
370376
sys.stderr = self.orig_stderr
371377
signal.signal(signal.SIGWINCH, self.orig_sigwinch_handler)
378+
signal.signal(signal.SIGTSTP, self.orig_sigtstp_handler)
372379
__builtins__['__import__'] = self.orig_import
373380

374381
def sigwinch_handler(self, signum, frame):
@@ -379,6 +386,13 @@ def sigwinch_handler(self, signum, frame):
379386
logger.info('sigwinch! Changed from %r to %r', (old_rows, old_columns), (self.height, self.width))
380387
logger.info('decreasing scroll offset by %d to %d', cursor_dy, self.scroll_offset)
381388

389+
def sigtstp_handler(self, signum, frame):
390+
self.__exit__()
391+
self.on_suspend()
392+
os.kill(os.getpid(), signal.SIGTSTP)
393+
self.after_suspend()
394+
self.__enter__()
395+
382396
def startup(self):
383397
"""
384398
Execute PYTHONSTARTUP file if it exits. Call this after front

0 commit comments

Comments
 (0)