zshrc for 2024

Throughout the years, I’ve been using zsh as my shell of choice. It’s been a great experience and I’ve learned a lot about how to configure it to my liking. Here’s my current zshrc file for 2024.

I’ve commented each thing in the .zshrc config. Some of the more personal information, but you can use this as a template for your own zshrc file.

Place this in your ~/.zshrc file and you should be good to go.


![Screenshot](/media/kitty.jpg)

# Theme
ZSH_THEME="sorin"

# History
SAVEHIST=5000
HISTFILE=~/.zsh_history

# Path to your oh-my-zsh installation.
export ZSH=/Users/marko/.oh-my-zsh

# Banner
python3 ~/Git/zshrc/banner.py

# https://github.com/lincheney/fzf-tab-completion
source ~/Git/fzf-tab-completion/zsh/fzf-zsh-completion.sh
bindkey '^I' fzf_completion

# Load Shell
source $ZSH/oh-my-zsh.sh
source <(fzf --zsh)

# Uncomment the following line to change how often to auto-update (in days).
export UPDATE_ZSH_DAYS=10

# Uncomment the following line to display red dots whilst waiting for completion.
COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# HIST_STAMPS="mm/dd/yyyy"

# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
#
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.

export NVM_LAZY_LOAD=true
export NVM_COMPLETION=true
# plugins=(nvm extract z zsh-syntax-highlighting zsh-autosuggestions)
plugins=(nvm z zsh-syntax-highlighting)

# User configuration
export PATH="/opt/homebrew/bin/psql:/bin:/sbin:/usr/bin:/opt/homebrew/sbin:/opt/homebrew/bin:/Users/marko/pear/bin:/opt/homebrew/share/npm/bin"

# PIP
export PIP_REQUIRE_VIRTUALENV=false

# Path Updates
export PATH="/opt/homebrew/bin:$PATH"
export PATH="$HOME/.node/bin:$PATH"
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
export PATH="/opt/homebrew/opt/php@8.0/sbin:$PATH"
export PATH="/opt/homebrew/opt/php@8.0/bin:$PATH"
export MYVIMRC="vimrc"
# export PATH_TO_CKPT="~/Git/stable-diffusion/downloads/"

export FZF_CTRL_T_OPTS="--height 60% \
--border sharp \
--layout reverse \
--prompt '∷ ' \
--pointer ▶ \
--marker ⇒"

export FZF_CTRL_R_OPTS="
  --preview 'echo {}' --preview-window up:3:hidden:wrap
  --bind 'ctrl-/:toggle-preview'
  --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
  --color header:italic
  --header 'Press CTRL-Y to copy command into clipboard'"

# tomasr/molokai
export FZF_DEFAULT_OPTS='--color=bg+:#293739,bg:#1B1D1E,border:#808080,spinner:#E6DB74,hl:#7E8E91,fg:#F8F8F2,header:#7E8E91,info:#A6E22E,pointer:#A6E22E,marker:#F92672,fg+:#F8F8F2,prompt:#F92672,hl+:#F92672'
#  https://vitormv.github.io/fzf-themes#eyJib3JkZXJTdHlsZSI6InJvdW5kZWQiLCJib3JkZXJMYWJlbCI6IiIsImJvcmRlckxhYmVsUG9zaXRpb24iOjAsInByZXZpZXdCb3JkZXJTdHlsZSI6InJvdW5kZWQiLCJwYWRkaW5nIjoiMCIsIm1hcmdpbiI6IjAiLCJwcm9tcHQiOiI+ICIsIm1hcmtlciI6Ij4iLCJwb2ludGVyIjoi4peGIiwic2VwYXJhdG9yIjoi4pSAIiwic2Nyb2xsYmFyIjoi4pSCIiwibGF5b3V0IjoiZGVmYXVsdCIsImluZm8iOiJkZWZhdWx0IiwiY29sb3JzIjoiZmcrOiNkMGQwZDAsYmcrOiMwNDA0MDQsaGw6IzVmODdhZixobCs6IzVmZDdmZixpbmZvOiNhZmFmODcsbWFya2VyOiNkNzAwNWYscHJvbXB0OiM4N2ZmMDAsc3Bpbm5lcjojZDcwMDVmLHBvaW50ZXI6I2Q3MDA1ZixoZWFkZXI6Izg3YWZhZixib3JkZXI6IzI2MjYyNixsYWJlbDojYWVhZWFlLHF1ZXJ5OiNkOWQ5ZDkifQ==
export FZF_DEFAULT_OPTS=$FZF_DEFAULT_OPTS'
  --color=fg:-1,fg+:#d0d0d0,bg:-1,bg+:#040404
  --color=hl:#5f87af,hl+:#5fd7ff,info:#afaf87,marker:#d7005f
  --color=prompt:#87ff00,spinner:#d7005f,pointer:#d7005f,header:#87afaf
  --color=border:#262626,label:#aeaeae,query:#d9d9d9
  --border="rounded" --border-label="" --preview-window="border-rounded" --prompt="> "
  --marker=">" --pointer="◆" --separator="─" --scrollbar="│"'

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Load NVM
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

export EDITOR="vim"
export VISUAL="vim"

# Z (Tracks most-used directories to make cd smarter)
. /opt/homebrew/etc/profile.d/z.sh

# Reload
alias reload="source ~/.zshrc"

# Alias for ddgr
alias ddg="ddgr"

# Alias for dig
alias dy="dig +short @dns.toys"

# change to root
alias ~="cd ~"

# clear
alias c='clear'

# edit php.ini
alias phpini='sudo vim /opt/homebrew/etc/php/8.0/php.ini'

# edit httpd.conf
# alias apacheconf='sudo vim /etc/apache2/httpd.conf'
alias apacheconf='sudo vim /opt/homebrew/etc/httpd/httpd.conf'

# edit new httpd.conf
alias apachconfnew='sudo vim /opt/homebrew/etc/httpd/httpd.conf'

# edit hosts
alias hosts='sudo vim /etc/hosts'

# edit this file
alias editzsh='sudo vim ~/.zshrc'

# edit user.conf
alias userconf='sudo vim /etc/apache2/users/marko.conf'

# edit httpd-vhosts.conf
alias vhosts='sudo vim /opt/homebrew/etc/httpd/extra/httpd-vhosts.conf'

# apache logs
alias apachelogs="less +F /var/log/apache2/error_log"

# colored search in files
alias grep='grep --color=auto'

# keys
alias keys='pbcopy < ~/.ssh/id_rsa.pub'

# flush dns
alias flush='sudo ifconfig en0 down && sudo ifconfig en1 down && sudo ifconfig en2 down && sudo route flush && sudo ifconfig en0 up && sudo ifconfig en1 up && sudo ifconfig en2 up'

# edit zshell
alias zshrc='editzsh'

# find todos
alias todos='ack -n -R --nogroup "(TODO|FIND|FIX(ME)?):" --ignore-dir={composer,vendor,vendors,min,lib}'

# find by name
alias qfind="find . -name "

# mute
alias stfu='osascript -e "set volume output muted true"'

# copy pwd
alias cpwd='pwd|tr -d "\n"|pbcopy'
# alias cl='fc -e -|pbcopy'

# remove .git
alias ungit='find . -name '.git' -exec rm -rf {} \;'

# IP info
alias ip='curl https://ipinfo.io/plain; echo'
# alias scrapeip='curl https://icanhazip.com; echo'
# myip() {
#     ip addr | awk '/inet / {sub(/\/.*/, "", $2); print $2}'
# }
# alias ip="ifconfig -a | perl -nle'/(\d+\.\d+\.\d+\.\d+)/ && print $1'"

# computer power options
alias reboot='sudo /sbin/reboot'
alias shutdown='sudo /sbin/shutdown'
alias lock='/System/Library/CoreServices/"Menu Extras"/User.menu/Contents/Resources/CGSession -suspend'
alias poweroff='sudo /sbin/poweroff'
# alias halt='sudo /sbin/halt'

# git log detailed
alias glg='git log --date-order --all --graph --format="%C(green)%h%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'

# git log files changed
alias glg2='git log --date-order --all --graph --name-status --format="%C(green)%H%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'

# history
alias h='history'
alias clear_history='echo "" > ~/.zsh_history & exec $SHELL -l'

# active connections
alias connections='lsof -i'

# Edit Vimrc
alias vimrc="vim /Users/marko/Git/vimrc/vimrc"

# Edit iTermocil
alias edititermocil="code ~/.itermocil"

# Desktop Alias
alias desktop="cd ~/Desktop"

# Top
alias top="btop"

# Iterm Shell Integration
source ~/.iterm2_shell_integration.`basename $SHELL`
compctl -g '~/.itermocil/*(:t:r)' itermocil

# Now Playing
alias nowplaying="sh ~/song.sh"

# Send Nowplaying to Slack
alias slackmusic="cd ~/Git/node-slack-fm-status && node run.js desmosthenes"

# Close Finder Windows
alias finder-close="osascript -e 'tell application \"Finder\" to close every window'"

# Clean Brew
alias brewski='brew update && brew upgrade && brew cleanup; brew doctor; brew missing; echo "Brewski Complete" | terminal-notifier -sound default -appIcon https://brew.sh/assets/img/homebrew-256x256.png -title "Homebrew"'

# Start the Day
alias communication="open -a 'Slack'; open -a 'Mimestream'; open -a 'Discord'; open -a 'Messages'; open -a 'WhatsApp';"

# Check Active Connections
alias check-open-connection="sudo lsof -iTCP -sTCP:LISTEN -n -P"

