A minor variant on rojo's excellent answer. Instead of backspacing over the dots, this uses a carriage return (without line-feed) to output the prompt, the dots, CR and the prompt again:
@echo off
setlocal enabledelayedexpansion
REM From https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"
set "DOTS=.................................................."
set "PROMPT=Fill in the blank: "
set /p "response=%PROMPT%%DOTS%!\r!%PROMPT%"
echo You entered "%response%".
Although, as rojo notes, the use of enabledelayedexpansion
may cause problems if you use exclamation marks elsewhere. One solution would be to put this code in a "subroutine" (where I additionally pass in the variable to contain the response and the prompt):
@echo off
setlocal
call :getString answer "Fill in the blank: "
echo You entered "%answer%".
goto :eof
:getString
setlocal enabledelayedexpansion
REM From https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"
set "DOTS=.................................................."
set "PROMPT=%~2"
set /p "response=%PROMPT%%DOTS%!\r!%PROMPT%"
endlocal && set %1=%response%
goto :eof
The last line (endlocal && ...
) allows us to end locality (and delayed-expansion) while still using the value of an environment variable defined within that block).
(I was working on an alternative solution using the (now not standard, but easily available) choice
command, to process the input character-by-character, but it doesn't look like it was going anywhere).