batch-filecmdconsolevt100

Make text stay as first line in cmd window


I would like some text to remain at the top of a command window when running a batch script.

I made this gif as a demonstration

enter image description here

The issue is I echo "Compiling Project A", then some commands then call msbuild, so I have no control over the following lines, it's just the output of msbuild. But I would like the "Compiling Project A" to remain as the first line, until "Compiling Project B" reaches the top, at which point it will replace it.

Ok, existing code. I have a function to build based on some arguments,

:buildFunction22
@ECHO off
SET name=%~1
SET compileCondition=%~2
SET buildPath=%~3
SET binPath=%~4
SET buildErrorName=%~5
SET compileSub=%~6
SET s=
IF %compileCondition% EQU 1 (
    IF !compileSub! EQU 0 (
        SET /A compileCurrent=!compileCurrent!+1
    ) ELSE IF !compileSub! EQU 1 (
        SET /A compileCurrent=!compileCurrent!+1
    )
    IF !compileSub! GEQ 1 (
        SET s=.%compileSub%
    )
    ECHO.
    ECHO [95mCompiling !name! (!compileCurrent!!s! / !compileCount!^^^) [0m
    ECHO.
    @TITLE Compiling !name! (!compileCurrent!!s! / !compileCount!^^^)
    ECHO Deleting bin path
    @ECHO OFF
    del !binPath! /f /q
    @ECHO ON
    %msBuildPath22% "%buildPath%" %msBuildOptions%
    SET /A "%~4=!%4!+!ERRORLEVEL!"
    ECHO Completed %name%
    CALL :printElapsedTime
)
EXIT /B 0

Called like this

CALL :buildFunction22 "!nameSmcTherm!" !compileSmcChils! !projectPathSmcTherm! !binPathSmcTherm! buildErrorSmcTherm 0
CALL :buildFunction22 "!nameCszEztTc!" !compileCszChils! !projectPathCszEztTc! !binPathCszEztTc! buildErrorCszEztTc 0
CALL :buildFunction22 "!nameApsLoads!" !compileApsLibrs! !projectPathApsLoads! !binPathApsLoads! buildErrorApsLoads 1
CALL :buildFunction22 "!nameApsPower!" !compileApsLibrs! !projectPathApsPower! !binPathApsPower! buildErrorApsPower 2

This is what the console window looks like now

enter image description here

And I would like to preserve the colors I've used.

Is there a way to make a specific line of colored text to pin to the top of the command window, then to make each following line of this type to replace it and remain there until a following line?

The title command was mentioned in a comment. I already use it but I would like that line to also appear as the first line inside the console window as well

enter image description here


Solution

  • It can be done with defining regions (ESC[<n>r) and using Save Cursor(ESC 7) and Restore Cursor(ESC 8).
    For deleting the rest of a line the ESC[0K can be used.

    For more sequences try a look at Supported Terminal Sequences

    @echo off
    setlocal
    cls
    for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
    
    set "off=%ESC%[m"
    set "red=%ESC%[0;31m"
    set "green=%ESC%[0;32m"
    
    set "EraseToEnd=%ESC%[0K"
    
    REM Create two regions, the first with Line1 to Line2, the other uses the remaining lines
    <nul set /p "=%ESC%[2r"
    
    REM Set cursor to first region and print text
    <nul set /p "=%ESC%[1H%RED%This is the title%OFF%"
    
    REM Set cursor to second region
    <nul set /p "=%ESC%[2H"
    
    for /L %%n in (1 1 70) do echo Text %%n
    ping -n 2 localhost  > NUL
    
    REM Save cursor position
    <nul set /p "=%ESC%7"
    REM Place cursor into region 1 and print text
    <nul set /p "=%ESC%[1H%green%Short title%OFF%%EraseToEnd%"
    REM Restore cursor position (jump into region 2)
    <nul set /p "=%ESC%8"
    
    echo Next Line