4 ms·
> I’m not sure what this does if the log output is multiple lines long It breaks, and it's not pretty. Instead of def clean_up(): for _ in range(n
by Joker_vD 3y ago
> I’m not sure what this does if the log output is multiple lines long
It breaks, and it's not pretty. Instead of
def clean_up():
for _ in range(num_lines):
print("\x1b[1A\x1b[2K", end="") # move up cursor and delete whole line
you need to do
def clean_up():
for printed_line in printed_lines:
print(f'\x1b[{(wcswidth(printed_line) + terminal_width - 1) // terminal_width}A', end='')
print(f'\x1b[J', end='')
However, if your wcswidth differs from the one that your terminal uses, you still get broken output (either missing or doubles lines). And I know of no reliable way to measure actual "lines taken" of a text except by switching terminal to the alternate screen mode, moving cursor to (1,1), printing the text, querying the cursor position from the terminal, then switching back to the normal screen — but it has horrible performance if you work over ssh.
How do I know all of that? I've tried to implement parallel input/output, like Erlang's shell does: you have prompt at the bottom of the terminal, but the output of the running program still gets printed above of the prompt, even as you typing the command. Erlang shell (and pretty much everyone else, e.g. consoline) do it by erasing the prompt with the partial input, printing new line of output, and re-printing back the prompt and your input. In this scenarion, you can't even relaibly query the terminal's cursor position because it will be reported on the stdin so you'll have to relaibly filter it out from the user input... ugh.
Surprisingly, there is no terminal command for "use this text for the prompt in canonical mode" which would solve almost all of it: the terminal itself of course know where it drew what and how many screen estate it took.
- tekknolagi 3y agoOof, good to know. Thank you. I also considered chopping off extra lines or too wide lines that wrap.