[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Pimp your shell - Debian developer tips?



On Wed, May 27, 2020 at 10:06:29PM +0300, Otto Kekäläinen wrote:
> Hello!
> 
> Do we have Debian devs here who have pimped their shell heavily with custom
> prompts, colors, command line fonts, shell window title hacks, perhaps
> using zsh etc? Have you written blogs about you experiences, can you share
> some good reads (with screenshots) of what you have done?

I wanted to overhaul our default prompt -- but ENOTUITS.  It's primitive,
and lacks basic goodies.

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 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)
* result of the last command

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.

Another thing is machine name in /etc/issue.  This might be counterintuitive
as it's used only for local sessions -- but the console ignores these
sequences so the title shows up only when accessed via serial.

> 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.

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).

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.

> Some might react that bells and whistles is useless and real unix beards
> only run plain bash, but I think that good text prompts have a potential to
> increase productivity.

Alas, zsh is a problem if you use many machines and many chroots (which also
want to be minimal), or machines not under your control.  Thus, bash is the
king because it is always there.  And it _can_ do everything that
powerlevel9k and such toys do, without performance problems.



Thus: my /etc/issue is:
\e]0;⭍\n\e\\Debian GNU/Linux \n \l

\n unobviously means the machine's mode, ⭍ is my marker for serial consoles.
These sequences before the word "Debian" are invisible and go only to a
window title if there's one.

As for my bashrc, some snippets:

# ! has been long obsoleted by ^R and it can cause nasty surprises.
set +H

# We want less goodness.
[ -x /usr/bin/lesspipe ] && eval "$(lesspipe)"

if [ -x /usr/bin/git ]
  then
    git_branch='$(parse_git_branch)'
    function parse_git_branch
    {
        git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
    }
fi

PROMPT_COMMAND='if ((ERROR=$?))
  then
    if [ "$ERROR" -gt 128 ]
      then
        ERRORSIG="$(kill -l $(($ERROR-128)) 2>/dev/null)"
        [ -n "$ERRORSIG" ] && ERROR="$ERRORSIG"
    fi
    PROMPT_ERRORC="0;33;1;41"
    PROMPT_ERROR="$ERROR"
  else PROMPT_ERROR=""
fi'

[ -n "$SCHROOT_CHROOT_NAME" ] && export PS1="\[\e[0;1m\]{$SCHROOT_CHROOT_NAME}\[\e[0m\]@$PS1"

# Compat with Hurd console and ancient bash.
case "$TERM" in
hurd)
    ;;
*)
    if [ "$UID" == "0" ]
      then
        RH=`echo "$HOSTNAME"|tr a-z A-Z`
    fi
    if [ -n "${BASH_VERSION/#4.2.*/}" ]
      then
        PROMPT_COMMAND+=';echo -ne "\e]0;${SCHROOT_CHROOT_NAME:+{$SCHROOT_CHROOT_NAME\} }${RH:-$HOSTNAME}: ${PWD/#$HOME/\~}\e\\"'
      else
        PROMPT_COMMAND+=';echo -ne "\e]0;${SCHROOT_CHROOT_NAME:+{$SCHROOT_CHROOT_NAME\} }${RH:-$HOSTNAME}: ${PWD/#$HOME/~}\e\\"'
    fi
    ;;
esac

# Per-hostname prompts.
case "$HOSTNAME" in
  umbar)        PSC1='\e[0;36m';;
  moria|khazad-dum)
                PSC1='\e[0;32m';;
  dimrill|baranzibar|redhorn|zirak-zigil|zirakzigil|silvertine|bundushathur|azanulbizar|mirrormere)
                PSC1='\e[0;32m' PSH=1;;
  andunie)      PSC1='\e[0;38;5;107m' PSC2='\e[0;1;38;5;193m';;
  harlond)      PSC1='\e[0;1;32m' PSC2='\e[0;32m';;
  sirius)       PSC1='\e[0;38;5;137m' PSC2='\e[0;38;5;223m';;
  # ...
  *)            PSC1='\e[0;1;31m' PSC2='\e[0;31m' PSH=1;;
esac
export PS1="${PSH:+\\[$PSC1\\]\\h}\\[${PSC2:-$PSC1\\e[1m}\\]${PSH:+:}[\\[$PSC1\\]\\w\\[${PSC2:-\\e[1m}\\]]\\[\\e[0;1;33m\\]$git_branch\\[\e[\${PROMPT_ERRORC}m\\]\$PROMPT_ERROR\\[\\e[0;1;33m\\]\\$\\[\e[?2004l\\e[0m\\] "
export PS2='\[\e[1;33m\]>\[\e[0m\] '
unset git_branch PSC1 PSC2 PSH


# Note: in PS1/PS2, you need to wrap any non-printables such as color codes
# in \e[ \e] so bash knows how long the prompt is.


Meow!
-- 
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ in the beginning was the boot and root floppies and they were good.
⢿⡄⠘⠷⠚⠋⠀                                       -- <willmore> on #linux-sunxi
⠈⠳⣄⠀⠀⠀⠀


Reply to: