WAD ANSI <ESC>[K

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
#1
In this situation (note the prompt)
Code:
v:\> echos ^e[%_row;1H^e[K
after pressing "Enter", I see
Code:
v
v:\>
The 'H' sequence does put the cursor at the beginning of the line (tested) but the character there is not erased. There would seem to be no way to erase the entire line.
 
#2
<esc>[nK is the standard sequence to erase within the current line, as follows:
If n is zero (or missing), clear from cursor to the end of the line.
If n is one, clear from cursor to beginning of the line.
If n is two, clear entire line.
Cursor position does not change.
Did not check how much of this is implemented by TCC.
 

rconn

Administrator
Staff member
May 14, 2008
10,096
85
#4
In this situation (note the prompt)
Code:
v:\> echos ^e[%_row;1H^e[K
after pressing "Enter", I see
Code:
v
v:\>
The 'H' sequence does put the cursor at the beginning of the line (tested) but the character there is not erased. There would seem to be no way to erase the entire line.
WAD, and not new -- this goes back 20+ years. The problem is with limitations (i.e., bugs) in a couple of the Windows console APIs. The various workarounds I tried made things worse, so since there was never (until now?) any case where somebody wanted to delete the line and not write something else there in its place, it has never been worth the trouble to deal with it.

The easy workaround is to use something like:

Code:
echos ^e[%_row;1H^e[K^s
 
#5
WAD, and not new -- this goes back 20+ years. The problem is with limitations (i.e., bugs) in a couple of the Windows console APIs. The various workarounds I tried made things worse, so since there was never (until now?) any case where somebody wanted to delete the line and not write something else there in its place, it has never been worth the trouble to deal with it.

The easy workaround is to use something like:

Code:
echos ^e[%_row;1H^e[K^s
I dunno! ANSICON has no problem including the current cursor position in erase_to_end_of_line and it doesn't look like it's working around any bugs.
Code:
            case 0:        // ESC[0K Clear to end of line
                len = Info.srWindow.Right - Info.dwCursorPosition.X + 1;
                FillConsoleOutputCharacter( hConOut, ' ', len,
                    Info.dwCursorPosition,
                    &NumberOfCharsWritten );
                FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
                    Info.dwCursorPosition,
                    &NumberOfCharsWritten );
                return;
FWIW, the ANSICON DLL works after mere injection into a process; it doesn't need its accompanying EXE to do the injecting or to hang around for anything. I put the bare minimum plugin essentials (three do-nothing functions) and turned it into a working plugin in five minutes. ANSICON is pretty heavy-handed, hooking (replacing) basic output functions and several others (like CreateProcess) so it can inject itself into child console processes ... which it seems to do well, even when initially loaded as a plugin.
 
#6
Code:
            case 0:        // ESC[0K Clear to end of line
                len = Info.srWindow.Right - Info.dwCursorPosition.X + 1;
                FillConsoleOutputCharacter( hConOut, ' ', len,
                    Info.dwCursorPosition,
                    &NumberOfCharsWritten );
                FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
                    Info.dwCursorPosition,
                    &NumberOfCharsWritten );
                return;
If anyone is interested ... there's an inconsistency in the way ANSICON handles the 'K' sequence. In the ^e[K code I posted (clear from cursor to EOL) the line is cleared only to the right edge of the window, not necessarily to the right edge of the console screen buffer as is done in the ^e[2K routine (clear entire line). I don't know if this was intentional and emailed the author. Anyway, a minor change to the code above will extend the clearing to the right edge of the buffer, namely,
Code:
len = Info.dwSize.X - Info.dwCursorPosition.X;