Skip to content

Instantly share code, notes, and snippets.

@ZviBaratz
Last active March 3, 2025 18:03
Show Gist options
  • Save ZviBaratz/368984cd1df8050ec84f01c5a22cebbd to your computer and use it in GitHub Desktop.
Save ZviBaratz/368984cd1df8050ec84f01c5a22cebbd to your computer and use it in GitHub Desktop.
Terminal setup
#!/bin/bash
#
# Cross-Platform Terminal Environment Setup Script
#
# This script automates the setup of the terminal environment with:
# - ZSH shell with Oh My Zsh framework
# - Powerlevel10k theme with optimized configuration
# - MesloLGS NF fonts for proper rendering
# - Useful plugins for productivity (autosuggestions, syntax highlighting, fzf)
#
# Supported platforms:
# - Ubuntu/Debian-based distributions
# - macOS
# - Amazon Linux 2
#
# Usage:
# Direct execution:
# 1. Download the script.
# 2. Make it executable:
# chmod +x setup-terminal.sh
# 3. Run the script:
# ./setup-terminal.sh
#
# Remote execution:
# 1. Get the raw content URL from the GitHub gist (click 'Raw' button)
# 2. Execute with `curl`:
# bash -c "$(curl -fsSL <RAW_GIST_URL>)"
# or with `wget`:
# bash -c "$(wget -qO- <RAW_GIST_URL>)"
#
# Author: Zvi Baratz
# License: MIT
set -uo pipefail
# Colors
GREEN="\033[0;32m"
BLUE="\033[0;34m"
YELLOW="\033[0;33m"
GRAY="\e[38;5;248m"
BOLD="\033[1m"
RED="\033[0;31m"
CLEAR="\033[0m"
# Symbols
SUCCESS="${GREEN}✔${CLEAR}"
NO_ACTION="${GRAY}●${CLEAR}"
ERROR="${RED}✗${CLEAR}"
WARNING="${YELLOW}!${CLEAR}"
# Track if any changes were made
CHANGES_MADE=0
# Backup directory
BACKUP_DIR="$HOME/.terminal_setup_backup_$(date +%Y%m%d_%H%M%S)"
# Detected OS variables
OS_TYPE=""
OS_NAME=""
OS_VERSION=""
PKG_MANAGER=""
################################################################################
# Handles errors that occur during script execution.
#
# Args:
# line_number: The line number where the error occurred.
# command: The command that caused the error.
#
# Returns:
# None
#
# Exits:
# With the original error code.
################################################################################
handle_error()
{
local exit_code=$?
local line_number=$1
local command=$2
echo -e "\r${ERROR} Error occurred in line ${line_number}: ${command}"
exit $exit_code
}
################################################################################
# Displays a progress message with optional status.
#
# Args:
# message: The message to display.
# status: The status symbol to use (SUCCESS, NO_ACTION, ERROR).
#
# Returns:
# None
################################################################################
display_msg()
{
local message="$1"
local status="${2:-}"
if [ -n "$status" ]; then
echo -e "\r${status} ${message}"
else
echo -ne "\r${message}..."
fi
}
################################################################################
# Checks if the script is run with sudo and warns against it.
#
# Args:
# None
#
# Returns:
# None
#
# Exits:
# With code 1 if run with sudo.
################################################################################
check_sudo()
{
if [ "$(id -u)" -eq 0 ]; then
display_msg "This script should not be run directly with sudo." "$ERROR"
echo " The script will use sudo for specific commands as needed."
echo " Please run the script as your regular user."
exit 1
fi
}
################################################################################
# Creates a backup of a file if it exists.
#
# Args:
# file_path: The path to the file to back up.
#
# Returns:
# None
################################################################################
backup_file()
{
local file="$1"
if [ -f "$file" ]; then
mkdir -p "$BACKUP_DIR"
cp "$file" "$BACKUP_DIR/$(basename "$file").bak"
return 0
fi
return 1
}
################################################################################
# Detects the operating system and sets OS_TYPE, OS_NAME, and PKG_MANAGER.
#
# Args:
# None
#
# Returns:
# 0 if the OS is detected and supported.
# 1 if the OS is not supported.
################################################################################
detect_os()
{
# Check for macOS
if [ "$(uname -s)" = "Darwin" ]; then
OS_TYPE="macos"
OS_NAME="macOS"
OS_VERSION=$(sw_vers -productVersion)
PKG_MANAGER="brew"
return 0
fi
# Check for Linux distributions
if [ -f /etc/os-release ]; then
. /etc/os-release
# Check for Amazon Linux 2
if [ -f /etc/system-release ] && grep -q "Amazon Linux" /etc/system-release; then
OS_TYPE="amazon"
OS_NAME="Amazon Linux"
OS_VERSION=$(cat /etc/system-release | grep -oE '[0-9]+\.[0-9]+' | head -1)
PKG_MANAGER="yum"
return 0
# Check for Debian-based distributions
elif [[ "$ID" =~ ^(ubuntu|debian|elementary|linuxmint|pop|zorin)$ ]]; then
OS_TYPE="debian"
OS_NAME="$PRETTY_NAME"
OS_VERSION="$VERSION_ID"
PKG_MANAGER="apt"
return 0
fi
fi
# Unknown or unsupported OS
OS_TYPE="unknown"
OS_NAME="Unknown OS"
display_msg "Your operating system could not be detected or is not officially supported." "$WARNING"
echo " This script officially supports Ubuntu/Debian-based systems, macOS, and Amazon Linux 2."
read -p " Do you want to continue anyway? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
display_msg "Installation aborted by user." "$ERROR"
exit 1
fi
# Try to determine package manager for unknown Linux
if command -v apt >/dev/null 2>&1; then
PKG_MANAGER="apt"
elif command -v yum >/dev/null 2>&1; then
PKG_MANAGER="yum"
elif command -v dnf >/dev/null 2>&1; then
PKG_MANAGER="dnf"
else
display_msg "Could not determine package manager for your system" "$ERROR"
exit 1
fi
return 0
}
################################################################################
# Installs Homebrew on macOS if it's not already installed.
#
# Args:
# None
#
# Returns:
# 0 if Homebrew is installed successfully or already present.
# 1 if installation fails.
################################################################################
install_homebrew()
{
if [ "$OS_TYPE" != "macos" ]; then
return 0
fi
if command -v brew >/dev/null 2>&1; then
display_msg "Homebrew is already installed" "$NO_ACTION"
return 0
fi
display_msg "Installing Homebrew"
local install_output
install_output=$(/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2>&1)
local install_status=$?
if [ $install_status -ne 0 ]; then
display_msg "Failed to install Homebrew" "$ERROR"
echo " Error output: $install_output"
return 1
fi
# Add Homebrew to PATH (this will only take effect in new terminal sessions)
if [ -d "/opt/homebrew/bin" ]; then
# For Apple Silicon Macs
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >>"$HOME/.zprofile"
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -d "/usr/local/bin" ]; then
# For Intel Macs
echo 'eval "$(/usr/local/bin/brew shellenv)"' >>"$HOME/.zprofile"
eval "$(/usr/local/bin/brew shellenv)"
fi
display_msg "Homebrew installed successfully" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Updates the package list and calculates if updates were available.
#
# Args:
# None
#
# Returns:
# 0 if successful.
# 1 if update fails.
################################################################################
update_packages()
{
display_msg "Updating package list"
local update_output=""
local update_status=0
case "$PKG_MANAGER" in
apt)
update_output=$(sudo apt update 2>&1)
update_status=$?
;;
yum)
update_output=$(sudo yum check-update -y 2>&1) || true
# yum check-update returns 100 if updates are available, which is not an error
if [ $? -ne 0 ] && [ $? -ne 100 ]; then
update_status=1
fi
;;
brew)
update_output=$(brew update 2>&1)
update_status=$?
;;
*)
display_msg "Unknown package manager: $PKG_MANAGER" "$ERROR"
return 1
;;
esac
if [ $update_status -ne 0 ]; then
display_msg "Failed to update package list" "$ERROR"
echo " Error output: $update_output"
return 1
fi
display_msg "Package list refreshed" "$SUCCESS"
return 0
}
################################################################################
# Installs a package if it is not already installed.
#
# Args:
# cmd: The command to check for existence.
# package_name: The name of the package to install (defaults to cmd if not provided).
# alt_pkg_names: Optional alternative package names for different package managers.
#
# Returns:
# 0 if installation successful or package already installed.
# 1 if installation fails.
################################################################################
install_package()
{
local cmd="${1}"
local default_pkg="${2:-$1}"
# Define platform-specific package names
local debian_pkg="${3:-$default_pkg}"
local amazon_pkg="${4:-$default_pkg}"
local macos_pkg="${5:-$default_pkg}"
# Select the appropriate package name based on OS
local package_name=""
case "$OS_TYPE" in
debian)
package_name="$debian_pkg"
;;
amazon)
package_name="$amazon_pkg"
;;
macos)
package_name="$macos_pkg"
;;
*)
package_name="$default_pkg"
;;
esac
if command -v "${cmd}" >/dev/null 2>&1; then
display_msg "${cmd} is already installed" "$NO_ACTION"
return 0
fi
display_msg "Installing ${cmd}"
local install_output=""
local install_status=0
case "$PKG_MANAGER" in
apt)
install_output=$(sudo apt install -y "${package_name}" 2>&1)
install_status=$?
;;
yum)
install_output=$(sudo yum install -y "${package_name}" 2>&1)
install_status=$?
;;
brew)
install_output=$(brew install "${package_name}" 2>&1)
install_status=$?
;;
*)
display_msg "Unknown package manager: $PKG_MANAGER" "$ERROR"
return 1
;;
esac
if [ $install_status -ne 0 ]; then
display_msg "Failed to install ${cmd}" "$ERROR"
echo " Error output: $install_output"
return 1
fi
if ! command -v "${cmd}" >/dev/null 2>&1; then
display_msg "Package ${package_name} was installed but ${cmd} command is not available" "$ERROR"
return 1
fi
display_msg "${cmd} installed successfully" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Installs Oh My Zsh if not already installed.
#
# Args:
# None
#
# Returns:
# 0 if installation successful or already installed.
# 1 if installation fails.
################################################################################
install_oh_my_zsh()
{
if [ -d "$HOME/.oh-my-zsh" ]; then
display_msg "Oh My Zsh is already installed" "$NO_ACTION"
return 0
fi
display_msg "Installing Oh My Zsh"
# Backup .zshrc if it exists
backup_file "$HOME/.zshrc"
# Using curl with error handling
local install_output
install_output=$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh 2>&1)
if [ $? -ne 0 ]; then
display_msg "Failed to download Oh My Zsh installation script" "$ERROR"
echo " Error output: $install_output"
return 1
fi
# Install Oh My Zsh
local omz_install_output
omz_install_output=$(RUNZSH=no KEEP_ZSHRC=yes sh -c "$install_output" 2>&1)
local omz_status=$?
if [ $omz_status -ne 0 ]; then
display_msg "Failed to install Oh My Zsh" "$ERROR"
echo " Error output: $omz_install_output"
return 1
fi
display_msg "Oh My Zsh installed successfully" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Installs Powerlevel10k theme for Oh My Zsh.
#
# Args:
# None
#
# Returns:
# 0 if installation successful or already installed.
# 1 if installation fails.
################################################################################
install_powerlevel10k()
{
local p10k_dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k"
if [ -d "$p10k_dir" ] && [ -n "$(ls -A "$p10k_dir" 2>/dev/null)" ]; then
display_msg "Powerlevel10k is already installed" "$NO_ACTION"
else
display_msg "Installing Powerlevel10k"
local clone_output
clone_output=$(git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "$p10k_dir" 2>&1)
local clone_status=$?
if [ $clone_status -ne 0 ]; then
display_msg "Failed to install Powerlevel10k" "$ERROR"
echo " Error output: $clone_output"
return 1
fi
# Check if the p10k.zsh source line already exists in .zshrc to avoid duplicates
if ! grep -q "source.*p10k.zsh" "$HOME/.zshrc"; then
echo '[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh' >>"$HOME/.zshrc"
fi
display_msg "Powerlevel10k installed successfully" "$SUCCESS"
CHANGES_MADE=1
fi
return 0
}
################################################################################
# Downloads and installs the p10k configuration file.
#
# Args:
# None
#
# Returns:
# 0 if configuration is installed successfully or already present.
# 1 if installation fails.
################################################################################
install_p10k_config()
{
if [ -f "$HOME/.p10k.zsh" ]; then
display_msg "Existing Powerlevel10k configuration file found" "$NO_ACTION"
return 0
fi
display_msg "Downloading p10k configuration"
local p10k_config_url="https://gist.githubusercontent.com/ZviBaratz/9529600d91695315c224263808b13ded/raw/64238295b34e3643ece0819f7a6a5f319a0e9b43/.p10k.zsh"
local download_output
download_output=$(wget -q -O "$HOME/.p10k.zsh" "$p10k_config_url" 2>&1)
local download_status=$?
if [ $download_status -ne 0 ]; then
display_msg "Failed to download p10k configuration" "$ERROR"
echo " Error output: $download_output"
return 1
fi
if [ ! -s "$HOME/.p10k.zsh" ]; then
display_msg "Downloaded p10k configuration file is empty" "$ERROR"
return 1
fi
display_msg "p10k configuration downloaded successfully" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Sets the ZSH theme to Powerlevel10k in the .zshrc file.
#
# Args:
# None
#
# Returns:
# 0 if theme is set successfully or already set.
# 1 if setting the theme fails.
################################################################################
set_zsh_theme()
{
# First check if the .zshrc file exists
if [ ! -f "$HOME/.zshrc" ]; then
display_msg "No .zshrc file found, cannot set theme" "$ERROR"
return 1
fi
# Use direct approach - look for any line that:
# 1. Isn't commented (doesn't start with #)
# 2. Contains ZSH_THEME=
# 3. Contains powerlevel10k
if grep -v "^[[:space:]]*#" "$HOME/.zshrc" | grep -q "ZSH_THEME.*powerlevel10k"; then
display_msg "Zsh theme already set to Powerlevel10k" "$NO_ACTION"
return 0
fi
display_msg "Setting Zsh theme to Powerlevel10k"
# Backup .zshrc before modifying
backup_file "$HOME/.zshrc"
# Handle macOS sed differences
if [ "$OS_TYPE" = "macos" ]; then
sed -i '' 's/^ZSH_THEME=.*$/ZSH_THEME="powerlevel10k\/powerlevel10k"/' "$HOME/.zshrc"
else
sed -i 's/^ZSH_THEME=.*$/ZSH_THEME="powerlevel10k\/powerlevel10k"/' "$HOME/.zshrc"
fi
# Check if the sed command actually made a change
if ! grep -q 'ZSH_THEME="powerlevel10k/powerlevel10k"' "$HOME/.zshrc"; then
# If sed didn't work (perhaps because there was no ZSH_THEME line),
# append the theme to the end of the file
echo 'ZSH_THEME="powerlevel10k/powerlevel10k"' >>"$HOME/.zshrc"
fi
display_msg "Zsh theme set to Powerlevel10k" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Returns the appropriate font directory for the current OS.
#
# Args:
# None
#
# Returns:
# The path to the font directory.
################################################################################
get_font_dir()
{
case "$OS_TYPE" in
macos)
echo "$HOME/Library/Fonts"
;;
*)
echo "$HOME/.fonts"
;;
esac
}
################################################################################
# Downloads and installs the MesloLGS NF fonts for Powerlevel10k.
#
# Args:
# None
#
# Returns:
# 0 if fonts are installed successfully or already present.
# 1 if any step of the installation fails.
################################################################################
install_p10k_fonts()
{
local fonts_dir=$(get_font_dir)
local fonts_downloaded=0
local p10k_media_url="https://github.com/romkatv/powerlevel10k-media/raw/master"
# Create fonts directory if it doesn't exist
if ! mkdir -p "$fonts_dir"; then
display_msg "Failed to create fonts directory" "$ERROR"
return 1
fi
# Download each font variant
for font in "Regular" "Bold" "Italic" "Bold Italic"; do
local font_file="MesloLGS NF ${font}.ttf"
local font_path="${fonts_dir}/${font_file}"
local font_url="${font// /%20}"
if [ -f "$font_path" ]; then
display_msg "Font ${font_file} already exists" "$NO_ACTION"
continue
fi
display_msg "Downloading ${font_file}"
local download_output
download_output=$(wget --no-clobber --quiet \
-O "$font_path" \
"${p10k_media_url}/MesloLGS%20NF%20${font_url}.ttf" 2>&1)
local download_status=$?
if [ $download_status -ne 0 ]; then
display_msg "Failed to download ${font_file}" "$ERROR"
echo " Error output: $download_output"
return 1
fi
display_msg "${font_file} downloaded successfully" "$SUCCESS"
fonts_downloaded=1
CHANGES_MADE=1
done
# Update font cache if new fonts were downloaded and OS is not macOS
if [ "$fonts_downloaded" -eq 1 ] && [ "$OS_TYPE" != "macos" ]; then
display_msg "Updating font cache"
local fc_output
fc_output=$(fc-cache -f -v 2>&1)
local fc_status=$?
if [ $fc_status -ne 0 ]; then
display_msg "Failed to update font cache" "$ERROR"
echo " Error output: $fc_output"
return 1
fi
display_msg "Font cache updated successfully" "$SUCCESS"
else
display_msg "All MesloLGS NF fonts are already installed" "$NO_ACTION"
fi
return 0
}
################################################################################
# Installs a Zsh plugin and adds it to the .zshrc configuration.
#
# Args:
# plugin_name: The name of the plugin to install.
# repo_url: The Git repository URL of the plugin.
#
# Returns:
# 0 if plugin is installed successfully or already present.
# 1 if installation or configuration fails.
################################################################################
install_zsh_plugin()
{
local plugin_name="$1"
local repo_url="$2"
local plugin_dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/${plugin_name}"
if [ -d "$plugin_dir" ] && [ -n "$(ls -A "$plugin_dir" 2>/dev/null)" ]; then
display_msg "${plugin_name} plugin is already installed" "$NO_ACTION"
return 0
fi
display_msg "Installing ${plugin_name} plugin"
local clone_output
clone_output=$(git clone "$repo_url" "$plugin_dir" 2>&1)
local clone_status=$?
if [ $clone_status -ne 0 ]; then
display_msg "Failed to install ${plugin_name} plugin" "$ERROR"
echo " Error output: $clone_output"
return 1
fi
# Add plugin to .zshrc plugins list if not already present
if ! grep -q "${plugin_name}" "$HOME/.zshrc"; then
# Backup .zshrc before modifying
backup_file "$HOME/.zshrc"
# More robust plugin addition using awk
awk -v plugin="$plugin_name" '
/^plugins=\(/ {
# Check if line ends with closing parenthesis
if ($0 ~ /\)$/) {
# Remove trailing parenthesis, add plugin and closing parenthesis
sub(/\)$/, " " plugin ")")
} else {
# This is a multi-line plugin declaration, just add to the first line
sub(/$/, " " plugin)
}
}
{ print }
' "$HOME/.zshrc" >"$HOME/.zshrc.tmp"
if [ $? -ne 0 ]; then
display_msg "Failed to modify plugins in .zshrc" "$ERROR"
rm -f "$HOME/.zshrc.tmp"
return 1
fi
mv "$HOME/.zshrc.tmp" "$HOME/.zshrc"
fi
display_msg "${plugin_name} plugin installed successfully" "$SUCCESS"
CHANGES_MADE=1
return 0
}
################################################################################
# Sets the default shell to Zsh if it isn't already.
#
# Args:
# None
#
# Returns:
# 0 if shell is set successfully or already set to Zsh.
# 1 if setting the shell fails.
################################################################################
set_default_shell()
{
local zsh_path
zsh_path=$(which zsh)
# Check if zsh is already the default shell
if [[ "$SHELL" == *zsh* ]] || grep -q "^${USER}.*zsh$" /etc/passwd 2>/dev/null; then
display_msg "Default shell is already Zsh" "$NO_ACTION"
return 0
fi
display_msg "Setting default shell to Zsh"
local chsh_output
local chsh_status
# Different commands for different OS types
case "$OS_TYPE" in
macos)
# macOS doesn't need sudo for chsh
chsh_output=$(chsh -s "$zsh_path" 2>&1)
chsh_status=$?
;;
amazon)
# For Amazon Linux, check if zsh is in /etc/shells
if ! grep -q "^$zsh_path$" /etc/shells; then
echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
fi
# Try to change the shell using chsh first (this might not work in all EC2 environments)
chsh_output=$(sudo chsh -s "$zsh_path" "$USER" 2>&1) || true
chsh_status=$?
# Track if we actually made changes
local files_changed=0
# Make sure to add to all possible startup files for EC2 instances
for file in ~/.bash_profile ~/.bashrc ~/.profile; do
if [ -f "$file" ] && ! grep -q "# Start zsh as default shell (added by terminal setup script)" "$file"; then
# Back up the file
cp "$file" "${file}.bak"
# Add the exec zsh command but allow for a way to bypass it if needed
echo "" >>"$file"
echo "# Start zsh as default shell (added by terminal setup script)" >>"$file"
echo "if [ -x $(which zsh) ] && [[ \"\$ZSH_VERSION\" == \"\" ]] && [[ \"\$TERM_PROGRAM\" != \"vscode\" ]] && [[ -z \"\$BASH_ONLY\" ]]; then" >>"$file"
echo " export SHELL=$(which zsh)" >>"$file"
echo " exec zsh" >>"$file"
echo "fi" >>"$file"
files_changed=1
fi
done
if [ $files_changed -eq 1 ]; then
display_msg "Configured login files to start Zsh" "$SUCCESS"
CHANGES_MADE=1
else
display_msg "Login files already configured for Zsh" "$NO_ACTION"
fi
;;
*)
# Other Linux systems
chsh_output=$(sudo chsh -s "$zsh_path" "$USER" 2>&1)
chsh_status=$?
;;
esac
if [ $chsh_status -ne 0 ] && [ "$OS_TYPE" != "amazon" ]; then
display_msg "Failed to change default shell to Zsh" "$WARNING"
echo " This is a common issue on some systems."
echo " You can manually change your shell by running: chsh -s $(which zsh)"
echo " Alternatively, you can add 'exec zsh' to your .bashrc to automatically start zsh"
# Add exec zsh to bashrc if it doesn't exist
if [ ! -f "$HOME/.bashrc" ] || ! grep -q "exec zsh" "$HOME/.bashrc"; then
echo "# Auto-start zsh (added by terminal setup script)" >>"$HOME/.bashrc"
echo "[ -f $(which zsh) ] && exec zsh" >>"$HOME/.bashrc"
display_msg "Added 'exec zsh' to .bashrc as a fallback" "$SUCCESS"
CHANGES_MADE=1
fi
elif [ "$OS_TYPE" != "amazon" ]; then
display_msg "Default shell set to Zsh" "$SUCCESS"
CHANGES_MADE=1
fi
return 0
}
################################################################################
# Main function that runs the script.
#
# Args:
# None
#
# Returns:
# 0 if all steps complete successfully.
# Various error codes if any step fails.
################################################################################
main()
{
# Set up error handling
trap 'handle_error ${LINENO} "$BASH_COMMAND"' ERR
echo -e "${BOLD}Cross-Platform Terminal Environment Setup${CLEAR}"
echo "This script will set up the terminal environment with Zsh, Oh My Zsh, and Powerlevel10k."
# Preliminary checks
check_sudo
detect_os
echo -e "${BLUE}${BOLD}Detected OS:${CLEAR} $OS_NAME"
# Create a section separator for visual organization
echo -e "\n${BLUE}${BOLD}System Preparation${CLEAR}"
# Install Homebrew for macOS
if [ "$OS_TYPE" = "macos" ]; then
install_homebrew
fi
# Update package repositories
update_packages
# Install required packages
echo -e "\n${BLUE}${BOLD}Installing Required Packages${CLEAR}"
# Install fontconfig (not needed on macOS)
if [ "$OS_TYPE" != "macos" ]; then
install_package "fc-cache" "fontconfig" "fontconfig" "fontconfig"
fi
# Install other required packages with platform-specific names
install_package "zsh" "zsh" "zsh" "zsh" "zsh"
install_package "git" "git" "git" "git" "git"
install_package "wget" "wget" "wget" "wget" "wget"
# Handle fzf installation differently based on OS
if [ "$OS_TYPE" = "amazon" ]; then
display_msg "Installing fzf on Amazon Linux 2"
# Check if fzf is already installed
if command -v fzf >/dev/null 2>&1; then
display_msg "fzf is already installed" "$NO_ACTION"
else
# Install fzf from git for Amazon Linux
if [ ! -d "$HOME/.fzf" ]; then
# Suppress detailed output
git clone --depth 1 https://github.com/junegunn/fzf.git "$HOME/.fzf" >/dev/null 2>&1
"$HOME/.fzf/install" --all >/dev/null 2>&1
display_msg "fzf installed successfully" "$SUCCESS"
CHANGES_MADE=1
else
display_msg "fzf directory exists but command not found, running installer"
"$HOME/.fzf/install" --all >/dev/null 2>&1
display_msg "fzf installed successfully" "$SUCCESS"
CHANGES_MADE=1
fi
fi
else
# For other systems, use package manager
install_package "fzf" "fzf" "fzf" "fzf" "fzf"
fi
install_package "curl" "curl" "curl" "curl" "curl"
# Install Oh My Zsh and configure it
echo -e "\n${BLUE}${BOLD}Setting Up Zsh Environment${CLEAR}"
install_oh_my_zsh
install_powerlevel10k
install_p10k_config
set_zsh_theme
# Install fonts
echo -e "\n${BLUE}${BOLD}Installing Custom Fonts${CLEAR}"
install_p10k_fonts
# Install plugins
echo -e "\n${BLUE}${BOLD}Installing Zsh Plugins${CLEAR}"
install_zsh_plugin "zsh-autosuggestions" "https://github.com/zsh-users/zsh-autosuggestions"
install_zsh_plugin "zsh-fzf-history-search" "https://github.com/joshskidmore/zsh-fzf-history-search"
install_zsh_plugin "zsh-syntax-highlighting" "https://github.com/zsh-users/zsh-syntax-highlighting.git"
# Set default shell
echo -e "\n${BLUE}${BOLD}Finalizing Setup${CLEAR}"
set_default_shell
# Display completion message
echo
if [ "$CHANGES_MADE" -eq 1 ]; then
echo -e "${GREEN}${BOLD}✨ Terminal setup completed successfully! ✨${CLEAR}"
# Check if backup was created
if [ -d "$BACKUP_DIR" ]; then
echo -e "${YELLOW}Backup of original configuration files created at:${CLEAR}"
echo " $BACKUP_DIR"
fi
echo -e "\n${BOLD}Next steps:${CLEAR}"
echo "1. Close this terminal and open a new one to activate Zsh"
echo "2. If the Powerlevel10k configuration wizard starts, follow the prompts to customize your theme"
echo "3. Alternatively, your terminal should already be configured with the downloaded settings"
echo
echo -e "${YELLOW}Note:${CLEAR} To see all the new features, make sure your terminal app is using one of the MesloLGS NF fonts"
# Platform-specific instructions
case "$OS_TYPE" in
macos)
echo -e "\n${BOLD}macOS-Specific Instructions:${CLEAR}"
echo "1. Open Terminal.app preferences"
echo "2. Go to 'Profiles' > Select your profile > 'Text'"
echo "3. Click 'Change...' next to the font and select 'MesloLGS NF'"
;;
amazon)
echo -e "\n${BOLD}Amazon Linux-Specific Instructions:${CLEAR}"
echo "1. If using EC2 with SSH, configure your local terminal to use MesloLGS NF font"
echo "2. For AWS CloudShell, you may need to adjust font settings in your browser"
;;
esac
else
echo -e "${BOLD}Terminal setup completed (no changes needed)${CLEAR}"
echo "Your system is already configured with all the requested components."
fi
return 0
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment