Re: Pimp your shell - Debian developer tips?
Hello world,
Like Paul said in his reply, I also have a "bash monstrosity" as a
Bash prompt. I last spent time tweaking it many years ago, so... This
migh reflect what my head was like in the past, not today :-]
I am attaching here the relevant portion of my .bashrc
> Basically the only improvements over lesser distributions we have are:
> * color: it's not for mere looks, but it visually separates output of
> commands between themselves
> * full path from ~ (Fedora has only the last component which sucks)
I do consider this to be very important for me. I'm not inlining it
here, as mine is quite verbose, but the colors are defined in
promptFunc(). I don't really follow what you mean by "full path from
~" — Isn't it what \w produces?
> I would like to add at minimum:
> * current git branch (but not -dirty as that can take ages on large repos
> on slow media -- you want changing directory to be instant)
Yes, I have all this set. I remember it being somewhat slow on large
repos, but I seldom notice it anymore (and on an SSD, it's seldom more
than a couple of seconds on a large Git tree that's not cached). Today
I see this as a heavy number of calls to git, and it always calls git
even if not in a git tree, but... Whatever ☺ This is defined in
parse_git_branch()
> * result of the last command
Yes, I find this to be tremendously useful. I don't absolutely like
the way I handle this (see LAST_RET at the beginning of prompt_func)
> Also, for people who use _many_ terminal tabs while logged on to _many_
> machines like me, I'd also suggest window title. To simplify the code I've
> personally added parsing this sequence to Linux kernel (as of 3.16).
> I also put the title in ALL UPPERCASE if it's a root session, this helps
> while doing admin tasks. There's no space for username so I give only
> machine name.
Makes sense. My window title was meant to reflect the previous command
run. But it reflects the last command that _finished_, amd that's not
always immediate.
I also print my regular username in green, but a root login is
presented in red (not only due to the '$' vs. '#' component).
> > I've read a bit on zsh and powerline and the like, but I am annoyed that
> > all those blog posts are quite superficial and do not mention security,
> > interoperability or performance aspects. Frankly any blog post that
> > recommends cloning random repos or even worse, running wget | sh something
> > gives me chills.
>
> Aye. Just bash in bashrc should be enough, without iffy Python daemons or
> similar stuff.
I agree. The code I'm sharing here is far from optimal, but it's easy
to follow (after... 5-10 years from its last modification.
> As for powerline: it's not in Unicode, and even worse, illegally uses code
> points that have since been assigned for something else. Another version of
> powerline uses PUA characters, but also with ill-chosen codepoints that
> clash with popular assignments (CSUR, MUFI).
I'm not aware of Powerline, so I won't comment on it.
> Another thing I've tried but rejected is writing some stuff on the right
> edge of the screen. This is easy to code and looks good, but causes nasty
> unaligned leftovers if you paste pieces of your console that include the
> prompt, with you not noticing until after the paste is done.
Agree completely.
So, without further ado, my prompt follows:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
# Useful to know where we stand while using different version control systems
parse_git_branch() {
# Yes, temporary, dirty, yada yada yada. Works for me™.
# --exclude-standard does not exist on git <= 1.5
git_opts='--exclude-standard'
branch=`git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
if [ ! -z "$branch" ]
then
clean=`git status --porcelain`
if [ ! -z "$clean" ]
then
branch="${branch}*"
new=`git ls-files -o $git_opts|wc -l`
del=`git ls-files -d $git_opts|wc -l`
mod=$(( `git ls-files -m $git_opts|wc -l` - $del ))
if [ $mod != 0 ]; then branch="${branch}${mod}M"; fi
if [ $new != 0 ]; then branch="${branch}${new}N"; fi
if [ $del != 0 ]; then branch="${branch}${del}D"; fi
fi
fi
echo $branch
}
# set a fancy prompt (non-color, unless we know we "want" color)
promptFunc()
{
LAST_RESULT="$?:$_"
LAST_RET=${LAST_RESULT/:*/}
LAST_CMD=${LAST_RESULT/*:/}
VC_STATUS=`parse_git_branch`
case "$TERM" in
screen*|xterm*|rxvt*)
COLOR_RED="\[\e[31;40m\]"
COLOR_GREEN="\[\e[32;40m\]"
COLOR_YELLOW="\[\e[33;40m\]"
COLOR_BLUE="\[\e[34;40m\]"
COLOR_MAGENTA="\[\e[35;40m\]"
COLOR_CYAN="\[\e[36;40m\]"
COLOR_RED_BOLD="\[\e[31;1m\]"
COLOR_GREEN_BOLD="\[\e[32;1m\]"
COLOR_YELLOW_BOLD="\[\e[33;1m\]"
COLOR_BLUE_BOLD="\[\e[34;1m\]"
COLOR_MAGENTA_BOLD="\[\e[35;1m\]"
COLOR_CYAN_BOLD="\[\e[36;1m\]"
COLOR_NONE="\[\e[0m\]"
TERM_TITLE="\\033]0;"
HOST="${COLOR_NONE}@${COLOR_CYAN}\h"
DIR="${COLOR_YELLOW}『\#』\w"
PROMPT="${COLOR_GREEN_BOLD}\\$ ${COLOR_NONE}"
if test ! -z "$VC_STATUS"
then
VC=" ${COLOR_CYAN}($VC_STATUS)${COLOR_NONE}"
else
VC=
fi
if test `whoami` != "root"
then
USERNAME="${COLOR_GREEN}\u"
else
USERNAME="${COLOR_RED}\u"
fi
if test $LAST_RET -eq 0
then
STATUS="${LAST_RET}"
else
STATUS="${COLOR_RED_BOLD}${LAST_RET}${COLOR_NONE} "
fi
;;
*)
STATUS=$LAST_RET
USERNAME="\u"
HOST="@\h"
COUNT="[\#]"
DIR="\w"
PROMPT="\\$ "
if test ! -z "$VC_STATUS"
then
VC="($VC_STATUS)"
else
VC=
fi
;;
esac
PS1="${STATUS}${VC} ${USERNAME}${HOST}${DIR}${PROMPT}"
# If this is an xterm set the title to user@host:dir
case "$TERM" in
screen*|xterm*|rxvt*)
echo -ne "${TERM_TITLE}(${LAST_CMD}:${LAST_RET}) ${USER}@${HOSTNAME}: ${PWD/$HOME/~}\\007"
;;
esac
}
PROMPT_COMMAND=promptFunc
Reply to: