summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2020-04-10 00:08:40 +0300
committerSimon Glass <sjg@chromium.org>2020-04-21 15:33:47 +0300
commit37b224f9f136f83f22de9221d48d9a0b1b2c3693 (patch)
tree018ff9d008f5dcd1149d98994c25cbad3f8a8a79 /tools
parenta84eb1617997d71bdec1f4152536bd8ecba82e87 (diff)
downloadu-boot-37b224f9f136f83f22de9221d48d9a0b1b2c3693.tar.xz
patman: Support erasing a previously unfinished text line
When printing progress it is useful to print a message and leave the cursor at the end of the line until the operation is finished. When it is finished, the line needs to be erased so a new line can start in its place. Add a function to handle clearing a line previously written by terminal.Print() Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools')
-rwxr-xr-xtools/patman/patman.py2
-rw-r--r--tools/patman/terminal.py47
2 files changed, 48 insertions, 1 deletions
diff --git a/tools/patman/patman.py b/tools/patman/patman.py
index cf53e532dd..7f4ac9aef4 100755
--- a/tools/patman/patman.py
+++ b/tools/patman/patman.py
@@ -93,7 +93,7 @@ elif options.test:
suite = unittest.TestLoader().loadTestsFromTestCase(module)
suite.run(result)
- for module in ['gitutil', 'settings']:
+ for module in ['gitutil', 'settings', 'terminal']:
suite = doctest.DocTestSuite(module)
suite.run(result)
diff --git a/tools/patman/terminal.py b/tools/patman/terminal.py
index 6541fa8f41..c7693eb57a 100644
--- a/tools/patman/terminal.py
+++ b/tools/patman/terminal.py
@@ -10,6 +10,7 @@ This module handles terminal interaction including ANSI color codes.
from __future__ import print_function
import os
+import re
import sys
# Selection of when we want our output to be colored
@@ -19,6 +20,13 @@ COLOR_IF_TERMINAL, COLOR_ALWAYS, COLOR_NEVER = range(3)
print_test_mode = False
print_test_list = []
+# The length of the last line printed without a newline
+last_print_len = None
+
+# credit:
+# stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python
+ansi_escape = re.compile(r'\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
+
class PrintLine:
"""A line of text output
@@ -36,6 +44,33 @@ class PrintLine:
return 'newline=%s, colour=%s, text=%s' % (self.newline, self.colour,
self.text)
+def CalcAsciiLen(text):
+ """Calculate the length of a string, ignoring any ANSI sequences
+
+ Args:
+ text: Text to check
+
+ Returns:
+ Length of text, after skipping ANSI sequences
+
+ >>> col = Color(COLOR_ALWAYS)
+ >>> text = col.Color(Color.RED, 'abc')
+ >>> len(text)
+ 14
+ >>> CalcAsciiLen(text)
+ 3
+ >>>
+ >>> text += 'def'
+ >>> CalcAsciiLen(text)
+ 6
+ >>> text += col.Color(Color.RED, 'abc')
+ >>> CalcAsciiLen(text)
+ 9
+ """
+ result = ansi_escape.sub('', text)
+ return len(result)
+
+
def Print(text='', newline=True, colour=None):
"""Handle a line of output to the terminal.
@@ -47,6 +82,8 @@ def Print(text='', newline=True, colour=None):
newline: True to add a new line at the end of the text
colour: Colour to use for the text
"""
+ global last_print_len
+
if print_test_mode:
print_test_list.append(PrintLine(text, newline, colour))
else:
@@ -55,8 +92,18 @@ def Print(text='', newline=True, colour=None):
text = col.Color(colour, text)
if newline:
print(text)
+ last_print_len = None
else:
print(text, end='', flush=True)
+ last_print_len = CalcAsciiLen(text)
+
+def PrintClear():
+ """Clear a previously line that was printed with no newline"""
+ global last_print_len
+
+ if last_print_len:
+ print('\r%s\r' % (' '* last_print_len), end='', flush=True)
+ last_print_len = None
def SetPrintTestMode():
"""Go into test mode, where all printing is recorded"""