|
#!/bin/bash |
|
|
|
# Zsh Installation Script with Oh-My-Zsh and Plugins |
|
# Installs latest Zsh from source, Oh-My-Zsh, plugins, and themes |
|
|
|
set -euo pipefail # Exit on error, undefined vars, pipe failures |
|
|
|
# Configuration |
|
readonly SCRIPT_NAME="${BASH_SOURCE[0]:-${0##*/}}" |
|
readonly TEMP_DIR=$(mktemp -d) |
|
readonly VERSION_API="https://version-release-watchdog.onrender.com/zsh" |
|
readonly ZSH_BASE_URL="https://sourceforge.net/projects/zsh/files/zsh" |
|
readonly OMZ_INSTALL_URL="https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh" |
|
|
|
# Colors for output |
|
readonly RED='\033[0;31m' |
|
readonly GREEN='\033[0;32m' |
|
readonly YELLOW='\033[1;33m' |
|
readonly BLUE='\033[0;34m' |
|
readonly PURPLE='\033[0;35m' |
|
readonly NC='\033[0m' # No Color |
|
|
|
# Global variables |
|
ZSH_VERSION="" |
|
INSTALL_HOMEBREW=false |
|
SKIP_PACKAGES=false |
|
SKIP_GIT_CONFIG=false |
|
SKIP_SHELL_CHANGE=false |
|
CUSTOM_CONFIG=false |
|
SKIP_XCLIP=false |
|
|
|
# Configuration files from gist |
|
declare -A CONFIG_FILES=( |
|
[".alias"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/alias" |
|
[".func"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/func" |
|
[".pathrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/pathrc" |
|
[".sourcerc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/sourcerc" |
|
[".vimrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/vimrc" |
|
[".zshrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/zshrc" |
|
) |
|
|
|
# Logging functions |
|
log_info() { |
|
echo -e "${BLUE}[INFO]${NC} $1" >&2 |
|
} |
|
|
|
log_success() { |
|
echo -e "${GREEN}[SUCCESS]${NC} $1" >&2 |
|
} |
|
|
|
log_warn() { |
|
echo -e "${YELLOW}[WARN]${NC} $1" >&2 |
|
} |
|
|
|
log_error() { |
|
echo -e "${RED}[ERROR]${NC} $1" >&2 |
|
} |
|
|
|
log_step() { |
|
echo -e "${PURPLE}[STEP]${NC} $1" >&2 |
|
} |
|
|
|
# Detect operating system |
|
detect_os() { |
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then |
|
if [[ -f /etc/os-release ]]; then |
|
. /etc/os-release |
|
echo "$ID" |
|
elif [[ -f /etc/debian_version ]]; then |
|
echo "debian" |
|
elif [[ -f /etc/redhat-release ]]; then |
|
echo "rhel" |
|
else |
|
echo "linux" |
|
fi |
|
elif [[ "$OSTYPE" == "darwin"* ]]; then |
|
echo "macos" |
|
elif [[ "$OSTYPE" == "cygwin" ]]; then |
|
echo "cygwin" |
|
elif [[ "$OSTYPE" == "msys" ]]; then |
|
echo "msys" |
|
else |
|
echo "unknown" |
|
fi |
|
} |
|
|
|
# Check if xclip is installed |
|
is_xclip_installed() { |
|
command -v xclip >/dev/null 2>&1 |
|
} |
|
|
|
# Show usage information |
|
show_usage() { |
|
cat << EOF |
|
Usage: $SCRIPT_NAME [OPTIONS] |
|
|
|
Install Zsh from source with Oh-My-Zsh, plugins, and themes. |
|
|
|
Options: |
|
-h, --help Show this help message |
|
-v, --version VERSION Specify Zsh version to install |
|
--with-homebrew Install Homebrew (interactive prompt by default) |
|
--skip-packages Skip system package installation |
|
--skip-git Skip Git configuration |
|
--skip-shell-change Don't change default shell to Zsh |
|
--skip-xclip Skip xclip installation prompt (Ubuntu only) |
|
--custom-config Use custom configuration files from gist |
|
--git-name NAME Set Git user name (default: prompt) |
|
--git-email EMAIL Set Git user email (default: prompt) |
|
|
|
Examples: |
|
$SCRIPT_NAME # Interactive installation |
|
$SCRIPT_NAME --with-homebrew --custom-config # Install with Homebrew and custom configs |
|
$SCRIPT_NAME -v 5.8.1 --skip-packages # Install specific version, skip packages |
|
$SCRIPT_NAME --skip-xclip # Skip xclip installation |
|
EOF |
|
} |
|
|
|
# Cleanup function |
|
cleanup() { |
|
local exit_code=$? |
|
log_info "Cleaning up temporary files..." |
|
rm -rf "$TEMP_DIR" |
|
if [[ $exit_code -ne 0 ]]; then |
|
log_error "Script failed with exit code $exit_code" |
|
fi |
|
exit $exit_code |
|
} |
|
|
|
# Set up cleanup trap |
|
trap cleanup EXIT |
|
|
|
# Parse command line arguments |
|
parse_arguments() { |
|
local custom_version="" |
|
local git_name="" |
|
local git_email="" |
|
|
|
while [[ $# -gt 0 ]]; do |
|
case $1 in |
|
-h|--help) |
|
show_usage |
|
exit 0 |
|
;; |
|
-v|--version) |
|
custom_version="$2" |
|
shift 2 |
|
;; |
|
--with-homebrew) |
|
INSTALL_HOMEBREW=true |
|
shift |
|
;; |
|
--skip-packages) |
|
SKIP_PACKAGES=true |
|
shift |
|
;; |
|
--skip-git) |
|
SKIP_GIT_CONFIG=true |
|
shift |
|
;; |
|
--skip-shell-change) |
|
SKIP_SHELL_CHANGE=true |
|
shift |
|
;; |
|
--skip-xclip) |
|
SKIP_XCLIP=true |
|
shift |
|
;; |
|
--custom-config) |
|
CUSTOM_CONFIG=true |
|
shift |
|
;; |
|
--git-name) |
|
git_name="$2" |
|
shift 2 |
|
;; |
|
--git-email) |
|
git_email="$2" |
|
shift 2 |
|
;; |
|
*) |
|
log_error "Unknown option: $1" |
|
show_usage |
|
exit 1 |
|
;; |
|
esac |
|
done |
|
|
|
# Export variables |
|
export CUSTOM_ZSH_VERSION="$custom_version" |
|
export GIT_USER_NAME="$git_name" |
|
export GIT_USER_EMAIL="$git_email" |
|
} |
|
|
|
# Check system requirements |
|
check_requirements() { |
|
log_info "Checking system requirements..." |
|
|
|
local os_type |
|
os_type=$(detect_os) |
|
|
|
log_info "Detected OS: $os_type" |
|
|
|
# Check if we're on a supported system |
|
if [[ "$os_type" != "ubuntu" && "$os_type" != "debian" ]]; then |
|
if ! command -v apt-get >/dev/null 2>&1; then |
|
log_error "This script requires apt-get (Debian/Ubuntu-based system)" |
|
return 1 |
|
fi |
|
fi |
|
|
|
# Check if running as root |
|
if [[ $EUID -eq 0 ]]; then |
|
log_error "This script should not be run as root" |
|
return 1 |
|
fi |
|
|
|
# Check sudo access |
|
if ! sudo -n true 2>/dev/null; then |
|
log_info "This script requires sudo access. You may be prompted for your password." |
|
fi |
|
|
|
log_success "System requirements check passed" |
|
} |
|
|
|
# Update system packages |
|
update_system() { |
|
if [[ "$SKIP_PACKAGES" == "true" ]]; then |
|
log_info "Skipping system package updates" |
|
return 0 |
|
fi |
|
|
|
log_step "Updating system packages..." |
|
|
|
if ! sudo apt-get update -y; then |
|
log_error "Failed to update package list" |
|
return 1 |
|
fi |
|
|
|
if ! sudo apt-get upgrade -y; then |
|
log_error "Failed to upgrade packages" |
|
return 1 |
|
fi |
|
|
|
log_success "System packages updated" |
|
} |
|
|
|
# Install xclip for Ubuntu systems |
|
install_xclip() { |
|
local os_type |
|
os_type=$(detect_os) |
|
|
|
# Only install xclip on Ubuntu/Debian systems |
|
if [[ "$os_type" != "ubuntu" && "$os_type" != "debian" ]]; then |
|
log_info "xclip installation is only supported on Ubuntu/Debian systems (detected: $os_type)" |
|
return 0 |
|
fi |
|
|
|
# Skip if packages are being skipped or xclip installation is explicitly skipped |
|
if [[ "$SKIP_PACKAGES" == "true" || "$SKIP_XCLIP" == "true" ]]; then |
|
log_info "Skipping xclip installation" |
|
return 0 |
|
fi |
|
|
|
# Check if xclip is already installed |
|
if is_xclip_installed; then |
|
log_info "xclip is already installed" |
|
return 0 |
|
fi |
|
|
|
log_step "Checking xclip installation..." |
|
|
|
# Prompt user for xclip installation |
|
local response |
|
cat << EOF |
|
${YELLOW}xclip utility information:${NC} |
|
xclip is a command line utility that allows you to copy and paste |
|
text to/from the X11 clipboard from the terminal. It's useful for |
|
copying command outputs or file contents directly to your clipboard. |
|
|
|
Example usage: |
|
echo "Hello World" | xclip -selection clipboard |
|
cat file.txt | xclip -sel c |
|
|
|
EOF |
|
|
|
read -p "Do you want to install xclip? (y/N): " response |
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then |
|
log_info "Skipping xclip installation" |
|
return 0 |
|
fi |
|
|
|
log_info "Installing xclip..." |
|
|
|
if ! sudo apt-get install -y xclip; then |
|
log_error "Failed to install xclip" |
|
return 1 |
|
fi |
|
|
|
log_success "xclip installed successfully" |
|
|
|
# Show usage tip |
|
cat << EOF |
|
${GREEN}xclip installed!${NC} You can now use commands like: |
|
${BLUE}echo "text" | xclip -selection clipboard${NC} # Copy to clipboard |
|
${BLUE}xclip -selection clipboard -o${NC} # Paste from clipboard |
|
|
|
EOF |
|
} |
|
|
|
# Install required packages |
|
install_packages() { |
|
if [[ "$SKIP_PACKAGES" == "true" ]]; then |
|
log_info "Skipping package installation" |
|
return 0 |
|
fi |
|
|
|
log_step "Installing required packages..." |
|
|
|
local packages=( |
|
"vim" |
|
"git" |
|
"zip" |
|
"unzip" |
|
"curl" |
|
"wget" |
|
"build-essential" |
|
"libncurses5-dev" |
|
"libncursesw5-dev" |
|
"libtinfo-dev" |
|
"libgdbm-dev" |
|
"libpcre3-dev" |
|
"xz-utils" |
|
) |
|
|
|
if ! sudo apt-get install -y "${packages[@]}"; then |
|
log_error "Failed to install required packages" |
|
return 1 |
|
fi |
|
|
|
log_success "Required packages installed" |
|
} |
|
|
|
# Configure Git |
|
configure_git() { |
|
if [[ "$SKIP_GIT_CONFIG" == "true" ]]; then |
|
log_info "Skipping Git configuration" |
|
return 0 |
|
fi |
|
|
|
log_step "Configuring Git..." |
|
|
|
# Set system-wide editor |
|
sudo git config --system core.editor "vim" |
|
|
|
# Get user name and email |
|
local git_name="$GIT_USER_NAME" |
|
local git_email="$GIT_USER_EMAIL" |
|
|
|
if [[ -z "$git_name" ]]; then |
|
read -p "Enter your Git user name: " git_name |
|
if [[ -z "$git_name" ]]; then |
|
log_warn "Git user name not provided, skipping Git user configuration" |
|
return 0 |
|
fi |
|
fi |
|
|
|
if [[ -z "$git_email" ]]; then |
|
read -p "Enter your Git email: " git_email |
|
if [[ -z "$git_email" ]]; then |
|
log_warn "Git email not provided, skipping Git user configuration" |
|
return 0 |
|
fi |
|
fi |
|
|
|
# Set global Git configuration |
|
git config --global user.name "$git_name" |
|
git config --global user.email "$git_email" |
|
|
|
log_success "Git configured with user: $git_name <$git_email>" |
|
} |
|
|
|
# Install Homebrew |
|
install_homebrew() { |
|
if [[ "$INSTALL_HOMEBREW" != "true" ]]; then |
|
local response |
|
read -p "Do you want to install Homebrew? (y/N): " response |
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then |
|
log_info "Skipping Homebrew installation" |
|
return 0 |
|
fi |
|
fi |
|
|
|
log_step "Installing Homebrew..." |
|
|
|
if command -v brew >/dev/null 2>&1; then |
|
log_info "Homebrew is already installed" |
|
return 0 |
|
fi |
|
|
|
# Install Homebrew |
|
if ! /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then |
|
log_error "Failed to install Homebrew" |
|
return 1 |
|
fi |
|
|
|
# Add Homebrew to PATH |
|
local brew_paths=( |
|
"/home/linuxbrew/.linuxbrew/bin/brew" |
|
"/opt/homebrew/bin/brew" |
|
) |
|
|
|
for brew_path in "${brew_paths[@]}"; do |
|
if [[ -x "$brew_path" ]]; then |
|
eval "$($brew_path shellenv)" |
|
log_success "Homebrew installed and configured" |
|
return 0 |
|
fi |
|
done |
|
|
|
log_warn "Homebrew installed but not found in expected locations" |
|
log_info "Please restart your terminal or add Homebrew to your PATH manually" |
|
} |
|
|
|
# Get Zsh version |
|
get_zsh_version() { |
|
if [[ -n "$CUSTOM_ZSH_VERSION" ]]; then |
|
ZSH_VERSION="$CUSTOM_ZSH_VERSION" |
|
log_info "Using specified Zsh version: $ZSH_VERSION" |
|
else |
|
log_step "Fetching latest Zsh version..." |
|
|
|
local response |
|
if ! response=$(curl -s -w "\n%{http_code}" "$VERSION_API"); then |
|
log_error "Failed to fetch Zsh version from API" |
|
return 1 |
|
fi |
|
|
|
local http_code=$(echo "$response" | tail -n1) |
|
local version_info=$(echo "$response" | sed '$d') |
|
|
|
if [[ "$http_code" != "200" ]]; then |
|
log_error "API returned HTTP $http_code" |
|
return 1 |
|
fi |
|
|
|
if [[ -z "$version_info" ]]; then |
|
log_error "Empty version response" |
|
return 1 |
|
fi |
|
|
|
ZSH_VERSION="$version_info" |
|
log_info "Latest Zsh version: $ZSH_VERSION" |
|
fi |
|
|
|
# Validate version format |
|
if ! [[ "$ZSH_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then |
|
log_error "Invalid Zsh version format: $ZSH_VERSION" |
|
return 1 |
|
fi |
|
} |
|
|
|
# Download and build Zsh |
|
install_zsh() { |
|
log_step "Installing Zsh $ZSH_VERSION from source..." |
|
|
|
cd "$TEMP_DIR" |
|
|
|
# Download Zsh source |
|
local filename="zsh-${ZSH_VERSION}.tar.xz" |
|
local url="${ZSH_BASE_URL}/${ZSH_VERSION}/${filename}/download" |
|
|
|
log_info "Downloading Zsh source..." |
|
if ! curl -fL --progress-bar -o "$filename" "$url"; then |
|
log_error "Failed to download Zsh source" |
|
return 1 |
|
fi |
|
|
|
# Extract |
|
log_info "Extracting Zsh source..." |
|
if ! tar -xf "$filename"; then |
|
log_error "Failed to extract Zsh source" |
|
return 1 |
|
fi |
|
|
|
# Build and install |
|
cd "zsh-${ZSH_VERSION}" |
|
|
|
log_info "Configuring Zsh build..." |
|
if ! ./configure --prefix=/usr/local --enable-multibyte --enable-unicode9; then |
|
log_error "Zsh configuration failed" |
|
return 1 |
|
fi |
|
|
|
log_info "Building Zsh (using $(nproc) cores)..." |
|
if ! make -j"$(nproc)"; then |
|
log_error "Zsh build failed" |
|
return 1 |
|
fi |
|
|
|
log_info "Installing Zsh..." |
|
if ! sudo make install; then |
|
log_error "Zsh installation failed" |
|
return 1 |
|
fi |
|
|
|
log_success "Zsh $ZSH_VERSION installed successfully" |
|
} |
|
|
|
# Configure Zsh as default shell |
|
configure_zsh_shell() { |
|
if [[ "$SKIP_SHELL_CHANGE" == "true" ]]; then |
|
log_info "Skipping shell change" |
|
return 0 |
|
fi |
|
|
|
log_step "Configuring Zsh as default shell..." |
|
|
|
local zsh_path |
|
zsh_path=$(command -v zsh) |
|
|
|
if [[ -z "$zsh_path" ]]; then |
|
log_error "Zsh not found in PATH" |
|
return 1 |
|
fi |
|
|
|
# Add Zsh to valid shells if not present |
|
if ! grep -Fxq "$zsh_path" /etc/shells; then |
|
log_info "Adding Zsh to /etc/shells..." |
|
echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null |
|
fi |
|
|
|
# Change default shell |
|
log_info "Changing default shell to Zsh..." |
|
if ! sudo chsh -s "$zsh_path" "$USER"; then |
|
log_error "Failed to change default shell" |
|
return 1 |
|
fi |
|
|
|
log_success "Default shell changed to Zsh" |
|
} |
|
|
|
# Install Oh-My-Zsh |
|
install_oh_my_zsh() { |
|
log_step "Installing Oh-My-Zsh..." |
|
|
|
if [[ -d "$HOME/.oh-my-zsh" ]]; then |
|
log_info "Oh-My-Zsh is already installed" |
|
return 0 |
|
fi |
|
|
|
# Download and install Oh-My-Zsh non-interactively |
|
export RUNZSH=no |
|
export KEEP_ZSHRC=yes |
|
|
|
if ! sh -c "$(curl -fsSL $OMZ_INSTALL_URL)"; then |
|
log_error "Failed to install Oh-My-Zsh" |
|
return 1 |
|
fi |
|
|
|
log_success "Oh-My-Zsh installed" |
|
} |
|
|
|
# Install Zsh plugins |
|
install_zsh_plugins() { |
|
log_step "Installing Zsh plugins..." |
|
|
|
local custom_dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" |
|
|
|
# Install zsh-autosuggestions |
|
local autosuggestions_dir="$custom_dir/plugins/zsh-autosuggestions" |
|
if [[ ! -d "$autosuggestions_dir" ]]; then |
|
log_info "Installing zsh-autosuggestions..." |
|
if ! git clone https://github.com/zsh-users/zsh-autosuggestions "$autosuggestions_dir"; then |
|
log_error "Failed to install zsh-autosuggestions" |
|
return 1 |
|
fi |
|
else |
|
log_info "zsh-autosuggestions already installed" |
|
fi |
|
|
|
# Install zsh-syntax-highlighting |
|
local highlighting_dir="$custom_dir/plugins/zsh-syntax-highlighting" |
|
if [[ ! -d "$highlighting_dir" ]]; then |
|
log_info "Installing zsh-syntax-highlighting..." |
|
if ! git clone https://github.com/zsh-users/zsh-syntax-highlighting "$highlighting_dir"; then |
|
log_error "Failed to install zsh-syntax-highlighting" |
|
return 1 |
|
fi |
|
else |
|
log_info "zsh-syntax-highlighting already installed" |
|
fi |
|
|
|
log_success "Zsh plugins installed" |
|
} |
|
|
|
# Install Spaceship theme |
|
install_spaceship_theme() { |
|
log_step "Installing Spaceship theme..." |
|
|
|
local custom_dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" |
|
local theme_dir="$custom_dir/themes/spaceship-prompt" |
|
local theme_link="$custom_dir/themes/spaceship.zsh-theme" |
|
|
|
if [[ ! -d "$theme_dir" ]]; then |
|
log_info "Downloading Spaceship theme..." |
|
if ! git clone https://github.com/spaceship-prompt/spaceship-prompt.git "$theme_dir" --depth=1; then |
|
log_error "Failed to install Spaceship theme" |
|
return 1 |
|
fi |
|
else |
|
log_info "Spaceship theme already installed" |
|
fi |
|
|
|
# Create symlink if it doesn't exist |
|
if [[ ! -L "$theme_link" ]]; then |
|
ln -sf "$theme_dir/spaceship.zsh-theme" "$theme_link" |
|
fi |
|
|
|
log_success "Spaceship theme installed" |
|
} |
|
|
|
# Download configuration files |
|
download_config_files() { |
|
if [[ "$CUSTOM_CONFIG" != "true" ]]; then |
|
local response |
|
read -p "Do you want to download custom configuration files? (y/N): " response |
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then |
|
log_info "Skipping custom configuration files" |
|
return 0 |
|
fi |
|
fi |
|
|
|
log_step "Downloading configuration files..." |
|
|
|
# Backup existing files |
|
local backup_dir="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)" |
|
mkdir -p "$backup_dir" |
|
|
|
for filename in "${!CONFIG_FILES[@]}"; do |
|
local filepath="$HOME/$filename" |
|
|
|
# Backup existing file |
|
if [[ -f "$filepath" ]]; then |
|
log_info "Backing up existing $filename to $backup_dir" |
|
cp "$filepath" "$backup_dir/" |
|
fi |
|
|
|
# Download new file |
|
log_info "Downloading $filename..." |
|
if ! curl -fsSL "${CONFIG_FILES[$filename]}" -o "$filepath"; then |
|
log_warn "Failed to download $filename" |
|
else |
|
log_info "Downloaded $filename" |
|
fi |
|
done |
|
|
|
log_success "Configuration files downloaded (backups in $backup_dir)" |
|
} |
|
|
|
# Update Zsh configuration |
|
update_zsh_config() { |
|
local zshrc="$HOME/.zshrc" |
|
|
|
if [[ ! -f "$zshrc" ]]; then |
|
log_warn "No .zshrc file found, creating basic configuration" |
|
cat > "$zshrc" << 'EOF' |
|
# Path to your oh-my-zsh installation. |
|
export ZSH="$HOME/.oh-my-zsh" |
|
|
|
# Set name of the theme to load |
|
ZSH_THEME="spaceship" |
|
|
|
# Add wisely, as too many plugins slow down shell startup. |
|
plugins=(git zsh-autosuggestions zsh-syntax-highlighting) |
|
|
|
source $ZSH/oh-my-zsh.sh |
|
EOF |
|
return 0 |
|
fi |
|
|
|
# Update theme if not already set to spaceship |
|
if ! grep -q 'ZSH_THEME="spaceship"' "$zshrc"; then |
|
sed -i 's/ZSH_THEME=".*"/ZSH_THEME="spaceship"/' "$zshrc" |
|
log_info "Updated ZSH_THEME to spaceship" |
|
fi |
|
|
|
# Update plugins |
|
local current_plugins |
|
current_plugins=$(grep -E '^plugins=' "$zshrc" | head -1) |
|
|
|
if [[ -n "$current_plugins" ]]; then |
|
if ! echo "$current_plugins" | grep -q "zsh-autosuggestions"; then |
|
sed -i 's/plugins=(\(.*\))/plugins=(\1 zsh-autosuggestions)/' "$zshrc" |
|
log_info "Added zsh-autosuggestions to plugins" |
|
fi |
|
|
|
if ! echo "$current_plugins" | grep -q "zsh-syntax-highlighting"; then |
|
sed -i 's/plugins=(\(.*\))/plugins=(\1 zsh-syntax-highlighting)/' "$zshrc" |
|
log_info "Added zsh-syntax-highlighting to plugins" |
|
fi |
|
fi |
|
|
|
log_success "Zsh configuration updated" |
|
} |
|
|
|
# Switch to Zsh automatically after installation |
|
switch_to_zsh() { |
|
if [[ "$SKIP_SHELL_CHANGE" == "true" ]]; then |
|
log_info "Skipping immediate shell switch" |
|
return 0 |
|
fi |
|
|
|
log_step "Switching to Zsh automatically..." |
|
|
|
local zsh_path |
|
zsh_path=$(command -v zsh) |
|
|
|
if [[ -z "$zsh_path" ]]; then |
|
log_error "Zsh not found in PATH" |
|
return 1 |
|
fi |
|
|
|
# Check if we're already in Zsh |
|
if [[ "$SHELL" == "$zsh_path" ]] && [[ -n "${ZSH_VERSION:-}" ]]; then |
|
log_info "Already running in Zsh" |
|
return 0 |
|
fi |
|
|
|
log_success "Starting new Zsh session..." |
|
|
|
# Replace current shell process with Zsh |
|
exec "$zsh_path" -l |
|
|
|
# This line will never be reached if exec succeeds |
|
log_error "Failed to switch to Zsh" |
|
return 1 |
|
} |
|
|
|
# Show completion message |
|
show_completion_message() { |
|
local os_type |
|
os_type=$(detect_os) |
|
|
|
cat << EOF |
|
|
|
${GREEN}╔══════════════════════════════════════════════════════════════╗ |
|
║ Zsh Installation Complete! ║ |
|
╚══════════════════════════════════════════════════════════════╝${NC} |
|
|
|
${YELLOW}What was installed:${NC} |
|
✓ Zsh $ZSH_VERSION (compiled from source) |
|
✓ Oh-My-Zsh framework |
|
✓ zsh-autosuggestions plugin |
|
✓ zsh-syntax-highlighting plugin |
|
✓ Spaceship theme |
|
EOF |
|
|
|
# Show xclip info if installed |
|
if [[ "$os_type" == "ubuntu" || "$os_type" == "debian" ]] && is_xclip_installed; then |
|
echo "✓ xclip clipboard utility" |
|
fi |
|
|
|
cat << EOF |
|
|
|
${YELLOW}Useful commands:${NC} |
|
- ${BLUE}omz update${NC} # Update Oh-My-Zsh |
|
- ${BLUE}omz plugin list${NC} # List available plugins |
|
- ${BLUE}omz theme list${NC} # List available themes |
|
EOF |
|
|
|
# Show xclip commands if available |
|
if [[ "$os_type" == "ubuntu" || "$os_type" == "debian" ]] && is_xclip_installed; then |
|
cat << EOF |
|
- ${BLUE}echo "text" | xclip -sel c${NC} # Copy to clipboard |
|
- ${BLUE}xclip -sel c -o${NC} # Paste from clipboard |
|
EOF |
|
fi |
|
|
|
cat << EOF |
|
|
|
${YELLOW}Configuration files:${NC} |
|
- Zsh config: ~/.zshrc |
|
- Oh-My-Zsh: ~/.oh-my-zsh/ |
|
|
|
EOF |
|
} |
|
|
|
# Main function |
|
main() { |
|
log_info "Starting Zsh installation..." |
|
|
|
parse_arguments "$@" |
|
check_requirements |
|
update_system |
|
install_packages |
|
install_xclip # Install xclip after basic packages |
|
configure_git |
|
install_homebrew |
|
get_zsh_version |
|
install_zsh |
|
configure_zsh_shell |
|
install_oh_my_zsh |
|
install_zsh_plugins |
|
install_spaceship_theme |
|
download_config_files |
|
update_zsh_config |
|
show_completion_message |
|
|
|
log_success "Zsh installation completed successfully!" |
|
|
|
# Automatically switch to Zsh |
|
switch_to_zsh |
|
|
|
# This line will only execute if switch_to_zsh fails |
|
echo "Enjoy your new Zsh setup! 🚀" |
|
} |
|
|
|
# Script entry point - Fixed to handle bash -c execution |
|
if [[ "${BASH_SOURCE[0]:-}" == "${0}" ]] || [[ -z "${BASH_SOURCE[0]:-}" ]]; then |
|
main "$@" |
|
fi |