Fish Shell
I am using Bash as my shell for as long as I am using Linux.
Over the years I had customized it quite a lot by making my .bashrc
load a whole bunch of scripts from a ~/.bashrc.d
directory. It worked fine but of course there is only so much you can do with simple aliases and function definitions…
I saw many of my friends switch to zsh, but every time I looked into it I was overwhelmed by its configuration and I wasn't convinced by the “just use oh-my-zsh” argument.
When I stumbled on Fish I was intrigued by it's features and easy configuration approach. I gave it a few halfhearted tries in the past but having to port over my collection of accumulated Bash configs was always holding me back from switching for reals.
This weekend I finally got around to properly switch to Fish. Fish already has the same concept for customizing that I used in Bash by providing a ~/.config/fish/conf.d
directory from which any .fish
file is loaded automatically. So I spent some time to port over by bash scripts.
Initially I used ChatGPT to help me with the porting, but after a few scripts I quickly got the knack of it myself. It's different but not overly complicated.
Prompt Setup
I spent most of the time fiddling with my prompt setup. Here's what I got so far:
The left hand side shows:
- The time when the prompt was shown. I sometimes uses this when I have to book my time at work and need to figure out when I started on a particular task.
- The current user. Normally in green, but highlighted in red when I'm root
- The hostname. White for the local machine, highlighted in magenta when on a remote host (this of course depends on me being logged into a machine with my fish setup)
- The current path. Only the last three segments are shown in full, if it gets longer the initial segments are abbreviated.
- The last non-zero return code is shown in red
Fish also supports a right hand side prompt. I configured this to show:
- The currently activated Python virtual environment (if any)
- The current git branch and dirty status (if any)
Finally there's a greeting message. Here I simply highlight if I working local or remotely again. I might add other info here later.
The code for all of this wasn't too terrible to come up with.
- .config/fish/conf.d/30-prompt.fish
set -g VIRTUAL_ENV_DISABLE_PROMPT true set -g __fish_git_prompt_showdirtystate true set -g __fish_git_prompt_showcolorhints true set -g __fish_git_prompt_showupstream auto set -g __fish_git_prompt_char_stateseparator '' function fish_prompt --description 'Write out the prompt' set -l last_pipestatus $pipestatus set -lx __fish_last_status $status # Export for __fish_print_pipestatus. set -l normal (set_color normal) set -q fish_color_status or set -g fish_color_status red # Get the current time in HHMM format set -l current_time (date '+%H%M') set -l time_color (set_color brblue) # Highlight root with bright red background set -l suffix '>' set -l user_color (set_color $fish_color_user) if fish_is_root_user set user_color $normal (set_color -b brred) set suffix '#' end # On remote connections color the host name set -l host_color $normal if set -q SSH_TTY set host_color $normal (set_color -b magenta) end # Write pipestatus set -l bold_flag --bold set -q __fish_prompt_status_generation; or set -g __fish_prompt_status_generation $status_generation if test $__fish_prompt_status_generation = $status_generation set bold_flag end set __fish_prompt_status_generation $status_generation set -l status_color (set_color $fish_color_status) set -l statusb_color (set_color $bold_flag $fish_color_status) set -l prompt_status (__fish_print_pipestatus "[" "]" "|" "$status_color" "$statusb_color" $last_pipestatus) echo -n -s $time_color $current_time $normal echo -n -s $user_color (whoami) $host_color '@' (prompt_hostname) ':' $normal echo -n -s (set_color $fish_color_cwd) (prompt_pwd --full-length-dirs 3) $normal echo -n -s $prompt_status echo -n -s $suffix " " end function fish_right_prompt --description 'Right side prompt for Python venv and Git' set -l normal (set_color normal) # Show active Python virtual environment, if any if set -q VIRTUAL_ENV set -l venv (basename "$VIRTUAL_ENV") set -l venv_color (set_color cyan) echo -n -s "($venv_color$venv$normal)" end # Show Git branch and status set -l git_info (fish_vcs_prompt) if test -n "$git_info" echo -n -s "$git_info" end end function fish_greeting set -l normal (set_color normal) set -l greeting_color (set_color cyan) set -l login_type "💻 Local session on" # Detect if logged in via SSH if set -q SSH_TTY set greeting_color (set_color brmagenta) set login_type "🔮 SSH session on" end # Get system information set -l host (prompt_hostname) # Get system hostname # Display greeting with system information echo -e "$greeting_color$login_type $host$normal" echo end
Daily Temp Dir
I am still using the daily temp dir mechanism I blogged about 17 years ago. Porting it to Fish was straight forward:
- .config/fish/conf.d/80-tools.fish
# Daily temp dir set -gx TD "$HOME/temp/$(date +'%Y-%m-%d')" function td set td $TD if test -n "$argv[1]" set td "$HOME/temp/$(date -d "$argv[1] days" +'%Y-%m-%d')" else ln -s -f -T $td "$HOME/temp/00-today" end mkdir -p $td cd $td end