Declined Tab width in Win 10

May 20, 2008
10,497
77
Syracuse, NY, USA
Windows 10's enhanced console supports setting tab positions. It's a bit cumbersome. Maybe the next TCC will wrap up a few simple tab-setting/clearing actions into a command. Here's a bit of fooling around with Win 10's ANSI. I don't know if there are console API functions to do this sort of thing.
2279
 
May 20, 2008
10,497
77
Syracuse, NY, USA
FWIW, Here's a TABWIDTH.BTM.
Code:
set width=%1
echos ^e[1G^e[s^e[3g
do i=1 to %@eval[%_columns\%width]
        echos ^eH%@repeat[%@char[160],%width]
enddo
echos ^eH^e[u
and a plugin version (not exactly the same).
Code:
INT WINAPI TABWIDTH(LPWSTR psz)
{
    DWORD w = wcstoul(psz, NULL, 10);
    if (w < 2 || wcsstr(psz, L"/?"))
    {
        Printf(L"%s\r\n", item[itabwidth].Help);
        return 0;
    }
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    COORD dwCursor = { 0, csbi.dwCursorPosition.Y };
    // cursor to BOL, save cursor position, clear tabs (except at BOL and EOL)
    Printf(L"\x1b[G\x1b[s\x1b[3g"); 
    for (dwCursor.X = 0; dwCursor.X < csbi.dwSize.X; dwCursor.X += w)
    {
        SetConsoleCursorPosition(STD_OUT, dwCursor);
        Printf(L"\x1bH"); // set a tab position
    }
    Printf(L"\x1b[u"); // restore cursor position.
    return 0;
}
They're crude, but either will produce this in my Win 10 enhanced console.

2284
 
May 20, 2008
10,497
77
Syracuse, NY, USA
Here's more functionality and plugin code that does it.
2287


Code:
INT WINAPI TABSAT(LPWSTR psz)
{
    INT argc;
    WCHAR szUty[16], **argv = GetArgs(psz, &argc); // CommandLineToArgvW with dummy argv[0]
    DWORD dwWritten;
    WORD wWidth = 0;
    BOOL bUseWidth;

    if ( argc < 3 || !(bUseWidth = !lstrcmpi(argv[1], L"/w")) && lstrcmpi(argv[1], L"/c") || !(wWidth = (WORD) _wtoi(argv[2])) )
    {
        Printf(L"%s\r\n", item[itabsat].Help);
        goto byebye;
    }

    HANDLE hConOut = OpenConOut(); // L"CONOUT$"
    // cursor to BOL, save cursor position, clear tabs (except at BOL and EOL)
    WriteConsole(hConOut, L"\x1b[G\x1b[s\x1b[3g", 10, &dwWritten, NULL);

    if ( bUseWidth ) /* use tab width */
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        GetConsoleScreenBufferInfo(hConOut, &csbi);
        wsprintf(szUty, L"\x1b[%uC\x1bH", wWidth);  // cursor forward w columns and set tab
        for (WORD i = 1; i <= csbi.dwSize.X / wWidth; i += 1)
            WriteConsole(hConOut, szUty, lstrlen(szUty), &dwWritten, NULL);
    }
    else /* use specified columns */
    {
        for (INT i = 2; i < argc; i++)
        {
            wsprintf(szUty, L"\x1b[%uG\x1bH", (WORD)_wtoi(argv[i])); // cursor to named column and set tab
            WriteConsole(hConOut, szUty, lstrlen(szUty), &dwWritten, NULL);
        }
    }

    /* restore cursor position */
    WriteConsole(hConOut, L"\x1b[u", 3, &dwWritten, NULL);

    CloseHandle(hConOut);
    byebye :
    LocalFree(argv);
    return 0;
}
 
May 20, 2008
10,497
77
Syracuse, NY, USA
While that's all fine and dandy, I just discovered that such settings only last until another EXE is run in the same console (including another TCC, say in a pipe). When that happens, the tabs revert to the default every 8 characters and they stay there ... bummer!

In fact the tabs settings revert if I run notepad, but not if I START notepad (see below). Does anyone know what might be happening?
2289