Skip to content

Terminal & Shell Setup

Ghostty

I've started using Mitchell Hashimoto's Ghostty, it's fast, clean and runs natively on both macOS and Linux.

Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.

Configuration

theme = catppuccin-mocha
font-family = "MesloLGM Nerd Font Mono"

Note

Ghostty has Nerd Fonts built-in, so if you use another terminal emulator you will need to install the Meslo font yourself.

Z shell (zsh)

zshrc

~/.zshrc
# Uncomment to profile startup times, be sure to add `zprof` at the end of this file
# zmodload zsh/zprof

eval "$(oh-my-posh init zsh --config ~/.config/ohmyposh/acecat.omp.toml)"

export PATH="$HOME/.local/bin:$PATH"

# Needed to let python know where some libs are
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"
export DYLD_LIBRARY_PATH="/usr/local/lib:/opt/homebrew/lib:$DYLD_LIBRARY_PATH"

# NodeJS (nvm)
# When installing nvm you may need to ensure that the ~/.nvm directory exists,
# and that it contains the `nvm.sh` and `bash_completion` files, or symlinks to them.
if [ -s "$HOME/.nvm/nvm.sh" ]; then
  export NVM_DIR="$HOME/.nvm"
  . "$NVM_DIR/nvm.sh" --no-use # This loads nvm, without auto-using the default version
fi

# uv autocompletion
# Uncomment the next line if you get the error: 'command not found: compdef'
autoload -Uz compinit && compinit
eval "$(uv generate-shell-completion zsh)"
eval "$(uvx --generate-shell-completion zsh)"

# bat config
export BAT_THEME="Catppuccin-mocha"
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
alias bathelp="bat --plain --language=help"
help() {
  "$@" --help 2>&1 | bathelp
}

# fzf keybindings and fuzzy search
if [ -f ~/.fzf.zsh ]; then
  # On MacOS this file is created by brew
  source ~/.fzf.zsh
elif [ -d "/usr/share/doc/fzf/examples" ]; then
  # We're probably on Ubuntu/Debian, so load the files from here
  source /usr/share/doc/fzf/examples/key-bindings.zsh
  source /usr/share/doc/fzf/examples/completion.zsh
fi
# catppuccin mocha theme for fzf
export FZF_DEFAULT_OPTS=" \
--color=bg+:#313244,bg:#1e1e2e,spinner:#f5e0dc,hl:#f38ba8 \
--color=fg:#cdd6f4,header:#f38ba8,info:#cba6f7,pointer:#f5e0dc \
--color=marker:#b4befe,fg+:#cdd6f4,prompt:#cba6f7,hl+:#f38ba8 \
--color=selected-bg:#45475a \
--multi"

ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20
source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

# aliases & functions
alias zls="zfs list -o type,name,available,used,logicalused,usedbysnapshots,compressratio,mountpoint"
alias zsl="zfs list -t snapshot"
alias s="ssh -l root"
alias l="ls -la"

# get all kubernetes resources for a namespace
kubectlgetall() {
  if [ -z "$1" ]; then
    echo "Usage: $0 <namespace>"
    return 1
  fi
  for i in $(kubectl api-resources --verbs=list --namespaced -o name | grep -v "events.events.k8s.io" | grep -v "events" | sort | uniq); do
    echo "Resource:" $i
    kubectl -n ${1} get --ignore-not-found ${i}
  done
}

# nextcloud
occ() {
  NEXTCLOUD_POD_NAME=$(kubectl get pod -n cosmoknots -l app.kubernetes.io/name=nextcloud -o jsonpath='{.items[0].metadata.name}')
  kubectl exec -n cosmoknots $NEXTCLOUD_POD_NAME -c nextcloud -i -t -- sudo -u '#33' PHP_MEMORY_LIMIT=512M /var/www/html/occ "$@"
}

# base64 decode that also works with base64url variant (no padding)
b64d() {
  local data=""
  while IFS= read -r line || [ -n "$line" ]; do
    data+="$line"
  done
  echo "${data}==" | base64 --decode
}

acecat Theme

~/.config/ohmyposh/acecat.omp.toml
version = 3

[upgrade]
  source = 'cdn'
  interval = '168h'
  auto = false
  notice = false

[palette]
  base = '#1e1e2e'
  text = '#cdd6f4'
  pink = '#f5c2e7'
  red = '#f38ba8'
  yellow = '#f9e2af'
  green = '#a6e3a1'
  teal = '#94e2d5'
  blue = '#89b4fa'

[[blocks]]
  type = 'prompt'
  alignment = 'left'

  [[blocks.segments]]
    template = '{{ if .WSL }}WSL at {{ end }}{{.Icon}}'
    foreground = 'p:text'
    type = 'os'
    style = 'plain'

  [[blocks.segments]]
    template = '  '
    foreground = 'p:red'
    type = 'root'
    style = 'plain'

  [[blocks.segments]]
    template = ' {{ if eq .PWD "~" }}{{ else }}{{ end }} {{ .Path }}'
    foreground = 'p:blue'
    type = 'path'
    style = 'plain'

    [blocks.segments.properties]
      style = 'full'
      folder_format = '<d>%s</d>'
      edge_format = '<b>%s</b>'

  [[blocks.segments]]
    template = ' {{ .UpstreamIcon }} {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uF044 {{ .Working.String }}{{ end }}{{ if and (.Staging.Changed) (.Working.Changed) }} |{{ end }}{{ if .Staging.Changed }} \uF046 {{ .Staging.String }}{{ end }}'
    foreground = 'p:yellow'
    type = 'git'
    style = 'plain'

    [blocks.segments.properties]
      fetch_upstream_icon = true
      fetch_status = true

[[blocks]]
  type = 'prompt'
  alignment = 'right'

  [[blocks.segments]]
    template = ' <p:red> {{ reason .Code }}({{ .Code }})</>'
    type = 'status'
    style = 'plain'

  [[blocks.segments]]
    template = '  {{ .FormattedMs }}'
    type = 'executiontime'
    style = 'plain'

    [blocks.segments.properties]
      style = 'round'
      threshold = 3000

  [[blocks.segments]]
    template = '{{ if .SSHSession }}  {{ .UserName }}@{{ .HostName }}{{ end }}'
    foreground = 'p:yellow'
    type = 'session'
    style = 'plain'

  [[blocks.segments]]
    template = '  {{ .CurrentDate | date .Format }}'
    foreground = 'p:blue'
    type = 'time'
    style = 'plain'

    [blocks.segments.properties]
      time_format = '15:04:05'

[[blocks]]
  type = 'prompt'
  alignment = 'left'
  newline = true

  [[blocks.segments]]
    template = '❯ '
    foreground = 'p:green'
    type = 'status'
    style = 'plain'
    foreground_templates = ['{{ if gt .Code 0 }}p:red{{ end }}']

    [blocks.segments.properties]
      always_enabled = true

[[tooltips]]
  type = 'kubectl'
  style = 'plain'
  tips = [ 'kubectl' ]

  [tooltips.properties]
    display_default = true

Optional: VS Code Settings

VS Code users will need to add the following to their settings.json:

"terminal.external.osxExec": "Ghostty.app",
"terminal.integrated.fontFamily": "MesloLGM Nerd Font Mono",