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 beC:\>
(since you didn't specify how to handle that case). If it is something likeC:\top\outer\middle\inner
, you will getinner>
, 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 ofch
, your prompt will not change. If this happens, just typech
(orch .
) 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
(orecho %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
.