TYPE resets console tab settings

May 20, 2008
Syracuse, NY, USA
Windows 10's enhanced console allows setting the tab stops. I've suggested that TCC v25 give us some interface to this mechanism and I've been experimenting with it myself. I find that many things will cause the console's tabs to revert to the default every 8 spaces ... running any console EXE in the same console ... even running notepad (by name only, but not with START). The most surprising one (because it's internal) is TYPE. See below how the tabs are set to 4 spaces and how they're reset to 8 spaces when I type the file. The file contains "a<tab>b<tab>c ...".

Rex, can you shed some light on why the tab settings change in this and other circumstances. FWIW, I'm setting the tabs using a handle obtained with CreateFile(L"CONOUT$"). I'm using WriteConsole() with ANSI escape sequences to do it and subsequently closing the handle.
Last edited:
May 20, 2008
Syracuse, NY, USA
If you have ANSI enabled, TYPE will be calling SetConsoleMode.
Does it change any settings? Is it expected to clobber tabs set with ANSI? What about notepad? Does issuing "notepad" at the prompt trigger a call to SetConsoleMode ... and (again) is that expected to clobber the tab settings?


Staff member
May 14, 2008
Does it change any settings? Is it expected to clobber tabs set with ANSI? What about notepad? Does issuing "notepad" at the prompt trigger a call to SetConsoleMode ... and (again) is that expected to clobber the tab settings?

TYPE does a GetConsoleMode to save the original settings, then calls SetConsoleMode to restore them after it's done. There is no flag for ANSI tabs.

Executing Notepad will not trigger a call to SetConsoleMode.

As to all the rest of your questions -- I have no idea. Talk to Microsoft; it's their undocumented feature.
May 20, 2008
Syracuse, NY, USA
The escape sequences are documented in Console Virtual Terminal Sequences - Windows Console

That document also has sketchy info on enabling/disabling VT processing with SetConsoleMode().

When, from the plugin function that set the tabs, I use CreateProcess() to run notepad, the tabs settings are not clobbered.

As far as I can tell, SetConsoleMode is called on every keystroke and with every issuance of the prompt. Issuing the command "notepad" causes a few additional calls to SetConsoleMode (with a different value (0x3 vs. 0xe7) for mode). Disabling/re-enabling VT processing may well clobber the tab settings.
May 20, 2008
Syracuse, NY, USA
Well, issuing "notepad" clobbers the tab settings. I don't know enough about it to say more now. After 30 years with tabs every 8 characters, I'm eager to see what's possible. Maybe TCC will wind up helping.
May 20, 2008
Syracuse, NY, USA
TCC does not remove the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag. It sets it at startup if you are running Windows 10 & have selected ANSI.
Do you think it could NOT do that in pipe and transient instances? In those cases, it's already running in a console with ENABLE_VIRTUAL_TERMINAL_PROCESSING. Transient instances clobber the tab settings (even though I set them to every 4th column in TCSTART.BTM).

May 20, 2008
Syracuse, NY, USA
Maybe for child pipe processes. It would be a bad idea for transient instances.
More on this, mostly just FYI and FWIW.

I read about the DWORD value HKCU\Console\VirtualTerminalLevel. When it exists and equals 1, ENABLE_VIRTUAL_TERMINAL_PROCESSING is the default (tested it with my own EXE). But even with VirtualTerminalLevel = 1, ENABLE_VIRTUAL_TERMINAL_PROCESSING is off at InitializePlugin time. So I figure TCC is turning it off earlier, possibly inadvertantly (and back on later). That may be what's clobbering the tab settings.
May 20, 2008
Syracuse, NY, USA
ENABLE_VIRTUAL_TERMINAL_PROCESSING is always disabled when a new console session starts.

That doesn't seem to be true. Using this code in a test app.

INT wmain(INT argc, WCHAR **argv)
    DWORD dwMode;
    GetConsoleMode(hConOut, &dwMode);
    wprintf(L"Mode: 0x%lX\n", dwMode);
    return 0;

and starting the test app with a double-click in explorer I get:

0x3 when HKCU\Console\VirtualTerminalLevel=0, and
0x7 when HKCU\Console\VirtualTerminalLevel=1.

Since ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4, I reckon the registry setting really does control the default startup mode.

I have HKCU\Console\VirtualTerminalLevel=1. And I have this code in InitializePlugin (to set tabs at 1, 5, 9 ...).

Starting TCC from explorer I get garbage.


If the plugin first does

    GetConsoleMode(con.h, &dwMode);
    SetConsoleMode(con.h, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

I get tabs at 1, 5, 9, ... as desired.

That's why I figure TCC has turned off ENABLE_VIRTUAL_TERMINAL_PROCESSING before InitializePlugin.
May 20, 2008
Syracuse, NY, USA
This code was supposed to be in my last post as text but the forum wouldn't accept it. So I'm trying again.

    if ( g.bInteractive )
        INT iTabWidth = 4;                                // or maybe something from INI file
        WCHAR szSequence[16];

        emit(L"\x1b[?25l\x1b[s\x1b[3g");                // cursor: off, save its position; clear all tabs


        for ( INT i = 1; i <= con.csbi.dwSize.X; i += iTabWidth )
            wsprintf(szSequence, L"\x1b[%dG\x1bH", i);    // cursor to column i and set a tabstop

        emit(L"\x1b[u\x1b[?25h");                        // restore cursor pos and turn it back on
Similar threads
Thread starter Title Forum Replies Date
Charles Dye TYPE /X double-spacing long lines Support 2
Joe Caverly Using TYPE with non-English text Support 22
vefatica TYPE behaving randomly Support 10
vefatica Garbage from TYPE Support 2
Joe Caverly Get a variable type Support 2
Joe Caverly v24 TYPE Re-direction Support 4
vefatica TYPE goes crazy with no-BOM Unicode file Support 7
J Piping ANSI control sequences through 'type' Support 4
nickles How to? Follow a JUNCTION type directory link Support 9
S International characters - TYPE vs %@LINE function Support 5
thedave WAD Unable to type various characters using Windows 8's onscreen keyboard Support 7
vefatica Fixed TYPE http://... incomplete data Support 40
Phileosophos Documentation TPIPE /string type code confusion Support 4
S WAD %_do_errors does not report errors when loop control variable type is not directory entry Support 1
vefatica TYPE beeping? Support 12
Charles Dye TYPE /P behaves strangely with piped/redirected input Support 0
vefatica LIST and TYPE show UTF8 BOM Support 4
vefatica TYPE, Unicode, installer Support 10
Charles Dye Fixed TYPE /X reports FF for all values >= 80h Support 6
M More SafeChars type issues... Support 4
Charles Dye Strange output, here-doc redirection, TYPE, //UnicodeOutput=Yes Support 6
Roedy MIME type for *.btm ? Support 1
S TYPE command issue Support 12
vefatica TYPE /X and Unicode files? Support 0
dcantor LIST /X and TYPE /X give different results Support 20
Juanma Barranquero App Paths of type REG_EXPAND_SZ Support 2
E colorization outside of type Support 7
p.f.moore Documentation tweak for TYPE Support 5
vefatica Console not redrawn in BTM or with multiple commands Support 4
vefatica ShutdownPlugin not called when I X the console? (just curious) Support 4
vefatica Console popup windows don't work correctly Support 0
vefatica Cancelling selection in the console? Support 7
G Console exe up / down history Support 8
vefatica Console cursor height in Win 10 Support 3
vefatica BTM, elevated, console window caption? Support 4
vefatica TCEXIT not executed if I X the console Support 4
vefatica Undesired scrolling in Windows 10 enhanced console. Support 2
L WAD In console, tabs are rendered with non-uniform tab-stop spacing Support 16
P No linefeed on last line of console window Support 2
fishman@panix.com TCC v22 & the Windows 10 Console Support 5
C TCMD not hiding the console Support 1
jaltman tcmd 21.0.19 win10 16179 console window loses content Support 2
vefatica Console output slower that before Support 8
L Fixed console line length in Take Command 19? Support 3
P Color directories in Win10 build 10586 console Support 11
Mordachai How to capture all console output from a TCMD session? Support 4
I Windows 10 console does not allow alt-F4 alias to complete Support 1
M Console-Mode (*.exe) works in TCC, not in TCMD Support 2
vefatica ON CLOSE, GOTO, and X-ing the console Support 5
I Attach console Support 3

Similar threads