8

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?

laggingreflex
  • 5,035
  • 17
  • 65
  • 96
  • what do you want "inner> PROMPT ??" to print in command instead of c:/>. If you want this then you can easily print it by PROMPT=inner$GPROMPT ?? – akash ujjwal Jan 07 '15 at 15:47
  • edited the question, hope it's clearer now. "inner" is not some particular piece of text that I want to display, it's actually the name of the folder. – laggingreflex Jan 07 '15 at 15:55
  • If there is a simple way then why do you want to go for a typical way, We can simply write it PROMPT=lastdirectory$G and both will give you the same result.Here, lastdirectory is inner. – akash ujjwal Jan 07 '15 at 16:09
  • did you want to make a batch file?? To run this then you can get an idea from here http://stackoverflow.com/questions/1724278/help-writing-dos-script-to-get-get-name-of-the-most-recent-directory-time-creat – akash ujjwal Jan 07 '15 at 16:12
  • 1
    I want it to reflect the current directory *automatically*. I don't see much point of setting it manually. – laggingreflex Jan 07 '15 at 16:24
  • I guess [this](http://www.hanselman.com/blog/ABetterPROMPTForCMDEXEOrCoolPromptEnvironmentVariablesAndANiceTransparentMultiprompt.aspx) should set you on the right track. If you want, I’ll provide an in-depth answer later. – Daniel B Jan 07 '15 at 16:29
  • I want the batch equivalent of this: http://superuser.com/questions/60555/show-only-current-directory-name-not-full-path-on-bash-prompt. Sorry for all the confusion with the "inner" stuff. – laggingreflex Jan 07 '15 at 16:36
  • 1
    I'm afraid there is no possibility I know about to accomplish that unless you hack into `cmd.exe`; you can display the current drive by `prompt $N$G` but not the pure name of the current working directory; you could however append a line-break to the standard prompt like `prompt $P$G$_` if that helps... – aschipfl Jun 27 '17 at 12:34

1 Answers1

3

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.

  • Very clever and useful answer. Lots more fun things to add to that final prompt call [here](https://superuser.com/a/1049058/114388). – ruffin Jun 12 '23 at 19:53