You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a table that can be displayed instantly, except for one column which takes a while to determine. I used Live to instantly print the table with the slow column blank, and backfill the empty cells as they're determined. This allows not waiting for the slow data before being able to see the rest of it. This worked great, except when it finishes and exits, the screen scrolls a line for the bash prompt to display. It's a bit jarring when I'm reading for it to scroll a line.
So, I tried:
Including a blank line in the Live renderable, immediately reserving the line for the shell prompt, with Group(table, Text("")).
After Live.stop() executed, manually moving the cursor up a line, moving to column 0, and clearing the line with console.file.write("\x1b[1A\r\x1b[2K").
This didn't quite work. During the slow Live updating, there was the trailing blank line (intended for the shell prompt.) But, afterward, Rich emitted another newline which caused the table to scroll again even though the shell prompt wound up on the line after the table, with a blank line after it.
I'd like to submit an issue and a PR to give Live an optional argument to skip printing the final newline when it's done. It would default to the current behavior of printing it so there's no change in behavior unless someone uses the new argument.
live_final_newline_demo.py, included below, can run without any changes to Rich and demonstrate what I'm talking about. It immediately prints the table, sleeps a second to simulate the slowness, and updates the last column. It shows the scrolling that seems jarring to me. With the proposed implementation on my feature/live/optional-final-newline branch, you can run this with --final-newline false to make the prompt land on the already reserved line.
An alternative implementation would be to give Live an option like reserve_final_line=False as a default, but when set to true it would automatically display a final blank line and leave the cursor on it when it's done. Then, the caller wouldn't have to emit an empty Text line and wouldn't have to manually move the cursor. That would be a larger set of changes. I'd be happy to do it and submit it that way, but my first instinct was to keep the change smaller.
live_final_newline_demo.py
"""Demo for Rich Live's optional final newline behavior.Run with released Rich: python live_final_newline_demo.pyRun with the patched Rich branch: python live_final_newline_demo.py --final-newline falseThe program intentionally prints nothing after the Live display exits. Theobservable behavior is where the shell prompt appears after the final table."""from __future__ importannotationsimportargparseimportinspectfromtimeimportsleepfromrich.consoleimportConsole, Groupfromrich.liveimportLivefromrich.tableimportTablefromrich.textimportTextdefbuild_table(phase: str, final_newline: str, supported: bool) ->Table:
table=Table(title="Live final newline demo")
table.add_column("Field")
table.add_column("Value")
table.add_row("phase", phase)
table.add_row("final_newline", final_newline)
table.add_row("supported", "yes"ifsupportedelse"no")
returntabledefbuild_renderable(phase: str, final_newline: str, supported: bool) ->Group:
returnGroup(build_table(phase, final_newline, supported), Text(""))
defsupports_final_newline() ->bool:
return"final_newline"ininspect.signature(Live).parametersdefparse_args() ->argparse.Namespace:
parser=argparse.ArgumentParser(
description="Display a short Live table, update it once, and exit without printing after the table.",
)
parser.add_argument(
"--final-newline",
choices=("default", "true", "false"),
default="default",
help=(
"Live final newline mode. 'default' passes no argument and works on released Rich; ""'false' demonstrates the patched behavior when supported."
),
)
returnparser.parse_args()
defmain() ->int:
args=parse_args()
console=Console()
supported=supports_final_newline()
final_newline_label=args.final_newlinelive_options= {
"console": console,
"refresh_per_second": 12,
"transient": False,
}
ifargs.final_newline!="default":
ifsupported:
live_options["final_newline"] =args.final_newline=="true"else:
final_newline_label=f"{args.final_newline} requested, unsupported"withLive(build_renderable("initial", final_newline_label, supported), **live_options) aslive:
sleep(1)
live.update(build_renderable("updated", final_newline_label, supported), refresh=True)
ifconsole.is_terminal:
console.file.write("\r\x1b[2K")
console.file.flush()
return0if__name__=="__main__":
raiseSystemExit(main())
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have a table that can be displayed instantly, except for one column which takes a while to determine. I used
Liveto instantly print the table with the slow column blank, and backfill the empty cells as they're determined. This allows not waiting for the slow data before being able to see the rest of it. This worked great, except when it finishes and exits, the screen scrolls a line for the bash prompt to display. It's a bit jarring when I'm reading for it to scroll a line.So, I tried:
Group(table, Text("")).Live.stop()executed, manually moving the cursor up a line, moving to column 0, and clearing the line withconsole.file.write("\x1b[1A\r\x1b[2K").This didn't quite work. During the slow Live updating, there was the trailing blank line (intended for the shell prompt.) But, afterward, Rich emitted another newline which caused the table to scroll again even though the shell prompt wound up on the line after the table, with a blank line after it.
I'd like to submit an issue and a PR to give
Livean optional argument to skip printing the final newline when it's done. It would default to the current behavior of printing it so there's no change in behavior unless someone uses the new argument.live_final_newline_demo.py, included below, can run without any changes to Rich and demonstrate what I'm talking about. It immediately prints the table, sleeps a second to simulate the slowness, and updates the last column. It shows the scrolling that seems jarring to me. With the proposed implementation on my feature/live/optional-final-newline branch, you can run this with--final-newline falseto make the prompt land on the already reserved line.An alternative implementation would be to give Live an option like
reserve_final_line=Falseas a default, but when set to true it would automatically display a final blank line and leave the cursor on it when it's done. Then, the caller wouldn't have to emit an emptyTextline and wouldn't have to manually move the cursor. That would be a larger set of changes. I'd be happy to do it and submit it that way, but my first instinct was to keep the change smaller.live_final_newline_demo.py
EDIT: Follow-up to #4185 (fair enough!)
All reactions