When the terminal width is sufficient to accommodate the length of the third line of the program output, it works as expected, but when the width is insufficient, problems occur.
Specifically, when using Termux on Android with the smartphone held vertically, the width is insufficient for the text, and it is treated as if a different line has been added, resulting in incomplete line deletion using ANSIescape.
When I searched for a solution to this problem, I found a way to know the cursor position, but it seemed very tricky and I couldn’t process it and use it well.
This is how the keyword x1b[6n appears.
Therefore, since the terminal width can be obtained relatively easily, I am thinking of calculating the number of times that width is exceeded (taking into account east asian width characters), and then using ANSIescape to move the cursor and delete the corresponding number of times.
I would like to know if there are any other clever solutions, such as changing the behavior depending on the terminal width so that it is not treated as a line break, and I am asking this question.
import time
# ANSI escape
MOVU = "\033[1A"
CRTN = "\033[2K"
# test text
sampletx = "text line 1 start\ntext line second here\nlong line long long line test one long line test two long line hello world here is long line third line\nhello\n"
def fspinner(rndrstr):
"""my spinner"""
# List rndrstr by line break
efline = rndrstr.splitlines()
# line in operation
cur = 0
lgl = len(efline[cur])
hdpos = 0
# vislist = " " * lgl # it was same id all
vislist = [" " for _ in range(lgl)]
print(f"{len(vislist)=}")
for list in efline:
lgl = len(efline[cur])
vislist = [" " for _ in range(lgl)]
for list in efline[cur]:
# Character judgment and put in the list.
if efline[cur][hdpos] == " ":
vislist[hdpos] = "░" # white space transform to symbol for testing
else:
vislist[hdpos] = efline[cur][hdpos]
# print(f"{vislist=}")
hdpos += 1
# Display
print(f'{"".join(vislist)}')
time.sleep(0.015)
# and erase
print(MOVU+CRTN, end="")
print(f"{''.join(vislist)}")
cur += 1
hdpos = 0
fspinner(sampletx)
To reproduce the abnormality on a computer, please extend the third line, which says “long long line” , as it too short.
So I think that would recreate the unintended output of the pyramid…
Can you take a screenshot of the problem on your phone and post that image here? That may help someone visualize the problem. Some people are just more visual.
If you hold it vertically, it will look like this. Line breaks are inserted at the width of the screen,(P.S. I was wrong, it seems that the vislist exceeds the screen width including whitespace every time)
so I think this is because the behavior of the ANSIescape cursor moving up one line and the carriage return (deleting a line) is different from other screens and becomes strange.
When I copied it, it looked different from the screen. I will prepare the image. Please wait. It is very long vertically.
In reality my code, it is get_east_asian_width_count(vislist) // tsize[0]
Increase the number of times to delete lines depending on the number of times.
for i in range(wad+1):
print(MOVU+CRTN, end="")
I’m starting to think that this is fine now.
I wondered why line breaks were added just by holding the smartphone vertically, but they are actually there
and I think ANSI escape just trying to work correctly. Yes, I am now convinced