Prettify your fish shell

I am using the fish shell these days. Fish stands for Friendly Interactive Shell. I like how programming the shell works and it has some very nice features like syntax and command highlighting you will not find in regular shells.

Note: important note if you are considering to use fish, fish is not a POSIX compliant shell. As such, for shell scripts that will need to work on any system you will still need to know how to script in sh/bash/ksh/etc. I do not consider fish to be a replacement for bash and it should not be the default shell on any system. It’s great as your interactive shell when working the console though.

With that out of the way, using a different or alternate shell can be fun but you probably also want it to look good. Or you want it to look the same or similar to your previous shell because that is what you are used to. As did I. I had a pretty nice prompt setup in bash, so I really wanted my fish shell to look and feel similar. This was the result:

fish prompt for root and regular user

To get this prompt, I created the following fish_prompt.fish under ~/.config/fish/functions.

# This theme is based on Bira theme from oh-my-fish (https://github.com/oh-my-fish/theme-bira)
# This theme also based on the default bash prompt of Kali Linux. (https://www.kali.org/)
# Created, modified and where possible bluntly stolen by throttlemeister.
#
# Bira theme from oh-my-fish listed abouve, based on:
# Theme based on Bira theme from oh-my-zsh: https://github.com/robbyrussell/oh-my-zsh/blob/master/themes/bira.zsh-theme
# Some code stolen from oh-my-fish clearance theme: https://github.com/bpinto/oh-my-fish/blob/master/themes/clearance/

function __user_host
  set fqdn (hostname -f)
  set -l content 
  if [ (id -u) = "0" ];
    echo -n (set_color --bold yellow)\((set_color --bold red)$USER(set_color --bold yellow)💀(set_color --bold red)$fqdn(set_color --bold yellow)\) (set color normal)
  else
    echo -n (set_color --bold blue)\((set_color --bold white)$USER(set_color --bold blue)웃(set_color --bold white)$fqdn(set_color --bold blue)\) (set color normal)
  end
end

function __current_path
  if [ (id -u) = "0" ];
    echo -n (set_color --bold yellow) [(set_color --bold white)(prompt_pwd)(set_color --bold yellow)] (set_color normal)
  else
    echo -n (set_color --bold blue) [(set_color --bold white)(prompt_pwd)(set_color --bold blue)] (set_color normal) 
  end
end

function _git_branch_name
  echo (command git symbolic-ref HEAD 2> /dev/null | sed -e 's|^refs/heads/||')
end

function _git_is_dirty
  echo (command git status -s --ignore-submodules=dirty 2> /dev/null)
end

function __git_status
  if [ (_git_branch_name) ]
    set -l git_branch (_git_branch_name)

    if [ (_git_is_dirty) ]
      set git_info '<'$git_branch"*"'>'
    else
      set git_info '<'$git_branch'>'
    end

    echo -n (set_color yellow) $git_info (set_color normal) 
  end
end

function fish_prompt
  if [ (id -u) = "0" ];
    echo -n (set_color --bold yellow)"╭─"(set_color normal)
  else
    echo -n (set_color --bold blue)"╭─"(set_color normal)
  end
  __user_host
  __current_path
  __git_status
  echo -e ''
  if [ (id -u) = "0" ];
    echo (set_color --bold yellow)"╰─""# "(set_color normal)
  else
    echo (set_color --bold blue)"╰─""\$ "(set_color normal)
  end
end

function fish_right_prompt
  set -l st $status

  if [ $st != 0 ];
    echo (set_color red) ↵ $st  (set_color normal)
  end
  set_color -o 666
  date '+ %T'
  set_color normal
end

Note: the latest version of this script can always be found on my GitHub here.

This prompt was, as the top comments indicate, not all my own and heavily borrowed and modified other prompt and resources. This exercise greatly helped me to understand the fishshell scripting language. This helped me to create some more scripts and functions to make my life in fish easier and simpler.

Mind you, sometimes bash is a lot simpler. For the same prompt, including checks for color support etc, the full bash equivalent for this in my .bashrc is this:

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=yes
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

host=`hostname -f`

if [ "$color_prompt" = yes ]; then
    prompt_color='\[\033[;94m\]'
    info_color='\[\033[0;1m\]'
    prompt_symbol=웃
    p_col='\[\033[1;33m\]'
    if [ "$EUID" -eq 0 ]; then # Change prompt colors for root user
        prompt_color='\[\033[1;33m\]'
        info_color='\[\033[1;31m\]'
        prompt_symbol=💀
        p_col='\[\033[0;1m\]'
    fi
    PS1=$prompt_color'┌──${debian_chroot:+($debian_chroot)──}('$info_color'\u'$p_col'${prompt_symbol}'$info_color'$host'$prompt_color')-[\[\033[0;1m\]\w'$prompt_color']\n'$prompt_color'└─\$\[\033[0m\] '
    # BackTrack red prompt

else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

Where basically only the last bit is what makes the prompt. And even that can be concatenated into a single line if you insert the colors directly instead of setting variables.

Leave a Reply

Your email address will not be published. Required fields are marked *