OK Start with the reasons you see:
I checked your code and noticed that this only happened when the window was resized. When the window remained at rest, it would write out a, and after pressing enter they would rewrite them with b (I assume that the expected behavior).
What seems to be happening is that when you partially resize the window, the row indices change, so at the next iteration you cannot trust the same coordinates when you call move_cursor ().
Interestingly, when you resize the window, word wrap pushes the text in front of the cursor. I assume this is part of the terminal emulator code (since we almost always want to keep the focus on the cursor, and if the cursor is at the bottom of the screen, resizing can obscure it beyond the window height if the wrap word pushed it down).
You will notice that after resizing, when you press the enter button, only two lines (and not all 3) remain visible. Here's what happens:
First, start with the initial output. (line numbers added for clarity)
1 2 3 4 5 aaaaaaaaaaaaaaa\n 6 aaaaaaaaaaaaaaa\n 7 aaaaaaaaaaaaaaa\n 8
Please note that at the end of each of these lines there is a new line symbol (therefore, your cursor appears below the last, despite the fact that you have not moved the cursor again)
When you reduce the window by one character, this happens:
1 2 aaaaaaaaaaaaaa 3 a\n 4 aaaaaaaaaaaaaa 5 a\n 6 aaaaaaaaaaaaaa 7 a\n 8
You’ll notice what I mean by pushing the text up.
Now, when you press enter and your loop repeats, the cursor goes to line 5 col 1 (as indicated by your code) and is placed directly above the last a of the second line. When he starts writing b, he overwrites the last a of the second line with b and the next line.
1 2 aaaaaaaaaaaaaa 3 a\n 4 aaaaaaaaaaaaaa 5 bbbbbbbbbbbbbb\n 6 bbbbbbbbbbbbbb 7 bbbbbbbbbbbbbb\n 8
It is important to note that this also overwrites the newline at the end of the second line. This means that now there is no new line separating the second line a and the first line b, so when you expand the window: they are displayed as one line.
1 2 3 4 5 aaaaaaaaaaaaaaa\n 6 aaaaaaaaaaaaaabbbbbbbbbbbbbb\n 7 bbbbbbbbbbbbbbbbbbbbbbbbbbbb\n 8
I'm not quite sure why this second line of b is also concatenated, but it seems to have something to do with the fact that the line in which the first is overwritten now skips its own newline completion, however, this is just an assumption.
The reason you get two line break characters if you try to squeeze the window with another character is because you are now trimming two halves of the same line of text, which means that one clicks on the other, causing two characters instead of one at the end.
For example: in these test windows, which I showed, the width starts with 15 characters, then I reduce it to 14 and print the letter b. There is another line with a length of 15 characters, and now a line of 14 a and 14 b, which is wrapped with lines with 14 characters. The same (for some reason) applies to the last two lines of b (they are one line of 28 characters wrapped in 14). Therefore, when you shorten the window with another character (up to 13): the first line of 15 a now has two trailing characters (15 - 13 = 2); the next line of 28 characters should now be in the 13-character window (28/13 = 2 R2), and the same applies to the last b.
0 aaaaaaaaaaaaa 1 aa\n 2 aaaaaaaaaaaaa 3 abbbbbbbbbbbb 4 bb\n 5 bbbbbbbbbbbbb 6 bbbbbbbbbbbbb 7 bb\n 8
Why does this work as follows:
Such things are the difficulty that you encounter when you try to run your program in another program, which has the right to move the text at its discretion. If you resize, your indexes become unreliable. Your terminal emulator tries to process the rearrangement for you and presses the text in front of your tooltip (which is fixed on line 8) up and down in the scroll bar so that you can always see your active invitation.
Rows and columns are something defined by a terminal / terminal emulator, and it should interpret their location accordingly. When appropriate escape sequences are specified, it is a terminal that interprets them accordingly for proper display.
Please note that some terminals behave differently, and an emulated terminal often uses a parameter to change which terminal it simulates, which can also affect the response of certain control sequences. This is why the UNIX environment usually has a parameter or environment variable ($ TERM) that tells it what type of terminal it is communicating with, so that it knows which control sequences to send.
Most terminals use standard ANSI compatible escape sequences or DEC VT hardware-based terminal systems.
In the settings of Terminal.app in the section "Settings" → "Settings"> "Advanced" you can see (or change) what type of terminal is emulated by your window in the drop-down menu next to "Declare terminal as:"
How to overcome this:
You may be able to reduce this by keeping the last known width and checking if the change has occurred. In this case, you can change the cursor logic to compensate for the changes.
Alternatively, you can use escape sequences designed to relative move the cursor (as opposed to absolute) to avoid accidentally overwriting previous lines after resizing. It is also possible to save and restore specific cursor locations using only escape sequences.
Esc[<value>A Up Esc[<value>B Down Esc[<value>C Forward Esc[<value>D Backward Esc[s Save Current Position Esc[u Restore Last Saved Position Esc[K Erase from cursor position to end of line
However, you have no real guarantee that all terminal emulators will deal with window resizing in the same way (which is not part of any terminal standard, AFAIK) or that it will not change in the future. If you are hoping to create a real terminal emulator, I suggest that you first get the customization of your GUI so that you can control all the resizing logic.
However, if you want to run a terminal emulator window and deal with window size reduction for this command-line utility that you are writing. I would suggest looking at the curses library for python. This is the kind of functionality that is used by all programs that support windows that I know from the top of my head (vim, yum, irssi), and can deal with such changes. Although I personally have no experience using it.
It is available for python through the curses module.
(and please, if you plan to redistribute your program, consider writing it in Python 3. Do this for children: D)
Resources:
These links may be helpful:
I hope this helps!