bczsalba / pytermgui

Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!
https://ptg.bczsalba.com
MIT License
2.21k stars 54 forks source link

[REQUEST] Allow printing to the last row of the terminal #53

Closed leftbones closed 2 years ago

leftbones commented 2 years ago

I've noticed that doing something like

for row in range(ptg.terminal.height):
    print("something!", pos=(0, row))

Always misses the last row of the terminal. Doing ptg.terminal.height + 1 scrolls the view down one line when printing the last line.

I'm in the process of learning this to replace curses, and I know with curses you can use functions like insstr() or insch() to be able to print right at the edges of the terminal without going out of bounds.

This is definitely something I'd like to see in PTG, it would make full screen apps feel truly "fullscreen"!

bczsalba commented 2 years ago

This bug had me very confused for a bit, but I figured out what the issue is.

By default, the pretty.print function mimics the builtin print, which has end set to \n. So in the code above, the last row is printed, then a newline is used to cap it off which causes the overflow.

There is also another more minor thing: the xterm terminal's coordinate system has its origin at (1, 1), not at (0, 0). Because of this it's usually beneficial to wrap coordinates in a way that accounts for the origin, especially as it is different on Windows AFAIK.

Regardless, the following works on my machine:

for row in range(ptg.terminal.height):
    print(f"{row} something!", pos=(1, row + 1), end="")

If the origin is not account for, the terminal essentially "swallows" the first row: it never appears on the screen.

Definitely something to document further, so thanks for the shout!

leftbones commented 2 years ago

Very interesting. Don't worry, I'm sure I'm going to find a million other weird bugs! I did find out just a minute ago that I can print in a loop to ptg.terminal.height + 1 using ansi_interface.print_to(), that'll print to the last row without any problems.

bczsalba commented 2 years ago

Yeah, that function I think is from before pretty.print and it is much more "raw" in a way. Really appreciate the testing!

leftbones commented 2 years ago

No problem! Stumbling my way through moving the cursor around so I'm sure I'll run into something else soon lol.