Upload files to "/"

This commit is contained in:
2026-03-25 15:19:54 +01:00
parent 2691174ec7
commit 073c73dad8
3 changed files with 667 additions and 0 deletions

507
setup_zsh.sh Normal file
View File

@@ -0,0 +1,507 @@
#!/bin/bash
# =============================================================================
# 🚀 StianNOR — ZSH + NERD FONT SETUP v2.0
# Merges font_nerd_hack.sh + setup_zsh.sh
# Supports: Arch/Manjaro, Debian/Ubuntu, Fedora, openSUSE, Alpine
# =============================================================================
set -euo pipefail
# --- Colors ---
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
LINE="────────────────────────────────────────────────────────────────────────────"
info() { echo -e "${CYAN} $*${RESET}"; }
success() { echo -e "${GREEN}$*${RESET}"; }
warn() { echo -e "${YELLOW}$*${RESET}"; }
error() { echo -e "${RED}$*${RESET}"; }
step() { echo -e "\n${BOLD}${BLUE}$*${RESET}"; echo -e "${BLUE}${LINE}${RESET}"; }
die() { error "$*"; exit 1; }
# --- Error trap ---
trap 'error "Failed at line $LINENO — command: $BASH_COMMAND"; exit 1' ERR
# =============================================================================
# 1. DETECT PACKAGE MANAGER
# =============================================================================
step "Detecting package manager"
detect_pm() {
if command -v pacman >/dev/null 2>&1; then PM="pacman"
elif command -v apt >/dev/null 2>&1; then PM="apt"
elif command -v dnf >/dev/null 2>&1; then PM="dnf"
elif command -v zypper >/dev/null 2>&1; then PM="zypper"
elif command -v apk >/dev/null 2>&1; then PM="apk"
else die "No supported package manager found."; fi
success "Package manager: $PM"
}
detect_pm
pkg_install() {
case "$PM" in
pacman) sudo pacman -S --noconfirm --needed "$@" ;;
apt) sudo apt install -y "$@" ;;
dnf) sudo dnf install -y "$@" ;;
zypper) sudo zypper install -y "$@" ;;
apk) sudo apk add "$@" ;;
esac
}
pkg_update() {
case "$PM" in
pacman) sudo pacman -Syu --noconfirm ;;
apt) sudo apt update ;;
dnf) sudo dnf check-update || true ;;
zypper) sudo zypper refresh ;;
apk) sudo apk update ;;
esac
}
# =============================================================================
# 2. DETECT ENVIRONMENT
# =============================================================================
step "Detecting desktop environment and terminals"
get_distro() {
[[ -f /etc/os-release ]] && { source /etc/os-release; echo "$NAME"; return; }
uname -s
}
get_desktop() {
local de="${XDG_CURRENT_DESKTOP,,}"
[[ -z "$de" ]] && de="${DESKTOP_SESSION,,}"
echo "$de"
}
get_terminals() {
local terms=()
for t in gnome-terminal konsole alacritty kitty wezterm xfce4-terminal mate-terminal tilix; do
pgrep -x "$t" >/dev/null 2>&1 && terms+=("$t")
done
# Also check $TERM_PROGRAM
[[ -n "${TERM_PROGRAM:-}" ]] && terms+=("${TERM_PROGRAM,,}")
# Deduplicate
printf '%s\n' "${terms[@]}" | sort -u | tr '\n' ' '
}
DISTRO_NAME=$(get_distro)
DESKTOP_ENV=$(get_desktop)
TERMINALS=$(get_terminals)
info "Distro: $DISTRO_NAME"
info "Desktop: ${DESKTOP_ENV:-unknown}"
info "Terminals: ${TERMINALS:-none detected}"
# =============================================================================
# 3. INSTALL DEPENDENCIES
# =============================================================================
step "Installing core dependencies"
pkg_update
case "$PM" in
pacman) pkg_install curl git wget unzip ruby gcc make ;;
apt) sudo apt install -y curl git wget unzip ruby ruby-dev gcc make build-essential ;;
dnf) sudo dnf install -y curl git wget unzip ruby ruby-devel gcc make ;;
zypper) sudo zypper install -y curl git wget unzip ruby ruby-devel gcc make ;;
apk) sudo apk add curl git wget unzip ruby ruby-dev gcc make ;;
esac
success "Core dependencies installed"
# =============================================================================
# 4. INSTALL HACK NERD FONT
# =============================================================================
step "Installing Hack Nerd Font"
FONT_DIR="/usr/local/share/fonts/nerd-fonts"
FONT_ALIAS="Hack Nerd Font"
FONT_TMPDIR=$(mktemp -d)
FONT_VERSION="v3.4.0"
# Ensure fontconfig tools available
command -v fc-cache >/dev/null 2>&1 || pkg_install fontconfig
cleanup_font_tmp() { rm -rf "$FONT_TMPDIR"; }
trap 'cleanup_font_tmp; error "Failed at line $LINENO — command: $BASH_COMMAND"; exit 1' ERR
trap 'cleanup_font_tmp' EXIT
info "Downloading Hack Nerd Font $FONT_VERSION..."
FONT_URL="https://github.com/ryanoasis/nerd-fonts/releases/download/${FONT_VERSION}/Hack.zip"
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$FONT_URL" -o "$FONT_TMPDIR/Hack.zip" || die "Font download failed"
else
wget -q "$FONT_URL" -O "$FONT_TMPDIR/Hack.zip" || die "Font download failed"
fi
info "Extracting fonts..."
unzip -q "$FONT_TMPDIR/Hack.zip" -d "$FONT_TMPDIR/Hack" || die "Font extraction failed"
sudo mkdir -p "$FONT_DIR"
# Only copy TTF/OTF — skip Windows-compat and licence files
find "$FONT_TMPDIR/Hack" -name "*.ttf" -o -name "*.otf" | while read -r f; do
[[ "$f" =~ (Windows|LICENSE|README) ]] && continue
sudo cp "$f" "$FONT_DIR/"
done
sudo fc-cache -f "$FONT_DIR"
success "Hack Nerd Font installed to $FONT_DIR"
# --- Apply to Desktop Environment ---
FONT_GENERAL="$FONT_ALIAS 12"
FONT_MONO="$FONT_ALIAS 11"
FONT_SMALL="$FONT_ALIAS 8"
FONT_OTHER="$FONT_ALIAS 10"
apply_kde_fonts() {
local kwrite
if command -v kwriteconfig6 >/dev/null 2>&1; then kwrite="kwriteconfig6"
elif command -v kwriteconfig5 >/dev/null 2>&1; then kwrite="kwriteconfig5"
else warn "kwriteconfig not found — KDE font config skipped"; return; fi
$kwrite --file kdeglobals --group General --key font "$FONT_ALIAS,12,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group Fixed --key font "$FONT_ALIAS,11,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group Small --key font "$FONT_ALIAS,8,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group Toolbar --key font "$FONT_ALIAS,10,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group Menu --key font "$FONT_ALIAS,10,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group "Window Title" --key font "$FONT_ALIAS,10,-1,5,50,0,0,0,0,0"
$kwrite --file kdeglobals --group General --key antialiasing "true"
$kwrite --file kdeglobals --group General --key hinting "slight"
$kwrite --file kdeglobals --group General --key subpixelRendering "rgb"
$kwrite --file kdeglobals --group General --key forceFontDpi 96
# Konsole profiles
find ~/.local/share/konsole -name "*.profile" 2>/dev/null \
-exec sed -i "s/^Font=.*/Font=$FONT_ALIAS,12,-1,5,50,0,0,0,0,0,Regular/" {} \;
success "KDE fonts applied via $kwrite"
}
apply_gnome_fonts() {
command -v gsettings >/dev/null 2>&1 || { warn "gsettings not found — GNOME font config skipped"; return; }
gsettings set org.gnome.desktop.interface font-name "$FONT_GENERAL"
gsettings set org.gnome.desktop.interface monospace-font-name "$FONT_MONO"
gsettings set org.gnome.desktop.interface document-font-name "$FONT_GENERAL"
# GNOME Terminal profiles via dconf
if command -v dconf >/dev/null 2>&1; then
while IFS= read -r profile; do
[[ -z "$profile" ]] && continue
dconf write "/org/gnome/terminal/legacy/profiles:/:${profile}/use-system-font" "false"
dconf write "/org/gnome/terminal/legacy/profiles:/:${profile}/font" "'$FONT_MONO'"
done < <(dconf list /org/gnome/terminal/legacy/profiles:/ 2>/dev/null | grep -oP '[^/:]+' || true)
fi
success "GNOME/Cinnamon fonts applied"
}
apply_xfce_fonts() {
command -v xfconf-query >/dev/null 2>&1 || { warn "xfconf-query not found — XFCE font config skipped"; return; }
xfconf-query -c xsettings -p /Gtk/FontName -s "$FONT_GENERAL" 2>/dev/null || true
xfconf-query -c xfwm4 -p /general/font -s "$FONT_GENERAL" 2>/dev/null || true
local xterm_conf="$HOME/.config/xfce4/terminal/terminalrc"
if [[ -f "$xterm_conf" ]]; then
sed -i "s/^FontName=.*/FontName=$FONT_MONO/" "$xterm_conf"
fi
success "XFCE fonts applied"
}
apply_mate_fonts() {
command -v gsettings >/dev/null 2>&1 || { warn "gsettings not found — MATE font config skipped"; return; }
gsettings set org.mate.interface font-name "$FONT_GENERAL" 2>/dev/null || true
success "MATE fonts applied"
}
case "$DESKTOP_ENV" in
*kde*|*plasma*) apply_kde_fonts ;;
*gnome*|*cinnamon*|*unity*) apply_gnome_fonts ;;
*xfce*) apply_xfce_fonts ;;
*mate*) apply_mate_fonts ;;
*) warn "Desktop '$DESKTOP_ENV' not specifically handled — font installed system-wide via fontconfig" ;;
esac
# --- Apply to detected terminal emulators ---
apply_terminal_font() {
local term="$1"
case "$term" in
alacritty)
# Support both .yml (old) and .toml (new Alacritty >=0.13)
local conf_toml="$HOME/.config/alacritty/alacritty.toml"
local conf_yml="$HOME/.config/alacritty/alacritty.yml"
if [[ -f "$conf_toml" ]]; then
if grep -q '^\[font\]' "$conf_toml"; then
sed -i '/^\[font\]/,/^\[/{s/^family = .*/family = "'"$FONT_ALIAS"'"/}' "$conf_toml"
else
printf '\n[font]\n[font.normal]\nfamily = "%s"\n[font.bold]\nfamily = "%s"\n[font.italic]\nfamily = "%s"\n\n[font.size]\nsize = 12.0\n' \
"$FONT_ALIAS" "$FONT_ALIAS" "$FONT_ALIAS" >> "$conf_toml"
fi
success "Alacritty TOML font updated"
elif [[ -f "$conf_yml" ]]; then
sed -i "/^ *family:/c\\ family: \"$FONT_ALIAS\"" "$conf_yml"
sed -i "/^ *size:/c\\ size: 12" "$conf_yml"
success "Alacritty YAML font updated"
else
warn "Alacritty config not found at $conf_toml or $conf_yml — skipping"
fi
;;
kitty)
local kconf="$HOME/.config/kitty/kitty.conf"
mkdir -p "$(dirname "$kconf")"
if [[ -f "$kconf" ]]; then
sed -i "/^font_family/c\\font_family $FONT_ALIAS" "$kconf"
sed -i "/^font_size/c\\font_size 12.0" "$kconf"
else
printf 'font_family %s\nfont_size 12.0\n' "$FONT_ALIAS" > "$kconf"
fi
success "Kitty font configured"
;;
wezterm)
local wconf="$HOME/.config/wezterm/wezterm.lua"
if [[ -f "$wconf" ]]; then
warn "WezTerm config found at $wconf — add this manually:"
echo " config.font = wezterm.font('$FONT_ALIAS')"
fi
;;
konsole)
find ~/.local/share/konsole -name "*.profile" 2>/dev/null \
-exec sed -i "s/^Font=.*/Font=$FONT_ALIAS,12,-1,5,50,0,0,0,0,0,Regular/" {} \;
success "Konsole profiles updated"
;;
xfce4-terminal)
local xterm_conf="$HOME/.config/xfce4/terminal/terminalrc"
[[ -f "$xterm_conf" ]] && sed -i "s/^FontName=.*/FontName=$FONT_MONO/" "$xterm_conf"
success "XFCE Terminal font updated"
;;
gnome-terminal) ;; # handled by apply_gnome_fonts via dconf
*) warn "Terminal '$term' font config not supported — set manually" ;;
esac
}
for term in $TERMINALS; do
apply_terminal_font "$term"
done
# --- fontconfig fallback (monospace alias) ---
sudo tee /etc/fonts/local.conf > /dev/null <<FONTCONF
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<alias>
<family>monospace</family>
<prefer>
<family>${FONT_ALIAS}</family>
</prefer>
</alias>
<alias>
<family>Hack Nerd Font Mono</family>
<prefer>
<family>${FONT_ALIAS}</family>
</prefer>
</alias>
</fontconfig>
FONTCONF
sudo fc-cache -f
success "fontconfig monospace alias set"
# NOTE: TTY/vconsole fonts must be bitmap/psf fonts — Nerd Font TTFs
# cannot be used in vconsole.conf. Skipping to avoid breaking TTY.
# =============================================================================
# 5. INSTALL ZSH
# =============================================================================
step "Installing Zsh"
if ! command -v zsh >/dev/null 2>&1; then
pkg_install zsh
success "Zsh installed"
else
success "Zsh already installed: $(zsh --version)"
fi
# =============================================================================
# 6. UPDATE RUBYGEMS + INSTALL COLORLS
# =============================================================================
step "Setting up Ruby gems (colorls)"
export GEM_HOME="$HOME/.gem"
export PATH="$PATH:$GEM_HOME/bin"
USER_GEM_BIN="$(ruby -e 'puts Gem.user_dir' 2>/dev/null)/bin"
# Update gems — skip system update on apt (breaks Debian policy)
if [[ "$PM" != "apt" ]]; then
gem update --system 2>/dev/null && success "RubyGems system updated" \
|| warn "RubyGems system update failed — continuing"
fi
gem update 2>/dev/null && success "All gems updated" || warn "gem update had warnings — continuing"
if gem list -i colorls >/dev/null 2>&1; then
success "colorls already installed"
else
info "Installing colorls..."
gem install --user-install colorls || die "colorls install failed"
success "colorls installed"
fi
# Add gem bin to PATH in both .zshrc and .bashrc so it works during this session too
for rc in "$HOME/.zshrc" "$HOME/.bashrc"; do
if [[ -f "$rc" ]] && ! grep -q "$USER_GEM_BIN" "$rc" 2>/dev/null; then
echo "export PATH=\"\$PATH:$USER_GEM_BIN\"" >> "$rc"
info "Added gem bin to PATH in $rc"
fi
done
export PATH="$PATH:$USER_GEM_BIN"
# =============================================================================
# 7. INSTALL FASTFETCH
# =============================================================================
step "Installing fastfetch"
if command -v fastfetch >/dev/null 2>&1; then
success "fastfetch already installed: $(fastfetch --version 2>/dev/null | head -1)"
else
info "Trying package manager first..."
installed=false
case "$PM" in
pacman) sudo pacman -S --noconfirm --needed fastfetch 2>/dev/null && installed=true ;;
apt)
# fastfetch not in standard apt — try PPA or direct .deb download
if sudo add-apt-repository -y ppa:zhangsongcui3371/fastfetch 2>/dev/null; then
sudo apt update && sudo apt install -y fastfetch && installed=true
fi ;;
dnf) sudo dnf install -y fastfetch 2>/dev/null && installed=true ;;
zypper) sudo zypper install -y fastfetch 2>/dev/null && installed=true ;;
apk) sudo apk add fastfetch 2>/dev/null && installed=true ;;
esac
if [[ "$installed" == false ]]; then
warn "Package manager install failed — downloading latest binary release..."
ARCH=$(uname -m)
[[ "$ARCH" == "x86_64" ]] && ARCH_NAME="amd64" || ARCH_NAME="$ARCH"
FF_URL=$(curl -s https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest \
| grep "browser_download_url" \
| grep "linux-${ARCH_NAME}.tar.gz" \
| head -1 | cut -d'"' -f4)
if [[ -n "$FF_URL" ]]; then
FF_TMP=$(mktemp -d)
curl -fsSL "$FF_URL" -o "$FF_TMP/fastfetch.tar.gz"
tar -xzf "$FF_TMP/fastfetch.tar.gz" -C "$FF_TMP"
sudo install -m755 "$FF_TMP"/fastfetch*/usr/bin/fastfetch /usr/local/bin/fastfetch 2>/dev/null \
|| sudo cp "$(find "$FF_TMP" -name fastfetch -type f | head -1)" /usr/local/bin/fastfetch
sudo chmod +x /usr/local/bin/fastfetch
rm -rf "$FF_TMP"
installed=true
fi
fi
if [[ "$installed" == true ]] && command -v fastfetch >/dev/null 2>&1; then
success "fastfetch installed: $(fastfetch --version 2>/dev/null | head -1)"
else
warn "fastfetch could not be installed automatically — install it manually"
fi
fi
# =============================================================================
# 8. INSTALL OH MY ZSH
# =============================================================================
step "Installing Oh My Zsh"
if [[ -f "$HOME/.oh-my-zsh/oh-my-zsh.sh" ]]; then
success "Oh My Zsh already installed"
else
info "Installing Oh My Zsh..."
rm -rf "$HOME/.oh-my-zsh"
RUNZSH=no KEEP_ZSHRC=yes \
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" \
|| die "Oh My Zsh install failed"
success "Oh My Zsh installed"
fi
ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
# =============================================================================
# 9. INSTALL POWERLEVEL10K
# =============================================================================
step "Installing Powerlevel10k theme"
P10K_DIR="$ZSH_CUSTOM/themes/powerlevel10k"
if [[ -d "$P10K_DIR" ]]; then
info "Updating Powerlevel10k..."
git -C "$P10K_DIR" pull --ff-only 2>/dev/null && success "Powerlevel10k updated" || warn "p10k update failed — skipping"
else
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "$P10K_DIR" \
|| die "Powerlevel10k install failed"
success "Powerlevel10k installed"
fi
# =============================================================================
# 10. INSTALL ZSH PLUGINS
# =============================================================================
step "Installing Zsh plugins"
declare -A ZSH_PLUGINS=(
[zsh-autosuggestions]="https://github.com/zsh-users/zsh-autosuggestions"
[zsh-syntax-highlighting]="https://github.com/zsh-users/zsh-syntax-highlighting"
[zsh-completions]="https://github.com/zsh-users/zsh-completions"
)
for plugin in "${!ZSH_PLUGINS[@]}"; do
local_dir="$ZSH_CUSTOM/plugins/$plugin"
if [[ -d "$local_dir" ]]; then
git -C "$local_dir" pull --ff-only 2>/dev/null && success "$plugin updated" || warn "$plugin update skipped"
else
info "Installing $plugin..."
git clone "${ZSH_PLUGINS[$plugin]}" "$local_dir" || warn "$plugin install failed — continuing"
success "$plugin installed"
fi
done
# =============================================================================
# 11. COPY .zshrc AND .p10k.zsh
# =============================================================================
step "Applying .zshrc and .p10k.zsh"
# Use the directory where THIS script lives as the source
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
copy_if_exists() {
local src="$1" dst="$2" label="$3"
if [[ -f "$src" ]]; then
cp "$src" "$dst"
success "$label$dst"
else
warn "$src not found — $label not copied"
fi
}
copy_if_exists "$SCRIPT_DIR/.zshrc" "$HOME/.zshrc" ".zshrc"
copy_if_exists "$SCRIPT_DIR/.p10k.zsh" "$HOME/.p10k.zsh" ".p10k.zsh"
# Ensure gem bin and zsh path are in the copied .zshrc
for line in \
"export PATH=\"\$PATH:$USER_GEM_BIN\"" \
"export GEM_HOME=\"\$HOME/.gem\""; do
grep -qF "$line" "$HOME/.zshrc" 2>/dev/null || echo "$line" >> "$HOME/.zshrc"
done
# =============================================================================
# 12. SET ZSH AS DEFAULT SHELL
# =============================================================================
step "Setting Zsh as default shell"
ZSH_PATH=$(command -v zsh)
if [[ "$SHELL" == "$ZSH_PATH" ]]; then
success "Zsh is already the default shell"
else
# Make sure zsh is in /etc/shells
grep -qxF "$ZSH_PATH" /etc/shells || echo "$ZSH_PATH" | sudo tee -a /etc/shells
if chsh -s "$ZSH_PATH" 2>/dev/null; then
success "Default shell set to $ZSH_PATH"
info "Log out and back in for the shell change to take effect"
else
warn "Could not change default shell — run manually: chsh -s $ZSH_PATH"
fi
fi
# =============================================================================
# DONE
# =============================================================================
echo ""
echo -e "${LINE}"
echo -e "${BOLD}${GREEN} ✅ StianNOR Zsh + Nerd Font Setup Complete!${RESET}"
echo -e "${LINE}"
echo -e " ${CYAN}Font:${RESET} Hack Nerd Font installed system-wide"
echo -e " ${CYAN}Shell:${RESET} Zsh + Oh My Zsh + Powerlevel10k"
echo -e " ${CYAN}Plugins:${RESET} autosuggestions, syntax-highlighting, completions"
echo -e " ${CYAN}Tools:${RESET} colorls, fastfetch"
echo -e "${LINE}"
echo -e " ${YELLOW}Next steps:${RESET}"
echo -e " 1. Log out and back in (shell change + font)"
echo -e " 2. Run ${CYAN}p10k configure${RESET} to set up your prompt"
echo -e " 3. In your terminal settings, select ${CYAN}Hack Nerd Font${RESET} manually if needed"
echo -e "${LINE}"
echo ""