Migrating Off Oh-My-Zsh and other recent Yak Shavings

5th March 2025 – 1457 words

Insprired by a recent blog post of Bohidar Batsov I decided to simplify my Zshrc.

About 10ish years ago, I started to use Zsh and used the Oh-My-Zsh distribution for a pleasant OOTB experience. But over the years, I don’t really use most of the stuff, but never really took the time to clean it up, as having NO zsh config just leaves a very ugly prompt by default.

As Bohidar, I also added Starship as prompt. This provides a nice framework for customizing and extending the prompt.

You can find the full zshrc on my dotfiles. Stuff, that you need to install:

  1. Starship, I used cargo (Rust) to install it:
    rustup update
    cargo install starship
    # make sure ~/.cargo/bin is in your $PATH
    
  2. fzf. The FZF that is available on the Ubuntu repos is quite old, so I installed it via git:
    git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
    ~/.fzf/install
    

In my case, I also needed to remove the system package, as it’s PATH priority would be higher than this installed version.

Starship

In the dotfiles repo, you can also find my Starship TOML. There is a couple of options that I disabled, like NodeJS version, Git “untracked” hint and removal of the verbose conjunctions, like “in” and “on” between it’s segments.

On the bottom, you can also find a SSH-Agent integration, that tells me, if my most important Keys are unlocked and ready to use (useful before Git-pushing, or ssh access to production machines).

my Starship Prompt

"$schema" = 'https://starship.rs/config-schema.json'

add_newline = false

[hostname]
ssh_only = true
format = '[$ssh_symbol$hostname]($style) '
ssh_symbol = "@"
style = "yellow"

[username]
format = '[$user]($style)'
style_user = "yellow"

[directory]
truncation_length = 4
truncate_to_repo = false

[git_branch]
truncation_length = 15
# remove the 'on' conjunction
format = '[$symbol$branch]($style) '

[git_status]
untracked = ""
stashed = "STASHED"

[nodejs]
disabled = true

[memory_usage]
disabled = true
threshold = -1
symbol = " "
style = "bold dimmed green"

[ruby]
# disable if too slow:
# disabled = false
symbol = "🔺 "
# remove 'via' conjunction
format = "[$symbol$version]($style) "

[custom.ssh_no_keys]
description = "SSH missing keys"
when = "ssh-add -l | grep -q 'no identities'"
command = "echo 🚫"
format = "$symbol[$output]($style) "
shell = ["bash", "--noprofile", "--norc"]
symbol = "🔑"
style = "bold fg:red"

[custom.primary_key_locked]
description = "SSH key count"
when = "! ssh-add -l | grep -v 'no identities' | egrep $HOME/.ssh/id_rsa"
symbol = "§"
style = "red"

[custom.primary_key_unlocked]
description = "SSH key count"
when = "ssh-add -l | grep -v 'no identities' | egrep $HOME/.ssh/id_rsa"
symbol = "§"
style = "green"

[custom.secondary_key_locked]
description = "SSH key count"
when = "! ssh-add -l | grep -v 'no identities' | egrep masterkey"
symbol = "§"
style = "red"

[custom.secondary_key_unlocked]
description = "SSH key count"
when = "ssh-add -l | grep -v 'no identities' | egrep masterkey"
symbol = "§"
style = "green"

Tangent: asdf upgrade

While running starship, I noticed that fetching the current Ruby version took about 250ms (time ruby -v). I am using the Ruby version manager asdf since a couple of years that I only noticed now took quite a long time to fetch the current version. Going on their Github repo, I saw, that the current version is a complete rewrite in Go, and supposedly much faster. So I decided to upgrade it. Fortunately, you can either compile with Go (which’s version on APT repos is also too old), or download the precompiled version, which I did:

wget https://github.com/asdf-vm/asdf/releases/download/v0.16.5/asdf-v0.16.5-linux-amd64.tar.gz
# or with Macos:
wget https://github.com/asdf-vm/asdf/releases/download/v0.16.5/asdf-v0.16.5-darwin-arm64.tar.gz
tar -xvzf asdf-v0.16.5-linux-amd64.tar.gz
sudo mv asdf /usr/local/bin
rm ~/.asdf/bin/asdf

Alternately, mise seems to be a very nice alternative to asdf.

Full zshrc listing

export TERM=xterm-256color
export EDITOR="nvim"

# improved history search, Like Ctrl+R
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh

HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000

setopt HIST_SAVE_NO_DUPS
setopt INC_APPEND_HISTORY

# Emacs keybindings, like Ctr+a Ctrl+e
bindkey -e

if [ -d "$HOME/go" ]; then
  export GOPATH=$HOME/go
  export PATH=$PATH:$GOPATH/bin
fi
if [ -d "/usr/local/opt/go/libexec" ]; then
  export GOROOT=/usr/local/opt/go/libexec
  export PATH=$PATH:$GOROOT/bin
fi
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin
export PATH="./bin:./node_modules/.bin:$PATH"

# disable autocorrect, which I find annoying
unsetopt correct_all
unsetopt correct

# use `j` autojump tool
source /usr/share/autojump/autojump.sh


# automatically run a SSH-agent on first command and load the ssh-agent
# environment variables in subsequent shells
if [[ "$(ps -u $USER | grep ssh-agent | wc -l)" -lt "1" ]]; then
  echo "$(date +%F@%T) - SSH-AGENT: Agent will be started"
  ssh-agent -s >~/.ssh/ssh-agent
  . ~/.ssh/ssh-agent >/dev/null
  echo "SSH-Agent: Add Key with ssh-add -t 28800 ~/.ssh/id_rsa"
else
  echo "$(date +%F@%T) - SSH-AGENT: Agent already running"
  . ~/.ssh/ssh-agent >/dev/null
fi

# Aliases
alias g='git'
compdef g=git
alias gst='git status -sb'
alias gl='git pull'
alias gp='git push'
alias gc='git commit -v'
alias ga='git add'
alias gca='git commit --amend --no-edit'
alias gau='git add -u'
alias rebase-continue='git add -u && git rebase --continue'
function gcm() {
  git commit -m "$*"
}

alias history='fc -l 1'
alias diff='diff --color -u'
alias ap='ansible-playbook'

alias lsa='ls -lah'
alias l='ls -la'
alias ll='ls -l'
alias sl=ls
export LSCOLORS="Gxfxcxdxbxegedabagacad"
ls --color -d . &>/dev/null 2>&1 && alias ls='ls --color=tty' || alias ls='ls -G'

# ruby aliases and helper
alias b="bundle exec"
function R() {
  if [ -f bin/spring ]
  then
    nocorrect bin/spring rspec "$@"
  else
    bundle exec rspec "$@"
  fi
}
function Rnf() {
  if [ -f bin/spring ]
  then
    nocorrect bin/spring rspec --next-failure "$@"
  else
    bundle exec rspec --next-failure "$@"
  fi
}
function Rof() {
  if [ -f bin/spring ]
  then
    nocorrect bin/spring rspec --only-failures "$@"
  else
    bundle exec  rspec --only-failures "$@"
  fi
}

# starship prompt
eval "$(starship init zsh)"

# asdf
export ASDF_DATA_DIR="$HOME/.asdf"
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
fpath=(${ASDF_DATA_DIR:-$HOME/.asdf}/completions $fpath)

# Initialize completion
autoload -U +X bashcompinit && bashcompinit
autoload -U +X compinit && compinit