Skip to content

Instantly share code, notes, and snippets.

@petronetto
Last active May 12, 2025 22:18
Show Gist options
  • Save petronetto/fb9cc3ab62f1ecf833ecde8d113fa240 to your computer and use it in GitHub Desktop.
Save petronetto/fb9cc3ab62f1ecf833ecde8d113fa240 to your computer and use it in GitHub Desktop.
My ZSH config
# General configuration
export LANG=en_GB.UTF-8
export TERM=xterm-256color
# XDG Base Directory Specification
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_RUNTIME_DIR="$HOME/.cache/run"
export XDG_CONFIG_DIRS="/etc/xdg"
export XDG_DATA_DIRS="/usr/local/share:/usr/share"
# ZSH configuration
export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
#!/usr/bin/env zsh
##############################################################################################
# 888~-_ d8 d8 d8 #
# 888 \ e88~~8e _d88__ 888-~\ e88~-_ 888-~88e e88~~8e _d88__ _d88__ e88~-_ #
# 888 | d888 88b 888 888 d888 i 888 888 d888 88b 888 888 d888 i #
# 888 / 8888__888 888 888 8888 | 888 888 8888__888 888 888 8888 | #
# 888_-~ Y888 , 888 888 Y888 ' 888 888 Y888 , 888 888 Y888 ' #
# 888 "88___/ "88_/ 888 "88_-~ 888 888 "88___/ "88_/ "88_/ "88_-~ #
##############################################################################################
source_if_exists() {
local file="$1"
[[ ! -f "$file" ]] || source "$file"
}
export EDITOR='vim'
# Homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"
# 1password agent
export SSH_AUTH_SOCK="$HOME/.1password/agent.sock"
# Zoxide configuration
export _ZO_DATA_DIR="$XDG_DATA_HOME/zoxide"
eval "$(zoxide init zsh)"
# History command configuration
# see more at https://zsh.sourceforge.io/Doc/Release/Options.html
export HISTSIZE=5000
export SAVEHIST=$HISTSIZE
export HISTDUP=erase
setopt INC_APPEND_HISTORY # Immediately saves commands to history across sessions
setopt SHARE_HISTORY # Share history across sessions
setopt HIST_IGNORE_ALL_DUPS # To ignore duplicated commands history list
setopt HIST_SAVE_NO_DUPS # Don't save duplicated entries
setopt HIST_FIND_NO_DUPS # Don't display duplicates in search results
setopt HIST_IGNORE_SPACE # Don't save commands starting with space
# beeping is annoying
unsetopt BEEP
# asdf version manager
# source $(brew --prefix asdf)/libexec/asdf.sh
# https://zdharma-continuum.github.io/zinit/wiki/
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
[ ! -d $ZINIT_HOME ] && mkdir -p "$(dirname $ZINIT_HOME)"
[ ! -d $ZINIT_HOME/.git ] && git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
source "${ZINIT_HOME}/zinit.zsh"
zinit ice from"gh-r" as"command" atload'eval "$(starship init zsh)"'
zinit load starship/starship
export STARSHIP_CONFIG="$XDG_CONFIG_HOME/starship/starship.toml"
export STARSHIP_LOG="error"
# Atuin
eval "$(atuin init zsh --disable-up-arrow)"
# Extra zsh completions
zinit ice lucid wait='0' atinit='zpcompinit'
zinit light zsh-users/zsh-completions
# zinit ice as"completion" ; zinit snippet https://github.com/docker/cli/blob/master/contrib/completion/zsh/_docker
# Syntax highlighting
zinit light zsh-users/zsh-syntax-highlighting
# zsh-autosuggestions
zinit ice wait lucid atload"!_zsh_autosuggest_start"
zinit load zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-history-substring-search
zinit light MichaelAquilina/zsh-you-should-use
# Plugin configuration
ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(
'bracketed-paste'
'history-search-forward'
'history-search-backward'
'history-beginning-search-forward'
'history-beginning-search-backward'
'history-substring-search-up'
'history-substring-search-down'
'up-line-or-beginning-search'
'down-line-or-beginning-search'
'up-line-or-history'
'down-line-or-history'
'accept-line'
'copy-earlier-word'
'menu-select'
)
# Configure history-substring-search
# https://github.com/zsh-users/zsh-history-substring-search?tab=readme-ov-file#configuration
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=0
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND=0
HISTORY_SUBSTRING_SEARCH_PREFIXED=1
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
source_if_exists "$XDG_CONFIG_HOME/zsh/aliases"
source_if_exists "$XDG_CONFIG_HOME/zsh/functions"
source_if_exists "$XDG_CONFIG_HOME/zsh/completions"
if [[ $TERM_PROGRAM = "iTerm.app" ]]; then
source_if_exists "$XDG_CONFIG_HOME/iterm2/shell_integration.zsh"
fi
source_if_exists "$XDG_CONFIG_HOME/fzf/fzf.zsh"
source_if_exists "$XDG_CONFIG_HOME/work/envs"
#!/usr/bin/env zsh
#---------------------------------------------------------------------------------------------------------------
# VIM
#---------------------------------------------------------------------------------------------------------------
alias vim='nvim'
#---------------------------------------------------------------------------------------------------------------
# Docker
#---------------------------------------------------------------------------------------------------------------
alias dc='docker compose'
alias dc-up='docker compose up -d'
alias dc-stop='docker compose stop'
alias docker-init='open --background -a Docker'
alias docker-ip='docker inspect -f "{{.Name}} - {{.NetworkSettings.IPAddress }}" $(docker ps -aq)'
alias docker-rm='docker stop $(docker ps -aq) && docker rm $(docker ps -aq)'
alias docker-rm-stoped='docker stop $(docker ps -aq -f status=exited) && docker rm $(docker ps -aq -f status=exited)'
alias docker-start-all='docker start $(docker ps -aq)'
alias docker-restart='docker restart $(docker ps -aq)'
alias docker-stop-all='docker stop $(docker ps -aq)'
alias dsa='docker-stop-all'
alias docker-rmi='docker rmi $(docker images -aq) -f'
alias docker-rm-net='docker network rm $(docker network ls -q)'
alias docker-rm-vol='docker volume rm $(docker volume ls -q)'
alias docker-clean='docker system prune --all -f'
alias docker-clean-all='docker system prune --all -f && docker volume rm -f $(docker volume ls -q) && docker network rm -f $(docker network ls -q)'
#---------------------------------------------------------------------------------------------------------------
# Git
#---------------------------------------------------------------------------------------------------------------
alias clone="git clone"
alias gmain="git checkout main"
alias gm="gmain"
alias gcb="git branch -vv | awk '/: gone\\]/ {print \$1}' | xargs git branch -f -d"
alias gfa="git fetch --all"
alias gpull="git fetch -p --all && git pull"
alias gp="gpull"
alias gpush="git push 2>&1 | grep \"git push\" | sh"
alias gph="gpush"
alias ggraph="git log --graph --oneline --decorate --all"
#---------------------------------------------------------------------------------------------------------------
# PHP
#---------------------------------------------------------------------------------------------------------------
alias cda='compi dump-autoload -oan'
alias cri='compi install'
alias cr='compi req'
alias crm='compi rem'
alias pa='php artisan'
alias lsail='[ -f sail ] && sh sail || sh vendor/bin/sail'
#---------------------------------------------------------------------------------------------------------------
# Python
#---------------------------------------------------------------------------------------------------------------
alias py='python'
venv() {
if [ -z "$1" ]; then
py -m venv venv
else
py -m venv "$1"
fi
}
alias actvenv='source venv/bin/activate'
alias mkvenv='venv && actvenv'
#---------------------------------------------------------------------------------------------------------------
# Utils
#---------------------------------------------------------------------------------------------------------------
alias -g N="1>/dev/null 2>/dev/null" # No Output
alias -g B="1>/dev/null 2>/dev/null &" # Background
alias -g A="2>&1" # All (merge stdout/err)
alias -g T="| tee -a /dev/stderr" # Tee to stderr
alias -g S="| sort | uniq" # Sort
alias -g U="| sort | uniq -c | sort -nr" # Count
alias -g UU="| sort | uniq -c | sort -n | sed -E 's/^ +[0-9]+ //g'" # No Number
alias -g L="| awk '{ print length, $0 }' | sort -n | uniq | cut -d' ' -f2" # Sort by Length
alias prev="fzf --preview 'bat --style=numbers --color=always --line-range :500 {}'"
alias ..='cd ..'
alias cls="clear"
alias tailf="tail -f"
alias cat="bat" # https://github.com/sharkdp/bat
alias cd="z" # replace cd with Zoxide command - https://github.com/ajeetdsouza/zoxide
# ls https://github.com/lsd-rs/lsd
alias ls="lsd"
alias la="ls -a"
alias ll="ls -ll"
alias pwd="pwd | tee >(pbcopy)"
alias reload='exec "$SHELL" -l'
alias sup="sail up -d"
#!/usr/bin/env zsh
setopt MENU_COMPLETE # Automatically highlight first element of completion menu
setopt AUTO_LIST # Automatically list choices on ambiguous completion.
setopt COMPLETE_IN_WORD # Complete from both ends of a word.
# Completions - https://thevaluable.dev/zsh-completion-guide-examples
# Define completers
zstyle ':completion:*' completer _extensions _complete _approximate
# Use cache for commands using cache
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path "$XDG_CACHE_HOME/zsh/.zcompcache"
# Complete the alias when _expand_alias is used as a function
zstyle ':completion:*' complete true
zle -C alias-expension complete-word _generic
zstyle ':completion:alias-expension:*' completer _expand_alias
# Allow you to select in a menu
zstyle ':completion:*' menu select
# Autocomplete options for cd instead of directory stack
zstyle ':completion:*' complete-options true
zstyle ':completion:*' file-sort modification
zstyle ':completion:*:*:*:*:corrections' format '%F{yellow}!- %d (errors: %e) -!%f'
zstyle ':completion:*:*:*:*:messages' format ' %F{purple} -- %d --%f'
zstyle ':completion:*:*:*:*:warnings' format ' %F{red}-- no matches found --%f'
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
# Colors for files and directory
zstyle ':completion:*:*:*:*:default' list-colors ${(s.:.)LS_COLORS}
# Only display some tags for the command cd
zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories
# zstyle ':completion:*:complete:git:argument-1:' tag-order !aliases
# Required for completion to be in good groups (named after the tags)
zstyle ':completion:*' group-name ''
zstyle ':completion:*:*:-command-:*:*' group-order aliases builtins functions commands
# See ZSHCOMPWID "completion matching control"
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' keep-prefix true
zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'
#!/usr/bin/env zsh
color_red=$(tput setaf 1)
color_green=$(tput setaf 2)
color_reset=$(tput sgr0)
# Converts text to snake_case
function snake() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/_/g' | sed -E 's/^_+|_+$//g'
}
# Converts text to a URL-friendly slug
function slug() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g' | sed -E 's/^-+|-+$//g'
}
# Converts text to camelCase
function camel() {
echo "$1" | sed -E 's/[^a-zA-Z0-9]+/ /g' | awk '{ for (i=1; i<=NF; i++) { $i = (i == 1 ? tolower($i) : toupper(substr($i, 1, 1)) substr($i, 2)) } }1' | tr -d ' '
}
function config() {
nvim "$ZDOTDIR"
}
function docker-rebuild() {
if [[ $1 != "" ]]; then
docker compose up -d --force-recreate --no-deps --build "$1"
else
echo "${color_red}ERROR!${color_reset} ${color_green}You must provide the contaner name${color_reset}"
fi
}
# Composer
function comp() {
docker run --rm --interactive --tty \
--volume $(pwd):/app \
--volume ${COMPOSER_HOME:-$HOME/.composer}:/tmp \
--user $(id -u):$(id -g) \
composer:2.7.7 "$@"
}
function compi() {
comp "$@" --ignore-platform-reqs
}
function ollama-ui() {
docker run -d -p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-v open-webui:/app/backend/data \
--name open-webui \
--restart always \
-e WEBUI_AUTH=false \
ghcr.io/open-webui/open-webui:main
}
function loadenv() {
local file="${1:-.env}"
if [[ -f "$file" ]]; then
while IFS= read -r line || [ -n "$line" ]; do
if [[ ! "$line" =~ ^# && "$line" =~ ^[[:alnum:]_]+=.+ ]]; then
export "$line"
fi
done <"$file"
fi
}
# mkdir then cd
function mkcddir() {
/bin/mkdir "$1"
\cd "$1" || return
}
function docker-exec() {
local container=$1
local command=${2:-sh}
if [[ -n $container ]]; then
bash -c "clear && docker exec -it $container $command"
else
echo -e "${color_red}ERROR!${color_reset} ${color_green}You must provide the container name${color_reset}"
fi
}
# Use: fzf to navigate in the git branches
function gch() {
git checkout "$(git branch --all | fzf | tr -d '[:space:]')"
}
function git-undo() {
local count=${1:-1} # Default to undoing 1 commit if no argument provided
local mode=${2:-'soft'} # Default to 'soft' reset if no mode is specified
if [[ $mode != "hard" && $mode != "soft" ]]; then
echo "Invalid mode specified. Use 'hard' or 'soft'."
return 1
fi
git reset --$mode "HEAD~$count"
}
function gcheck() {
cmd="git checkout"
if [[ $2 = "--create" ]] || [[ $2 = "-c" ]]; then
cmd="$cmd -b"
fi
if [[ $1 != "" ]]; then
eval "$cmd $1"
else
echo "${color_red}ERROR!${color_reset} ${color_green}You must provide the branch name${color_reset}"
fi
}
# Delete files
function rm-all() {
if [[ $1 != "" ]]; then
find . -name "$1" -exec rm -rf {} \;
else
echo "ERROR! Type a file name"
fi
}
function pyclean() {
find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
}
function now() {
date '+%e, %B (%m) %Y - %H:%M'
}
# diff with clipboard
function diffp() {
diff <(cat $1) <(pbp)
}
function histsearch() {
fc -lim "*$@*" 1
}
function histclean() {
# Get the command history and display in reverse
local number=$(\cat -n $HISTFILE | sort -rn | fzf | awk '{print $1}')
# Delete the specific line from the history file
sed -i '' "${number}d" $HISTFILE
# Reload history
fc -R
}
# Remoe the last command from history
function forget() {
local number=$(\cat -n $HISTFILE | awk 'END{print $1-1}')
# Delete the specific line from the history file
sed -i '' "${number}d" $HISTFILE
fc -R
}
function month() {
if [[ "$1" =~ ^[0-9]+$ ]]; then
case "$1" in
1) echo "January" ;;
2) echo "February" ;;
3) echo "March" ;;
4) echo "April" ;;
5) echo "May" ;;
6) echo "June" ;;
7) echo "July" ;;
8) echo "August" ;;
9) echo "September" ;;
10) echo "October" ;;
11) echo "November" ;;
12) echo "December" ;;
*) echo "Invalid month number" ;;
esac
else
case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
january) echo 1 ;;
february) echo 2 ;;
march) echo 3 ;;
april) echo 4 ;;
may) echo 5 ;;
june) echo 6 ;;
july) echo 7 ;;
august) echo 8 ;;
september) echo 9 ;;
october) echo 10 ;;
november) echo 11 ;;
december) echo 12 ;;
*) echo "Invalid month name" ;;
esac
fi
}
function install() {
PACKAGE=$1
if [ -z "$PACKAGE" ]; then
echo "Usage: install <package_name>"
return 1
fi
# Identifying the platform
OS="$(uname)"
if [ "$OS" = "Darwin" ]; then
# macOS
echo "Detected macOS. Installing with brew..."
brew install $PACKAGE
elif [ "$OS" = "Linux" ]; then
# Assuming Ubuntu/Debian. Additional checks could be implemented for other distros.
echo "Detected Linux. Checking for Ubuntu/Debian..."
if grep -qEi "(debian|buntu)" /etc/*release; then
echo "Detected Ubuntu/Debian. Installing with apt..."
sudo apt update && sudo apt install -y $PACKAGE
else
echo "Unsupported Linux distribution. Please install $PACKAGE manually."
fi
else
echo "Unsupported OS. Please install $PACKAGE manually."
fi
}
# Loosely adapted from rustup-init.sh (see sh.rustup.rs)
function get_architecture() {
local _ostype _cputype _arch
_ostype="$(uname -s)"
_cputype="$(uname -m)"
if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
# Darwin `uname -m` lies
if sysctl hw.optional.x86_64 | grep -q ': 1'; then
_cputype=x86_64
fi
fi
case "$_ostype" in
Linux) _ostype=unknown-linux-gnu ;;
Darwin) _ostype=apple-darwin ;;
MINGW* | MSYS* | CYGWIN* | Windows_NT) _ostype=pc-windows-gnu ;;
*) err "unrecognized OS type: $_ostype" ;;
esac
case "$_cputype" in
i386 | i486 | i686 | i786 | x86) _cputype=i686 ;;
xscale | arm | armv6l | armv7l | armv8l) _cputype=arm ;;
aarch64 | arm64) _cputype=aarch64 ;;
x86_64 | x86-64 | x64 | amd64) _cputype=x86_64 ;;
*) err "unknown CPU type: $_cputype" ;;
esac
_arch="${_cputype}-${_ostype}"
RETVAL="$_arch"
echo "$RETVAL"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment