summaryrefslogtreecommitdiffstats
path: root/python/mach/mach/terminal.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mach/mach/terminal.py')
-rw-r--r--python/mach/mach/terminal.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/python/mach/mach/terminal.py b/python/mach/mach/terminal.py
new file mode 100644
index 0000000000..a0c8d0a6ed
--- /dev/null
+++ b/python/mach/mach/terminal.py
@@ -0,0 +1,76 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+"""This file contains code for interacting with terminals.
+
+All the terminal interaction code is consolidated so the complexity can be in
+one place, away from code that is commonly looked at.
+"""
+
+import logging
+import sys
+
+from six.moves import range
+
+
+class LoggingHandler(logging.Handler):
+ """Custom logging handler that works with terminal window dressing.
+
+ This is alternative terminal logging handler which contains smarts for
+ emitting terminal control characters properly. Currently, it has generic
+ support for "footer" elements at the bottom of the screen. Functionality
+ can be added when needed.
+ """
+
+ def __init__(self):
+ logging.Handler.__init__(self)
+
+ self.fh = sys.stdout
+ self.footer = None
+
+ def flush(self):
+ self.acquire()
+
+ try:
+ self.fh.flush()
+ finally:
+ self.release()
+
+ def emit(self, record):
+ msg = self.format(record)
+
+ if self.footer:
+ self.footer.clear()
+
+ self.fh.write(msg)
+ self.fh.write("\n")
+
+ if self.footer:
+ self.footer.draw()
+
+ # If we don't flush, the footer may not get drawn.
+ self.flush()
+
+
+class TerminalFooter(object):
+ """Represents something drawn on the bottom of a terminal."""
+
+ def __init__(self, terminal):
+ self.t = terminal
+ self.fh = sys.stdout
+
+ def _clear_lines(self, n):
+ for i in range(n):
+ self.fh.write(self.t.move_x(0))
+ self.fh.write(self.t.clear_eol())
+ self.fh.write(self.t.move_up())
+
+ self.fh.write(self.t.move_down())
+ self.fh.write(self.t.move_x(0))
+
+ def clear(self):
+ raise Exception("clear() must be implemented.")
+
+ def draw(self):
+ raise Exception("draw() must be implemented.")