Skip to content

Instantly share code, notes, and snippets.

@SmileMachine
Last active May 16, 2026 12:47
Show Gist options
  • Select an option

  • Save SmileMachine/4b0ef5d6fb57873fd6bd9b04ef93d612 to your computer and use it in GitHub Desktop.

Select an option

Save SmileMachine/4b0ef5d6fb57873fd6bd9b04ef93d612 to your computer and use it in GitHub Desktop.
Install Oh My Zsh and some useful plugins on a new machine.
#!/bin/bash
# !!! This script is used specially for first install of omz on a new machine
# !!! All configurations in .zshrc will be replaced !!! (A backup file will be created)
# Use -y to skip this script's confirmation prompt.
set -euo pipefail
# Terminal colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
PKG_INSTALL_CMD=()
PKG_MANAGER=""
# Error handling function
error_exit() {
echo -e "${RED}[ERROR] $1${NC}" >&2
exit 1
}
# Check if command exists
check_command() {
command -v "$1" >/dev/null 2>&1
}
find_brew() {
local brew_path
for brew_path in /opt/homebrew/bin/brew /usr/local/bin/brew; do
if [ -x "$brew_path" ]; then
printf '%s\n' "$brew_path"
return 0
fi
done
command -v brew 2>/dev/null
}
ensure_homebrew() {
local brew_cmd
if brew_cmd=$(find_brew); then
export PATH="$(dirname "$brew_cmd"):$PATH"
return 0
fi
if ! check_command curl; then
error_exit "curl required to install Homebrew"
fi
echo -e "${YELLOW}[INFO] Installing Homebrew for macOS${NC}"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if brew_cmd=$(find_brew); then
export PATH="$(dirname "$brew_cmd"):$PATH"
return 0
fi
error_exit "Homebrew installed, but brew was not found in PATH, /opt/homebrew/bin, or /usr/local/bin"
}
# Show warning and get confirmation
show_warning() {
echo -e "${RED}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║ WARNING ║${NC}"
echo -e "${RED}╠══════════════════════════════════════════════════════════════╣${NC}"
echo -e "${RED}║ This script is for FIRST INSTALL of OMZ on a NEW machine ║${NC}"
echo -e "${RED}║ All .zshrc configurations will be REPLACED! ║${NC}"
echo -e "${RED}║ (A backup will be created) ║${NC}"
echo -e "${RED}╚══════════════════════════════════════════════════════════════╝${NC}"
echo
echo -e "${YELLOW}Are you sure you want to continue?${NC}"
read -p "Type 'YES' in uppercase to confirm: " confirmation
if [[ $confirmation != "YES" ]]; then
echo -e "${YELLOW}[INFO] Installation aborted by user${NC}"
exit 0
fi
echo -e "${GREEN}[INFO] Continuing with installation...${NC}"
echo
}
# Detect OS and package manager
detect_pkg_manager() {
local optional=false
local brew_cmd
if [[ "${1:-}" == "--optional" ]]; then
optional=true
fi
detect_failed() {
if [[ $optional == true ]]; then
return 1
fi
error_exit "$1"
}
case "$(uname -sr)" in
Linux*)
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
debian|ubuntu|linuxmint|elementary|pop|kali|raspbian)
PKG_INSTALL_CMD=(sudo apt install -y)
PKG_MANAGER="apt"
;;
fedora|rhel|centos|rocky|almalinux)
if check_command dnf; then
PKG_INSTALL_CMD=(sudo dnf install -y)
PKG_MANAGER="dnf"
else
PKG_INSTALL_CMD=(sudo yum install -y)
PKG_MANAGER="yum"
fi
;;
arch|manjaro)
PKG_INSTALL_CMD=(sudo pacman -Sy --noconfirm)
PKG_MANAGER="pacman"
;;
opensuse*|suse)
PKG_INSTALL_CMD=(sudo zypper install -y)
PKG_MANAGER="zypper"
;;
alpine)
PKG_INSTALL_CMD=(sudo apk add)
PKG_MANAGER="apk"
;;
void)
PKG_INSTALL_CMD=(sudo xbps-install -Sy)
PKG_MANAGER="xbps"
;;
*)
detect_failed "Unsupported OS: $ID" || return 1
;;
esac
else
detect_failed "Could not identify Linux distribution" || return 1
fi
;;
Darwin*)
if [[ $optional == true ]]; then
if brew_cmd=$(find_brew); then
export PATH="$(dirname "$brew_cmd"):$PATH"
else
return 1
fi
else
ensure_homebrew
fi
PKG_INSTALL_CMD=(brew install)
PKG_MANAGER="brew"
;;
CYGWIN*|MINGW*|MSYS*)
PKG_INSTALL_CMD=(pacman -S --noconfirm)
PKG_MANAGER="pacman"
;;
*)
detect_failed "Unsupported system: $(uname -sr)" || return 1
;;
esac
}
# Install required dependencies
install_dependencies() {
local required_deps=()
! check_command curl && required_deps+=(curl)
! check_command git && required_deps+=(git)
! check_command zsh && required_deps+=(zsh)
if [ ${#required_deps[@]} -gt 0 ]; then
if [ ${#PKG_INSTALL_CMD[@]} -eq 0 ]; then
detect_pkg_manager
fi
echo -e "${YELLOW}[INFO] Installing dependencies: ${required_deps[*]}${NC}"
"${PKG_INSTALL_CMD[@]}" "${required_deps[@]}" || error_exit "Failed to install dependencies"
fi
}
# Install a Zsh plugin if it does not already exist
install_plugin() {
local plugins_dir="$1"
local repo="$2"
local plugin_name="${3:-$(basename "$repo")}"
if [ ! -d "$plugins_dir/$plugin_name" ]; then
echo -e "${YELLOW}[INFO] Installing plugin: $plugin_name${NC}"
git clone --depth=1 "$repo" "$plugins_dir/$plugin_name" ||
error_exit "Failed to install plugin: $plugin_name"
else
echo -e "${GREEN}[INFO] Plugin exists: $plugin_name${NC}"
fi
}
# Install Zsh plugins used by the generated .zshrc
install_zsh_plugins() {
local plugins_dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins"
mkdir -p "$plugins_dir"
install_plugin "$plugins_dir" https://github.com/zsh-users/zsh-autosuggestions
install_plugin "$plugins_dir" https://github.com/zdharma-continuum/fast-syntax-highlighting
}
# Install fzf if it is missing
install_fzf() {
if check_command fzf; then
echo -e "${GREEN}[INFO] fzf already exists${NC}"
return
fi
echo -e "${YELLOW}[INFO] Installing fzf${NC}"
if [ -z "$PKG_MANAGER" ]; then
detect_pkg_manager --optional || PKG_MANAGER=""
fi
case "$PKG_MANAGER" in
apt) sudo apt install -y fzf ;;
dnf|yum) sudo "$PKG_MANAGER" install -y fzf ;;
pacman) sudo pacman -Sy --noconfirm fzf ;;
apk) sudo apk add fzf ;;
zypper) sudo zypper install -y fzf ;;
xbps) sudo xbps-install -Sy fzf ;;
brew) brew install fzf ;;
*)
if [ -d "$HOME/.fzf" ]; then
echo -e "${GREEN}[INFO] ~/.fzf already exists${NC}"
else
git clone --depth 1 https://github.com/junegunn/fzf.git "$HOME/.fzf"
fi
"$HOME/.fzf/install" --all --no-update-rc
;;
esac
}
# Main installation function
main() {
# Show warning
AUTO_CONFIRM=false
for arg in "$@"; do
if [[ "$arg" == "-y" ]]; then
AUTO_CONFIRM=true
break
fi
done
if [[ $AUTO_CONFIRM == true ]]; then
echo -e "${GREEN}[INFO] Auto-confirm enabled, skipping warnings${NC}"
else
show_warning
fi
install_dependencies
# Check current shell
local current_shell=$(basename "$SHELL")
if [[ $current_shell == "zsh" ]]; then
echo -e "${GREEN}[INFO] Already running in Zsh${NC}"
else
if ! check_command zsh; then
error_exit "Zsh installation failed"
else
echo -e "${GREEN}[INFO] Zsh installed successfully${NC}"
fi
fi
# Install Oh My Zsh
if [ ! -d "$HOME/.oh-my-zsh" ]; then
echo -e "${YELLOW}[INFO] Installing Oh My Zsh${NC}"
if check_command curl; then
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
elif check_command wget; then
sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)" "" --unattended
else
error_exit "curl or wget required to install Oh My Zsh"
fi
else
echo -e "${GREEN}[INFO] Oh My Zsh already exists${NC}"
fi
# Install plugins
install_zsh_plugins
# Install fzf
install_fzf
# Configure Zsh
local zshrc="$HOME/.zshrc"
local backup_file=""
echo -e "${YELLOW}[INFO] Configuring $zshrc${NC}"
# Backup existing config
if [ -f "$zshrc" ]; then
backup_file="${zshrc}.backup.$(date +%s)"
cp "$zshrc" "$backup_file"
echo -e "${GREEN}[INFO] Old .zshrc saved to $backup_file${NC}"
fi
# Generate new configuration
cat << "EOZSH" > "$zshrc"
# Basic configuration
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="robbyrussell"
HYPHEN_INSENSITIVE="true"
COMPLETION_WAITING_DOTS="true"
# Do not prompt for update when start, only check and reminder.
zstyle ':omz:update' mode reminder
# Plugin configuration
plugins=(
git
zsh-autosuggestions
fast-syntax-highlighting
fzf
)
# Load Oh My Zsh
source $ZSH/oh-my-zsh.sh
# Fix for slow pasting
# https://github.com/zsh-users/zsh-autosuggestions/issues/238
pasteinit() {
OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
zle -N self-insert url-quote-magic
}
pastefinish() {
zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish
EOZSH
# Set default shell if not already zsh
if [[ $current_shell != "zsh" ]]; then
echo -e "${YELLOW}[INFO] Setting Zsh as default shell${NC}"
if ! chsh -s "$(command -v zsh)"; then
echo -e "${YELLOW}[WARNING] Could not change default shell. You may need to run manually:"
echo -e "chsh -s $(command -v zsh)"
echo -e "or edit /etc/passwd${NC}"
fi
fi
# Success message
echo -e "\n${GREEN}[SUCCESS] Setup complete!${NC}"
echo -e "Restart your terminal or run: zsh"
echo -e "Edit configuration: nano $zshrc"
echo -e "Note: First launch may be slow while plugins compile"
}
# Execute main function
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment