tartley / colorama

Simple cross-platform colored terminal text in Python
BSD 3-Clause "New" or "Revised" License
3.51k stars 249 forks source link

Add colorama.just_fix_windows_console() #352

Closed njsmith closed 1 year ago

njsmith commented 1 year ago

As discussed in https://github.com/tartley/colorama/pull/139

Re: the bugs you collected:

just_fix_windows_console() is a no-op if run repeatedly, or if run after someone else has called init.

just_fix_windows_console only touches streams that are pointing to a Windows console. So I guess in theory it would still interfere with your random binary if you try dumping it on your terminal, but (a) no-one expects that to do anything useful, (b) it interprets the random binary the same way a Unix console would, and people seem to live with that. So I'm not worried about it.

I've tested this manually (running demos/demo01.py) on Linux/Win7/Win10.

The big remaining issue is that I'm not sure how to test this, because it touches global state, and init also touches global state, and I'm not sure how to make all the tests run in a single process.

njsmith commented 1 year ago

The big remaining issue is that I'm not sure how to test this, because it touches global state, and init also touches global state, and I'm not sure how to make all the tests run in a single process.

Never mind, fixed this and wrote a test.

tartley commented 1 year ago

This looks amazing, works for me, thank you @njsmith !

LqdBcnAtWork commented 1 year ago

I'm unsure what's up with 0.4.6, but Cursor appears to be broken on win10. Sort of.

Cursor.UP seems to do nothing. Cursor.POS appears to work.

Also, is there a better way to get cursor position than win32.GetConsoleScreenBufferInfo().dwCursorPosition?

njsmith commented 1 year ago

@LqdBcnAtWork Microsoft says it should work, and it seems to work for me: image Do you have a test case you can share?

LqdBcnAtWork commented 1 year ago

I have determined the issue I was having. Cursor is not effected. colorama.win32.GetConsoleScreenBufferInfo().dwCursorPosition however is.

The following code has shown the issue and is repeatable for me:

from time import sleep
from colorama import Cursor
import colorama

colorama.just_fix_windows_console()

space = 10

print(1)
print("\n"*space,Cursor.UP(space),end="\r",sep="") #run with end="" and end="\r"
sleep(1) # take note of where the cursor is while 'sleeping'
pos = colorama.win32.GetConsoleScreenBufferInfo().dwCursorPosition
print(2)
print("pos:",pos.Y)

By having end="" the Y position is calculated while not respecting the movement done by Cursor.UP, however having something print after the reposition fixes the issue.

njsmith commented 1 year ago

Huh, weird. Sounds like this is a quirk on Microsoft's end, so not much we can do about it, but useful to know.

On Tue, Oct 18, 2022 at 4:01 AM LqdBcnAtWork @.***> wrote:

I have determined the issue I was having. Cursor is not effected. colorama.win32.GetConsoleScreenBufferInfo().dwCursorPosition however is.

The following code has shown the issue and is repeatable for me:

from time import sleepfrom colorama import Cursorimport colorama colorama.just_fix_windows_console() space = 10 print(1)print("\n"*space,Cursor.UP(space),end="\r",sep="") #run with end="" and end="\r"sleep(1) # take note of where the cursor is while 'sleeping'pos = colorama.win32.GetConsoleScreenBufferInfo().dwCursorPositionprint(2)print("pos:",pos.Y)

By having end="" the Y position is calculated while not respecting the movement done by Cursor.UP, however having something print after the reposition fixes the issue.

— Reply to this email directly, view it on GitHub https://github.com/tartley/colorama/pull/352#issuecomment-1282205817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEU42HXGKR6GDN7LV75XNTWDZ7P3ANCNFSM6AAAAAARGUAJIY . You are receiving this because you were mentioned.Message ID: @.***>

-- Nathaniel J. Smith -- https://vorpus.org http://vorpus.org

LqdBcnAtWork commented 1 year ago

I discovered another quirk with colorama.win32.GetConsoleScreenBufferInfo(). While this is probably a bad place to write it, I'm unsure of where I should.

Anyway, in windows default command prompt, running str(colorama.win32.GetConsoleScreenBufferInfo()) yields something like this: '(9001,120,56,0,7,27,0,56,119,63,120)'. Those first two numbers are the terminal height and width. However calling the same function in something like the fancy new Terminal app for win10, the result is very different '(52,209,51,0,7,0,0,51,208,52,209)'. It gives the actual space for text, no matter how much you can scroll back by. Now this is an issue because the CMD reports the cursor position from it's zero, while the Terminal reports the cursor position within the screen, but both translate the ANSI calls to be relative to the screen.

So, in my case I have a function that'll print n lines, move back up, n lines, then save the cursor position for printing/reprinting a line. This is so I can specify the amount of lines I may or may not print (but not track) before scrolling would happen. That way I can return to a line and update it's contents without worrying about having to know exactly how many lines have been printed. But due to inconsistent execution between dev and production I need to be able to handle things like the CMD and the Terminal.

Fortunately colorama.win32.GetConsoleScreenBufferInfo().srWindow.Top reports correctly for both, so I just get the Y value for the cursor, and subtract that Top value from it, and add 1. That way I always get an accurate value for the cursor's line.

Windows console, always causing issues because it's different.

tartley commented 1 year ago

Thank you for sharing the info @LqdBcnAtWork, it's good to have it posted somewhere publicly. If I was better at curating our 'issues', I'd suggest it should go there. In fact, why don't I transfer it there... https://github.com/tartley/colorama/issues/357

I created both your reported quirks as issues. Thank you! I closed them, because I don't think we ought to be making any changes to Colorama in response (but am happy to hear disagreements), and then at least anyone who hits the same quirks can find them by searching our issues and possibly find workarounds, etc.

tartley commented 1 year ago

We have a release candidate on PyPI containing this PR. Thank you for your contributions! https://pypi.org/project/colorama/0.4.6rc1/

If nobody spots any problems with it, I'll push the final 0.4.6 tomorrow.