Try this:
PROMPT_COMMAND='PS1X=$(perl -pl0 -e "s|^${HOME}|~|;s|([^/])[^/]*/|$""1/|g" <<<${PWD})'
or, pure bash:
PROMPT_COMMAND='PS1X=$(p="${PWD#${HOME}}"; [ "${PWD}" != "${p}" ] && printf "~";IFS=/; for q in ${p:1}; do printf /${q:0:1}; done; printf "${q:1}")'
then
PS1='\u@\h ${PS1X} $ '
produces (notice the ~
for ${HOME}
):
rfkrocktk@work-laptop ~/D/P/W/m/s/m/j/c/tkassembled $
I improved my answer thanks to @enzotib's
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
I think the setting you're looking for is in something like
on this line:
(Note that your installation may be different from mine so you might have to search for the file.)
See Powerline quick setup guide. This reddit post might also help. (If you're in a hurry edit that file directly.)
FYI, a simple alternative is the powerline command's
--width
flag which takes max width of the prompt in columns/characters. E.g.powerline --width 40 ...
. This will dynamically resize segments of the prompt as needed which usually means shrinking the path segment.You probably won't know if you like it until you try it. That way you can see exactly how it behaves for different console widths, different paths, with whatever other segments you are displaying, etc.
I couldn't find a straightforward way to set this but looking at the code it seems that setting
COLUMNS=X
(X is desired width) in your environment before invoking thepowerline.sh
startup script will do the trick.