# RIPGREP
alias rgweb="rg --type-add 'web:*.{html,css,scss,js,php}'"

# Reload Yabai
alias yabai-reload='launchctl kickstart -k "gui/${UID}/homebrew.mxcl.yabai"'

# Edit Yabairc
alias yabairc="sudo vim ~/.yabairc"

# Servers
alias dobox="ssh USER@HOSTSERVER"
alias archCakes="ssh USER@HOSTSERVER"
alias spbox="ssh USER@HOSTSERVER"

# Override cmus with sudo
alias cmus="sudo cmus"

# Run PHP server quickly
# alias dev="kill -9 $(lsof -i:9999 -t); php -S localhost:9999"

# Python 3
alias python=python3

# Git
alias gg='cd ~/Git'

# Eza
unalias ls
alias ls="eza -lhaGF --icons --git"

# NPM Run Dev
alias nrd="npm run dev"

### FZF

# Another fd - cd into the selected directory
# This one differs from the above, by only showing the sub directories and not
#  showing the directories within those.
fd() {
  DIR=`find * -maxdepth 0 -type d -print 2> /dev/null | fzf --height 40% \
    --border sharp \
    --layout reverse \
    --prompt '∷ ' \
    --pointer\
    --marker` \
    && cd "$DIR"
}

# fdr - cd to selected parent directory
fdr() {
  local declare dirs=()
  get_parent_dirs() {
    if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
    if [[ "${1}" == '/' ]]; then
      for _dir in "${dirs[@]}"; do echo $_dir; done
    else
      get_parent_dirs $(dirname "$1")
    fi
  }
  local DIR=$(get_parent_dirs $(realpath "${1:-$PWD}") | fzf --height 40% \
    --border sharp \
    --layout reverse \
    --prompt '∷ ' \
    --pointer\
    --marker--tac)
  cd "$DIR"
}

# fcd - cd into the directory of the selected file
fcd() {
   local file
   local dir
   file=$(fzf --height 40% \
     --border sharp \
     --layout reverse \
     --prompt '∷ ' \
     --pointer\
     --marker ⇒ +m -q "$1") && dir=$(dirname "$file") && cd "$dir"
}

# fh - repeat command history
fh() {
  eval $( ([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf --height 40% \
  --border sharp \
  --layout reverse \
  --prompt '∷ ' \
  --pointer\
  --marker ⇒ +s --tac | sed -E 's/ *[0-9]*\*? *//' | sed -E 's/\\/\\\\/g')
}

# fkill - kill processes - list only the ones you can kill.
fkill() {
    local pid
    if [ "$UID" != "0" ]; then
        pid=$(ps -f -u $UID | sed 1d | fzf --height 40% \
          --border sharp \
          --layout reverse \
          --prompt '∷ ' \
          --pointer\
          --marker-m | awk '{print $2}')
    else
        pid=$(ps -ef | sed 1d | fzf --height 60% \
          --border sharp \
          --layout reverse \
          --prompt '∷ ' \
          --pointer\
          --marker-m | awk '{print $2}')
    fi

    if [ "x$pid" != "x" ]
    then
        echo $pid | xargs kill -${1:-9}
    fi
}

# fbr - checkout git branch (including remote branches)
fbr() {
  local branches branch
  branches=$(git branch --all | grep -v HEAD) &&
  branch=$(echo "$branches" |
           fzf-tmux -d $(( 2 + $(wc -l <<< "$branches") )) +m) &&
  git checkout $(echo "$branch" | sed "s/.* //" | sed "s#remotes/[^/]*/##")
}

# fcoc - checkout git commit
fcoc() {
  local commits commit
  commits=$(git log --pretty=oneline --abbrev-commit --reverse) &&
  commit=$(echo "$commits" | fzf --tac +s +m -e) &&
  git checkout $(echo "$commit" | sed "s/ .*//")
}

# fshow - git commit browser (& view commit contents)
fshow() {
  git log --graph --color=always \
      --format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
  fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-s:toggle-sort \
      --bind "ctrl-/:execute:
                (grep -o '[a-f0-9]\{7\}' | head -1 |
                xargs -I % sh -c 'git show --color=always % | less -R') << 'FZF-EOF'
                {}
FZF-EOF"
}

# like normal z when used with arguments but displays an fzf prompt when used without.
unalias z 2> /dev/null
z() {
  [ $# -gt 0 ] && _z "$*" && return
  cd "$(_z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')"
}

bindkey "${key[Up]}" fzf-history-widget

# f() {
#     sels=( "${(@f)$(fd "${fd_default[@]}" "${@:2}"| fzf)}" )
#     test -n "$sels" && print -z -- "$1 ${sels[@]:q:q}"
# }

In particular, I’ve been using fzf far more in my terminal workflow. It’s truly made the experience much smoother, and eliminated quite a few painpoints. Can’t recommend it enough.

ender