Skip to content

Commit

Permalink
Move screen stop/start logic into context manager.
Browse files Browse the repository at this point in the history
As well as reducing duplication and adding screen size detection to
:pipeto and :pyshell, this ensures that the screen is always restarted,
resulting in cleaner error handling if an error occurs while the screen
is stopped.
  • Loading branch information
tomjnixon committed Feb 19, 2018
1 parent 021735b commit 0101656
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 22 deletions.
14 changes: 4 additions & 10 deletions alot/commands/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,8 @@ def thread_code(*_):
d = threads.deferToThread(thread_code)
d.addCallback(afterwards)
else:
ui.mainloop.stop()
ret = thread_code()
ui.mainloop.start()

# make sure urwid renders its canvas at the correct size
ui.mainloop.screen_size = None
ui.mainloop.draw_screen()
with ui.paused():
ret = thread_code()

afterwards(ret)

Expand Down Expand Up @@ -348,9 +343,8 @@ class PythonShellCommand(Command):
repeatable = True

def apply(self, ui):
ui.mainloop.stop()
code.interact(local=locals())
ui.mainloop.start()
with ui.paused():
code.interact(local=locals())


@registerCommand(MODE, 'repeat')
Expand Down
21 changes: 9 additions & 12 deletions alot/commands/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,18 +769,15 @@ def apply(self, ui):
if self.notify_stdout:
ui.notify(out)
else:
logging.debug('stop urwid mainloop')
ui.mainloop.stop()
logging.debug('call: %s', self.cmd)
# if proc.stdout is defined later calls to communicate
# seem to be non-blocking!
proc = subprocess.Popen(self.cmd, shell=True,
stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = proc.communicate(mail)
logging.debug('start urwid mainloop')
ui.mainloop.start()
with ui.paused():
logging.debug('call: %s', self.cmd)
# if proc.stdout is defined later calls to communicate
# seem to be non-blocking!
proc = subprocess.Popen(self.cmd, shell=True,
stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = proc.communicate(mail)
if err:
ui.notify(err, priority='error')
return
Expand Down
19 changes: 19 additions & 0 deletions alot/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import signal
import codecs
import contextlib

from twisted.internet import reactor, defer, task
import urwid
Expand Down Expand Up @@ -363,6 +364,24 @@ def exit():
exit_msg = 'Could not stop reactor: {}.'.format(e)
logging.error('%s\nShutting down anyway..', exit_msg)

@contextlib.contextmanager
def paused(self):
"""
context manager that pauses the UI to allow running external commands.
If an exception occurs, the UI will be started before the exception is
re-raised.
"""
self.mainloop.stop()
try:
yield
finally:
self.mainloop.start()

# make sure urwid renders its canvas at the correct size
self.mainloop.screen_size = None
self.mainloop.draw_screen()

def buffer_open(self, buf):
"""register and focus new :class:`~alot.buffers.Buffer`."""

Expand Down
1 change: 1 addition & 0 deletions tests/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def make_key(revoked=False, expired=False, invalid=False, can_encrypt=True,

def make_ui(**kwargs):
ui = mock.Mock(**kwargs)
ui.paused.return_value = mock.MagicMock()

return ui

Expand Down

0 comments on commit 0101656

Please sign in to comment.