Display only the current directory name (not the full path) in Windows CMD Prompt

In Windows CMD.EXE, I have my prompt string set to $P$G, so, if my current working directory is

C:\Some\long\folder\inner

my prompt is like this:

C:\Some\long\folder\inner>

I want it to show only the last (lowest level) folder name, like this:

inner>

where "inner" is just the name of the inner-most folder, and it should automatically change to the inner-most folder of whichever directory I'm currently inside – equivalent to the capability discussed in Show only current directory name (not full path) on bash prompt.  How can I do this?


Here's a workaround, if you're willing to change your habits a little.

First of all, pick a directory in your PATH that you can write to.  Assuming that you're on your own machine, and you have admin rights, you could use \Windows or \Program Files\something.  But it's probably better to use something like\Users\username\bin.  (Add it to your PATH if you don't already have it there.)

Then create a file there called CH.BAT, or something like that, with the following contents:

@echo off
REM Pass the argument(s) to the real "cd".  If it fails, don't do anything else.
cd %*  ||  exit /b
REM Get our current directory name.
set "dirname=%CD%"
:loop
REM Strip off one directory level -- remove everything through the first \.
set "remove_one=%dirname:*\=%"
REM If there's nothing left, that means dirname ENDS with a \.
REM The only (?) way this can happen is if it is the root directory
REM of a filesystem (partition), e.g., C:\.
REM In this case, set the prompt to the normal thing, C:\>.
if "%remove_one%" == ""          goto exit_loop
REM If "%remove_one%" == "%dirname%", that means we are down to
REM the last directory name (i.e., there are no backslashes left).
if "%remove_one%" == "%dirname%" goto exit_loop
set "dirname=%remove_one%"
REM Keep on removing levels until we get to the bottom.
goto loop

:exit_loop
REM To handle the case where a directory name contains dollar sign(s)
REM (e.g., $P$G), replace each $ with $$ to remove its special meaning
REM in the prompt, and just display a $.
set "dirname=%dirname:$=$$%"
prompt %dirname%$G

And then get into the habit of typing ch instead of cd (or chdir, if you're old enough to remember its original name (which is still supported)).  I believe that the comments explain it fairly well, but, to recapitulate:

  • Invoke cd on the command-line argument(s).  If it fails, exit the script.
  • Use variable substitution (%varname:old=new%) to strip off directory levels.  Loop until there's nothing left to do.  If the current directory is the root (e.g., C:\), then the prompt will be C:\> (since you didn't specify how to handle that case).  If it is something like C:\top\outer\middle\inner, you will get inner>, as requested.
  • As we know, dollar signs are special in the prompt.  But they are legal in directory names.  You can escape dollar signs in the prompt by doubling them; i.e., if you put $$ in the prompt, it will display as $.  So we replace all dollar sign(s) in the directory name with $$ to get them to display correctly.
  • The script hard-codes the current directory name into the prompt string, so, if you subsequently accidentally type cd instead of ch, your prompt will not change.  If this happens, just type ch (or ch .) to set the prompt based on the new current directory.
  • If you ever want to see the full pathname of your current directory, type cd (or echo %CD%).
  • I have tested this with directory names that contain spaces (and dollar signs), but I haven't tested every legal character.  Please let me know if you find a problem.

Naturally, it does no good to name the script CD.BAT or CHDIR.BAT, because CMD.EXE always interprets cd and chdir as the “change directory” built-in command.  You can run such a script by typing its pathname, but obviously that’s infeasible (from a workflow perspective) as an override/replacement for cd.