I have command prompt in tcsh that shows the current working directory. The problem is that the command prompt becomes very big once I am in a deep hierarchy of folders. How do I set the command prompt to show, let's say, only the last 3 directory names?
Setting up command promt in tcsh to show only last 3 working directory instead of complete path
prompttcsh
Related Solutions
Well, if an external script is an acceptable solution, you could do something like this:
#!/usr/bin/env perl
use Cwd;
my $cwd=getcwd();
$cwd =~ /$ENV{HOME}/ ?
print "$cwd % " :
print "%{\033[1;31m%}CAREFUL\\\!%{\033[0m%} $cwd % ";
Save that somewhere in your $PATH
as make_prompt.pl
and make it executable. And then, in your ~/.tcshrc
:
alias precmd 'set prompt="`make_prompt.pl`"'
This will result in:
You can also add more conditions to change the prompt in specific ways in different directories:
#!/usr/bin/env perl
use Cwd;
my $cwd=getcwd();
## Here are some colors to choose from
my $red="%{\033[1;31m%}";
my $green="%{\033[0;32m%}";
my $yellow="%{\033[1;33m%}";
my $blue="%{\033[1;34m%}";
my $magenta="%{\033[1;35m%}";
my $cyan="%{\033[1;36m%}";
my $white="%{\033[0;37m%}";
## This resets the color, you need it after each color command
my $end="%{\033[0m%}";
## If you are in $HOME or one of its sub dirs, print a green prompt
if($cwd =~ /$ENV{HOME}/){
print "$green$cwd$end % ";
}
## If you are in /usr or one of its sub dirs, print a red prompt
elsif($cwd=~ /\/usr/){
print "$red$cwd$end % ";
}
## If you are in /etc or one of its sub dirs, print a blue prompt
elsif($cwd=~/\/etc/){
print "$blue$cwd$end % ";
}
## If you're in /root. As you can see, colors can be combined
elsif($cwd=~/\/root/){
print $red . "OY\\! You're not allowed in here\\!" .
$end . $magenta . " $cwd$end % ";
}
## For wherever else, just print a plain prompt
else {
print "$cwd % ";
}
Bash's prompt control features are rather static. If you want more control, you can include variables in your prompt; make sure you haven't turned off the promptvars
option.
PS1='${PWD#"${PWD%/*/*}/"} \$ '
Note the single quotes: the variable expansions must happen at the time the prompt is displayed, not at the time the PS1
variable is defined.
If you want more control over what is displayed, you can use command substitutions. For example, the snippet above loses the ~
abbreviation for the home directory.
PS1='$(case $PWD in
$HOME) HPWD="~";;
$HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
$HOME/*) HPWD="~/${PWD##*/}";;
/*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
*) HPWD="$PWD";;
esac; printf %s "$HPWD") \$ '
This code is rather cumbersome, so instead of sticking it into the PS1
variable, you can use the PROMPT_COMMAND
variable to run code to set HPWD
and then use that in your prompt.
PROMPT_COMMAND='case $PWD in
$HOME) HPWD="~";;
$HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
$HOME/*) HPWD="~/${PWD##*/}";;
/*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
*) HPWD="$PWD";;
esac'
PS1='$HPWD \$'
Since the shortened prompt only changed on a directory change, you don't need to recalculate it each time a prompt is displayed. Bash doesn't provide a hook that runs on a current directory change, but you can simulate it by overriding cd
and its cousins.
cd () { builtin cd "$@" && chpwd; }
pushd () { builtin pushd "$@" && chpwd; }
popd () { builtin popd "$@" && chpwd; }
chpwd () {
case $PWD in
$HOME) HPWD="~";;
$HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
$HOME/*) HPWD="~/${PWD##*/}";;
/*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
*) HPWD="$PWD";;
esac
}
PS1='$HPWD \$'
Note that you don't need to, and should not, export PS1
, since it's a shell setting, not an environment variable. A bash PS1
setting wouldn't be understood by other shells.
P.S. If you want a nice interactive shell experience, switch to zsh, where all of these (prompt %
expansions largely encompassing tcsh's, chpwd
, etc.) are native features.
PS1='%2~ %# '
Best Answer
According to this question, you can achieve that by setting:
This should show you last three directory names of your CWD, followed by a space and a percent sign.