miniterm: restore EOL and repr toggles, rename transformation->filter
- EOL mode can be toggled (menu + CTRL+L)
- filters can be edited at runtime (menu + CTRL+F)
- encoding can be changed at runtime (menu + CTRL+A)
diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py
index e56e4cc..59086ba 100644
--- a/serial/tools/miniterm.py
+++ b/serial/tools/miniterm.py
@@ -250,10 +250,13 @@
# - add date/time for each newline
# - insert newline after: a) timeout b) packet end character
-TRANSFORMATIONS = {
+EOL_TRANSFORMATIONS = {
'crlf': CRLF,
'cr': CR,
'lf': LF,
+ }
+
+TRANSFORMATIONS = {
'direct': Transform, # no transformation
'default': NoTerminal,
'nocontrol': NoControls,
@@ -273,7 +276,7 @@
class Miniterm(object):
- def __init__(self, port, baudrate, parity, rtscts, xonxoff, echo=False, transformations=()):
+ def __init__(self, port, baudrate, parity, rtscts, xonxoff, echo=False, eol='crlf', filters=()):
self.console = Console()
self.serial = serial.serial_for_url(port, baudrate, parity=parity, rtscts=rtscts, xonxoff=xonxoff, timeout=1)
self.echo = echo
@@ -283,9 +286,9 @@
self.raw = False
self.input_encoding = 'UTF-8'
self.output_encoding = 'UTF-8'
- self.tx_transformations = [TRANSFORMATIONS[t]() for t in transformations]
- self.rx_transformations = list(reversed(self.tx_transformations))
- self.transformation_names = transformations
+ self.eol = eol
+ self.filters = filters
+ self.update_transformations()
self.exit_character = 0x1d # GS/CTRL+]
self.menu_character = 0x14 # Menu: CTRL+T
@@ -320,6 +323,11 @@
if not transmit_only:
self.receiver_thread.join()
+ def update_transformations(self):
+ transformations = [EOL_TRANSFORMATIONS[self.eol]] + [TRANSFORMATIONS[f] for f in self.filters]
+ self.tx_transformations = [t() for t in transformations]
+ self.rx_transformations = list(reversed(self.tx_transformations))
+
def set_rx_encoding(self, encoding, errors='replace'):
self.input_encoding = encoding
self.rx_decoder = codecs.getincrementaldecoder(encoding)(errors)
@@ -353,7 +361,8 @@
#~ LF_MODES[self.convert_outgoing]))
sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
- sys.stderr.write('--- transformations: {}\n'.format(' '.join(self.transformation_names)))
+ sys.stderr.write('--- EOL: {}\n'.format(self.eol.upper()))
+ sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
def reader(self):
"""loop and copy serial->console"""
@@ -455,6 +464,45 @@
elif c == '\x05': # CTRL+E -> toggle local echo
self.echo = not self.echo
sys.stderr.write('--- local echo {} ---\n'.format('active' if self.echo else 'inactive'))
+ elif c == '\x06': # CTRL+F -> edit filters
+ sys.stderr.write('\n--- Available Filters:\n')
+ sys.stderr.write('\n'.join(
+ '--- {:<10} = {.__doc__}'.format(k, v)
+ for k, v in sorted(TRANSFORMATIONS.items())))
+ sys.stderr.write('\n--- Enter new filter name(s) [{}]: '.format(' '.join(self.filters)))
+ with self.console:
+ new_filters = sys.stdin.readline().lower().split()
+ if new_filters:
+ for f in new_filters:
+ if f not in TRANSFORMATIONS:
+ sys.stderr.write('--- unknown filter: {}'.format(repr(f)))
+ break
+ else:
+ self.filters = new_filters
+ self.update_transformations()
+ sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
+ elif c == '\x0c': # CTRL+L -> EOL mode
+ modes = list(EOL_TRANSFORMATIONS) # keys
+ eol = modes.index(self.eol) + 1
+ if eol >= len(modes):
+ eol = 0
+ self.eol = modes[eol]
+ sys.stderr.write('--- EOL: {} ---\n'.format(self.eol.upper()))
+ self.update_transformations()
+ elif c == '\x01': # CTRL+A -> set encoding
+ sys.stderr.write('\n--- Enter new encoding name [{}]: '.format(self.input_encoding))
+ with self.console:
+ new_encoding = sys.stdin.readline().strip()
+ if new_encoding:
+ try:
+ codecs.lookup(new_encoding)
+ except LookupError:
+ sys.stderr.write('--- invalid encoding name: {}\n'.format(new_encoding))
+ else:
+ self.set_rx_encoding(new_encoding)
+ self.set_tx_encoding(new_encoding)
+ sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
+ sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
elif c == '\x09': # CTRL+I -> info
self.dump_port_settings()
#~ elif c == '\x01': # CTRL+A -> cycle escape mode
@@ -553,9 +601,11 @@
--- {exit:7} Send the exit character itself to remote
--- {info:7} Show info
--- {upload:7} Upload file (prompt will be shown)
+--- {repr:7} encoding
+--- {filter:7} edit filters
--- Toggles:
---- {rts:7} RTS {echo:7} local echo
---- {dtr:7} DTR {brk:7} BREAK
+--- {rts:7} RTS {dtr:7} DTR {brk:7} BREAK
+--- {echo:7} echo {eol:7} EOL
---
--- Port settings ({menu} followed by the following):
--- p change port
@@ -575,10 +625,14 @@
echo=key_description('\x05'),
info=key_description('\x09'),
upload=key_description('\x15'),
+ repr=key_description('\x01'),
+ filter=key_description('\x06'),
+ eol=key_description('\x0c'),
)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# default args can be used to override when calling main() from an other script
# e.g to create a miniterm-my-device.py
def main(default_port=None, default_baudrate=9600, default_rts=None, default_dtr=None):
@@ -639,8 +693,7 @@
help="set the encoding for the serial port, default: %(default)s",
default='UTF-8')
- group.add_argument("-t", "--transformation",
- dest="transformations",
+ group.add_argument("-f", "--filter",
action="append",
metavar="NAME",
help="add text transformation",
@@ -696,19 +749,18 @@
dump_port_list()
args.port = raw_input('Enter port name:')
- if args.transformations:
- if 'help' in args.transformations:
- sys.stderr.write('Available Transformations:\n')
+ if args.filter:
+ if 'help' in args.filter:
+ sys.stderr.write('Available filters:\n')
sys.stderr.write('\n'.join(
- '{:<20} = {.__doc__}'.format(k, v)
+ '{:<10} = {.__doc__}'.format(k, v)
for k, v in sorted(TRANSFORMATIONS.items())))
sys.stderr.write('\n')
sys.exit(1)
- transformations = args.transformations
+ filters = args.filter
else:
- transformations = ['default']
+ filters = ['default']
- transformations.insert(0, args.eol.lower())
try:
miniterm = Miniterm(
@@ -718,7 +770,8 @@
rtscts=args.rtscts,
xonxoff=args.xonxoff,
echo=args.echo,
- transformations=transformations,
+ eol=args.eol.lower(),
+ filters=filters,
)
miniterm.exit_character = unichr(args.exit_char)
miniterm.menu_character = unichr(args.menu_char)