scripts: Adopted -n/--lines in most ascii art scripts

The notable exception being plot.py, where line-level history doesn't
really make sense.

These scripts all default to height=1, and -n/--lines can be useful for
viewing changes over time.

In theory you could achieve something similar to this with tailpipe.py,
but you would lose the header info, which is useful.

---

Note, as a point of simplicity, we do _not_ show sub-char history like
we used to in tracebd.py. That was way too complicated for what it was
worth.
This commit is contained in:
Christopher Haster
2025-04-10 17:12:56 -05:00
parent 8e3760c5b8
commit fc5bfdae14
5 changed files with 113 additions and 29 deletions
+43 -7
View File
@@ -1357,8 +1357,11 @@ def main_(f, paths, *,
def main(paths, *, def main(paths, *,
width=None,
height=None, height=None,
no_header=None,
keep_open=False, keep_open=False,
lines=None,
head=False, head=False,
cat=False, cat=False,
sleep=False, sleep=False,
@@ -1366,23 +1369,47 @@ def main(paths, *,
# keep-open? # keep-open?
if keep_open: if keep_open:
try: try:
# keep track of history if lines specified
if lines is not None:
ring = RingIO(lines+1
if not no_header and lines > 0
else lines)
while True: while True:
# register inotify before running the command, this avoids # register inotify before running the command, this avoids
# modification race conditions # modification race conditions
if Inotify: if Inotify:
inotify = Inotify(paths) inotify = Inotify(paths)
# cat? write directly to stdout
if cat: if cat:
main_(sys.stdout, paths, main_(sys.stdout, paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
# not cat? write to a bounded ring
else: else:
ring = RingIO(head=head) ring_ = RingIO(head=head)
main_(ring, paths, main_(ring_, paths,
height=height if height is not False else 0, width=width,
height=0 if height is ... else height,
no_header=no_header,
**args) **args)
ring.draw() # no history? draw immediately
if lines is None:
ring_.draw()
# history? merge with previous lines
else:
# write header separately?
if not no_header:
if not ring.lines:
ring.lines.append('')
ring.lines.extend(it.islice(ring_.lines, 1, None))
ring.lines[0] = ring_.lines[0]
else:
ring.lines.extend(ring_.lines)
ring.draw()
# try to inotifywait # try to inotifywait
if Inotify: if Inotify:
@@ -1402,8 +1429,10 @@ def main(paths, *,
# single-pass? # single-pass?
else: else:
main_(sys.stdout, paths, main_(sys.stdout, paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
@@ -1518,7 +1547,7 @@ if __name__ == "__main__":
'-H', '--height', '-H', '--height',
nargs='?', nargs='?',
type=lambda x: int(x, 0), type=lambda x: int(x, 0),
const=False, const=..., # handles shell prompt spacing, which is a bit subtle
help="Height in rows. <=0 uses the terminal height. Defaults " help="Height in rows. <=0 uses the terminal height. Defaults "
"to 1.") "to 1.")
parser.add_argument( parser.add_argument(
@@ -1630,6 +1659,13 @@ if __name__ == "__main__":
'-k', '--keep-open', '-k', '--keep-open',
action='store_true', action='store_true',
help="Continue to open and redraw the CSV files in a loop.") help="Continue to open and redraw the CSV files in a loop.")
parser.add_argument(
'-n', '--lines',
nargs='?',
type=lambda x: int(x, 0),
const=0,
help="Show this many lines of history. <=0 uses the terminal "
"height. Defaults to 1.")
parser.add_argument( parser.add_argument(
'-^', '--head', '-^', '--head',
action='store_true', action='store_true',
+14 -8
View File
@@ -4821,7 +4821,9 @@ def main_(f, disk, mroots=None, *,
def main(disk, mroots=None, *, def main(disk, mroots=None, *,
width=None,
height=None, height=None,
no_header=None,
keep_open=False, keep_open=False,
lines=None, lines=None,
head=False, head=False,
@@ -4834,7 +4836,7 @@ def main(disk, mroots=None, *,
# keep track of history if lines specified # keep track of history if lines specified
if lines is not None: if lines is not None:
ring = RingIO(lines+1 ring = RingIO(lines+1
if not args.get('no_header') and lines > 0 if not no_header and lines > 0
else lines) else lines)
while True: while True:
# register inotify before running the command, this avoids # register inotify before running the command, this avoids
@@ -4842,18 +4844,21 @@ def main(disk, mroots=None, *,
if Inotify: if Inotify:
inotify = Inotify([disk]) inotify = Inotify([disk])
# TODO sync these comments
# cat? write directly to stdout # cat? write directly to stdout
if cat: if cat:
main_(sys.stdout, disk, mroots, main_(sys.stdout, disk, mroots,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
# not cat? write to a bounded ring # not cat? write to a bounded ring
else: else:
ring_ = RingIO(head=head) ring_ = RingIO(head=head)
main_(ring_, disk, mroots, main_(ring_, disk, mroots,
height=height if height is not False else 0, width=width,
height=0 if height is ... else height,
no_header=no_header,
**args) **args)
# no history? draw immediately # no history? draw immediately
if lines is None: if lines is None:
@@ -4861,7 +4866,7 @@ def main(disk, mroots=None, *,
# history? merge with previous lines # history? merge with previous lines
else: else:
# write header separately? # write header separately?
if not args.get('no_header'): if not no_header:
if not ring.lines: if not ring.lines:
ring.lines.append('') ring.lines.append('')
ring.lines.extend(it.islice(ring_.lines, 1, None)) ring.lines.extend(it.islice(ring_.lines, 1, None))
@@ -4888,8 +4893,10 @@ def main(disk, mroots=None, *,
# single-pass? # single-pass?
else: else:
main_(sys.stdout, disk, mroots, main_(sys.stdout, disk, mroots,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
@@ -4996,7 +5003,7 @@ if __name__ == "__main__":
'-H', '--height', '-H', '--height',
nargs='?', nargs='?',
type=lambda x: int(x, 0), type=lambda x: int(x, 0),
const=False, const=..., # handles shell prompt spacing, which is a bit subtle
help="Height in rows. <=0 uses the terminal height. Defaults " help="Height in rows. <=0 uses the terminal height. Defaults "
"to 1.") "to 1.")
parser.add_argument( parser.add_argument(
@@ -5079,7 +5086,6 @@ if __name__ == "__main__":
'-k', '--keep-open', '-k', '--keep-open',
action='store_true', action='store_true',
help="Continue to open and redraw the CSV files in a loop.") help="Continue to open and redraw the CSV files in a loop.")
# TODO drop this?
parser.add_argument( parser.add_argument(
'-n', '--lines', '-n', '--lines',
nargs='?', nargs='?',
+10 -4
View File
@@ -1801,6 +1801,7 @@ def main_(f, csv_paths, *,
def main(csv_paths, *, def main(csv_paths, *,
width=None,
height=None, height=None,
keep_open=False, keep_open=False,
head=False, head=False,
@@ -1816,15 +1817,19 @@ def main(csv_paths, *,
if Inotify: if Inotify:
inotify = Inotify(csv_paths) inotify = Inotify(csv_paths)
# cat? write directly to stdout
if cat: if cat:
main_(sys.stdout, csv_paths, main_(sys.stdout, csv_paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
**args) **args)
# not cat? write to a bounded ring
else: else:
ring = RingIO(head=head) ring = RingIO(head=head)
main_(ring, csv_paths, main_(ring, csv_paths,
height=height if height is not False else 0, width=width,
height=0 if height is ... else height,
**args) **args)
ring.draw() ring.draw()
@@ -1846,8 +1851,9 @@ def main(csv_paths, *,
# single-pass? # single-pass?
else: else:
main_(sys.stdout, csv_paths, main_(sys.stdout, csv_paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
**args) **args)
@@ -1969,7 +1975,7 @@ if __name__ == "__main__":
'-H', '--height', '-H', '--height',
nargs='?', nargs='?',
type=lambda x: int(x, 0), type=lambda x: int(x, 0),
const=False, const=..., # handles shell prompt spacing, which is a bit subtle
help="Height in rows. <=0 uses the terminal height. Defaults " help="Height in rows. <=0 uses the terminal height. Defaults "
"to 17.") "to 17.")
parser.add_argument( parser.add_argument(
+3 -3
View File
@@ -2511,13 +2511,13 @@ def main(path='-', *,
# other scripts? # other scripts?
width=width, width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1) height=-1 if height is ... else height)
# not cat? write to a bounded ring # not cat? write to a bounded ring
else: else:
ring_ = RingIO(head=head) ring_ = RingIO(head=head)
draw__(ring_, draw__(ring_,
width=width, width=width,
height=height if height is not False else 0) height=0 if height is ... else height)
# no history? draw immediately # no history? draw immediately
if lines is None: if lines is None:
ring_.draw() ring_.draw()
@@ -2704,7 +2704,7 @@ if __name__ == "__main__":
'-H', '--height', '-H', '--height',
nargs='?', nargs='?',
type=lambda x: int(x, 0), type=lambda x: int(x, 0),
const=False, const=..., # handles shell prompt spacing, which is a bit subtle
help="Height in rows. <=0 uses the terminal height. Defaults " help="Height in rows. <=0 uses the terminal height. Defaults "
"to 1.") "to 1.")
parser.add_argument( parser.add_argument(
+43 -7
View File
@@ -1238,8 +1238,11 @@ def main_(f, csv_paths, *,
def main(csv_paths, *, def main(csv_paths, *,
width=None,
height=None, height=None,
no_header=None,
keep_open=False, keep_open=False,
lines=None,
head=False, head=False,
cat=False, cat=False,
sleep=False, sleep=False,
@@ -1247,23 +1250,47 @@ def main(csv_paths, *,
# keep-open? # keep-open?
if keep_open: if keep_open:
try: try:
# keep track of history if lines specified
if lines is not None:
ring = RingIO(lines+1
if not no_header and lines > 0
else lines)
while True: while True:
# register inotify before running the command, this avoids # register inotify before running the command, this avoids
# modification race conditions # modification race conditions
if Inotify: if Inotify:
inotify = Inotify(csv_paths) inotify = Inotify(csv_paths)
# cat? write directly to stdout
if cat: if cat:
main_(sys.stdout, csv_paths, main_(sys.stdout, csv_paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
# not cat? write to a bounded ring
else: else:
ring = RingIO(head=head) ring_ = RingIO(head=head)
main_(ring, csv_paths, main_(ring_, csv_paths,
height=height if height is not False else 0, width=width,
height=0 if height is ... else height,
no_header=no_header,
**args) **args)
ring.draw() # no history? draw immediately
if lines is None:
ring_.draw()
# history? merge with previous lines
else:
# write header separately?
if not no_header:
if not ring.lines:
ring.lines.append('')
ring.lines.extend(it.islice(ring_.lines, 1, None))
ring.lines[0] = ring_.lines[0]
else:
ring.lines.extend(ring_.lines)
ring.draw()
# try to inotifywait # try to inotifywait
if Inotify: if Inotify:
@@ -1283,8 +1310,10 @@ def main(csv_paths, *,
# single-pass? # single-pass?
else: else:
main_(sys.stdout, csv_paths, main_(sys.stdout, csv_paths,
width=width,
# make space for shell prompt # make space for shell prompt
height=height if height is not False else -1, height=-1 if height is ... else height,
no_header=no_header,
**args) **args)
@@ -1381,7 +1410,7 @@ if __name__ == "__main__":
'-H', '--height', '-H', '--height',
nargs='?', nargs='?',
type=lambda x: int(x, 0), type=lambda x: int(x, 0),
const=False, const=..., # handles shell prompt spacing, which is a bit subtle
help="Height in rows. <=0 uses the terminal height. Defaults " help="Height in rows. <=0 uses the terminal height. Defaults "
"to 1.") "to 1.")
parser.add_argument( parser.add_argument(
@@ -1475,6 +1504,13 @@ if __name__ == "__main__":
'-k', '--keep-open', '-k', '--keep-open',
action='store_true', action='store_true',
help="Continue to open and redraw the CSV files in a loop.") help="Continue to open and redraw the CSV files in a loop.")
parser.add_argument(
'-n', '--lines',
nargs='?',
type=lambda x: int(x, 0),
const=0,
help="Show this many lines of history. <=0 uses the terminal "
"height. Defaults to 1.")
parser.add_argument( parser.add_argument(
'-^', '--head', '-^', '--head',
action='store_true', action='store_true',