diff --git a/install.sh b/install.sh index cf59d9d..afc5a06 100755 --- a/install.sh +++ b/install.sh @@ -65,11 +65,9 @@ EOF list_modules() { echo "Available modules:" - echo "" for module in $(module_list); do local rel_path="${module#$OMERON_MODULE_DIR/}" rel_path="${rel_path%.sh}" - local description="" if source "$module" 2>/dev/null && declare -F "module_description" >/dev/null 2>&1; then description="$(module_description)" @@ -82,47 +80,59 @@ list_modules() { parse_args() { while [[ $# -gt 0 ]]; do case "$1" in - --fresh) - OMERON_FRESH_INSTALL=1 - shift - ;; - --modules) - IFS=',' read -ra RUN_MODULES <<< "$2" - shift 2 - ;; - --skip) - IFS=',' read -ra SKIP_MODULES <<< "$2" - shift 2 - ;; - --skip-packages) - SKIP_MODULES+=("core/packages") - shift - ;; - --with-sddm) - WITH_SDDM=1 - shift - ;; - --list-modules) - list_modules - ;; - -h|--help) - usage - ;; - *) - echo "Unknown option: $1" >&2 - usage - ;; + --fresh) OMERON_FRESH_INSTALL=1; shift ;; + --modules) IFS=',' read -ra RUN_MODULES <<< "$2"; shift 2 ;; + --skip) IFS=',' read -ra SKIP_MODULES <<< "$2"; shift 2 ;; + --skip-packages) SKIP_MODULES+=("core/packages"); shift ;; + --with-sddm) WITH_SDDM=1; shift ;; + --list-modules) list_modules ;; + -h|--help) usage ;; + *) echo "Unknown option: $1" >&2; usage ;; esac done } +detect_environment() { + tui_detect + + if ((!OMERON_HAS_GUM)) && have pacman; then + printf '\033[1;36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m\n' + printf '\033[1;36m Ꮎ Ꮇ Ꭼ Ꮢ Ꮎ Ꮑ — Modular System Setup Framework\033[0m\n' + printf '\033[1;36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m\n' + printf '\n' + printf ' \033[1;33mgum is not installed.\033[0m Installing it enables the full TUI experience.\n' + printf '\n' + + if tui_install_gum; then + printf ' \033[1;32m✓ gum installed!\033[0m\n' + else + if ((OMERON_HAS_WHIPTAIL)); then + printf ' \033[1;33musing whiptail as fallback\033[0m\n' + else + printf ' \033[1;33musing basic text mode (install gum for UI: pacman -S gum)\033[0m\n' + fi + fi + printf '\n' + fi + + if ((!OMERON_FRESH_INSTALL)) && ((${#RUN_MODULES[@]} == 0)); then + log_info "Checking for fresh install..." + if is_fresh_install; then + OMERON_FRESH_INSTALL=1 + export OMERON_FRESH_INSTALL + fi + fi + + if ((OMERON_FRESH_INSTALL)) && ((!OMERON_HAS_GUM)) && have pacman; then + tui_install_gum 2>/dev/null || true + fi +} + collect_modules() { if ((${#RUN_MODULES[@]})); then - local result=() for mod in "${RUN_MODULES[@]}"; do - result+=("$OMERON_MODULE_DIR/$mod.sh") + printf '%s\n' "$OMERON_MODULE_DIR/$mod.sh" done - printf '%s\n' "${result[@]}" return fi @@ -133,8 +143,6 @@ collect_modules() { modules=("${DEFAULT_MODULES[@]}") fi - local module_order=() - for mod in "${modules[@]}"; do local skip=0 for skipped in "${SKIP_MODULES[@]}"; do @@ -143,16 +151,11 @@ collect_modules() { break fi done - [[ "$mod" == "core/sddm" && "$WITH_SDDM" -eq 0 && "$OMERON_FRESH_INSTALL" -eq 0 ]] && skip=1 - ((skip)) && continue - local module_file="$OMERON_MODULE_DIR/$mod.sh" - [[ -f "$module_file" ]] && module_order+=("$module_file") + [[ -f "$module_file" ]] && printf '%s\n' "$module_file" done - - printf '%s\n' "${module_order[@]}" } collect_all_interactive() { @@ -182,7 +185,7 @@ collect_all_interactive() { if declare -F "module_required" >/dev/null 2>&1; then source "$module_file" if module_required; then - log_info "Required module - will run" + tui_info "Required module — will run" module_order+=("$module_file") ((idx++)) continue @@ -194,7 +197,6 @@ collect_all_interactive() { else log_info "Skipped" fi - ((idx++)) done @@ -203,44 +205,41 @@ collect_all_interactive() { show_banner() { tui_header " Ꮎ Ꮇ Ꭼ Ꮢ Ꮎ Ꮑ " - tui_format "" - tui_format "#{bold}Modular System Setup Framework#{normal}" - tui_format "#{italic}Arch / Hyprland / CachyOS#{normal}" - tui_format "" + tui_info "Modular System Setup Framework" + tui_info "Arch / Hyprland / CachyOS" + printf '\n' if ((OMERON_FRESH_INSTALL)); then - tui_format "#{bold}#{yellow}⚡ FRESH INSTALL MODE#{normal}" - tui_format "Will install Hyprland, GPU drivers, and all dependencies." - tui_format "" + tui_warn "FRESH INSTALL MODE" + tui_info "Will install Hyprland, GPU drivers, and all dependencies." + printf '\n' fi } show_summary() { local modules=("$@") - tui_format "" - tui_format "#{bold}Installation Summary:#{normal}" - tui_format " Modules to run: ${#modules[@]}" + tui_separator + tui_bold "Installation Summary" + tui_info "$(tui_bold "${#modules[@]}") module(s) to run" local gpu gpu="$(detect_gpu)" - tui_format " Detected GPU: ${gpu}" + tui_info "Detected GPU: $(tui_bold "$gpu")" if ((${#modules[@]})); then - tui_format "" - tui_format "#{bold}Steps:#{normal}" + printf '\n' + tui_bold "Steps:" local i=1 for mod in "${modules[@]}"; do - local name - name="$(basename "$mod" .sh)" - tui_format " $i. ${name}" + printf ' \033[1;36m%d.\033[0m %s\n' "$i" "$(basename "$mod" .sh)" ((i++)) done fi - tui_format "" + printf '\n' if ! tui_confirm "Proceed with installation?"; then - tui_format "#{bold}Installation cancelled by user.#{normal}" + tui_bold "Installation cancelled." exit 0 fi } @@ -251,23 +250,14 @@ main() { parse_args "$@" - tui_style - show_banner - mkdir -p "$(dirname "$OMERON_LOG_FILE")" log_info "Omeron installation started" log_info "Log file: $OMERON_LOG_FILE" log_info "Project: $OMERON_ROOT" - log_info "Fresh install: $OMERON_FRESH_INSTALL" - if ((!OMERON_FRESH_INSTALL)) && ((${#RUN_MODULES[@]} == 0)); then - log_info "Checking for fresh install..." - if is_fresh_install; then - OMERON_FRESH_INSTALL=1 - export OMERON_FRESH_INSTALL - log_info "Fresh system detected — switching to full setup mode" - fi - fi + detect_environment + + show_banner local modules_to_run=() if ((${#RUN_MODULES[@]})); then @@ -277,7 +267,7 @@ main() { fi if ((${#modules_to_run[@]} == 0)); then - log_warn "No modules selected. Nothing to do." + tui_warn "No modules selected. Nothing to do." exit 0 fi @@ -291,47 +281,46 @@ main() { if source "$module_path" 2>/dev/null && declare -F "module_description" >/dev/null 2>&1; then description="$(module_description)" fi - printf '\n' log_step "$idx" "$total" "${description:-$(basename "$module_path" .sh)}" + module_run "$module_path" || { local rc=$? if declare -F "module_required" >/dev/null 2>&1; then source "$module_path" if module_required 2>/dev/null; then - log_error "Required module failed. Aborting." + tui_error "Required module failed. Aborting." exit $rc fi fi - log_warn "Module completed with warnings" + tui_warn "Module completed with warnings" } ((idx++)) done printf '\n' tui_header " Ꮎ Ꮇ Ꭼ Ꮢ Ꮎ Ꮑ " - tui_format "" - tui_format "#{bold}#{green}Installation Complete!#{normal}" - tui_format "" - tui_format "Log: ${OMERON_LOG_FILE}" - tui_format "" + tui_success "Installation Complete!" + printf '\n' + tui_info "Log: ${OMERON_LOG_FILE}" + printf '\n' if ((OMERON_FRESH_INSTALL)); then - tui_format "#{bold}Your system is ready for Hyprland!#{normal}" - tui_format "" - tui_format " Start Hyprland: Hyprland" - tui_format " Or enable SDDM: sudo systemctl enable --now sddm" - tui_format " Reload config: hyprctl reload" + tui_bold "Your system is ready for Hyprland!" + tui_list \ + "Start Hyprland: Hyprland" \ + "Or enable SDDM: sudo systemctl enable --now sddm" \ + "Reload config: hyprctl reload" else - tui_format "What next?" - tui_format " - Reload config with: hyprctl reload" - tui_format " - Re-run installer: ./install.sh" + tui_bold "What next?" + tui_list \ + "Reload config: hyprctl reload" \ + "Re-run installer: ./install.sh" fi - - tui_format "" + printf '\n' if have notify-send; then - notify-send "Omeron" "Installation complete! ✨" >/dev/null 2>&1 || true + notify-send "Omeron" "Installation complete!" >/dev/null 2>&1 || true fi } diff --git a/lib/log.sh b/lib/log.sh index 97fca4a..8df0218 100755 --- a/lib/log.sh +++ b/lib/log.sh @@ -40,7 +40,7 @@ log_step() { log_section() { local message="$1" local line - line="$(printf '━%.0s' $(seq 1 "${#message}"))" + printf -v line '%*s' "${#message}" '' && line="${line// /━}" printf '\n%s\n%s\n%s\n' "$line" "$message" "$line" __log_write "SECTION" "$message" } diff --git a/lib/tui.sh b/lib/tui.sh index 4b8a197..e65c27c 100755 --- a/lib/tui.sh +++ b/lib/tui.sh @@ -1,55 +1,123 @@ #!/usr/bin/env bash -TUI_STYLE="${TUI_STYLE:-gum}" +OMERON_HAS_GUM=0 +OMERON_HAS_WHIPTAIL=0 +OMERON_TUI_MODE="basic" -tui_check() { - if [[ "$TUI_STYLE" == "gum" ]] && ! command -v gum >/dev/null 2>&1; then - printf "gum is not installed. Install it or set TUI_STYLE=basic\n" >&2 - return 1 +tui_detect() { + OMERON_HAS_GUM=0 + OMERON_HAS_WHIPTAIL=0 + + command -v gum >/dev/null 2>&1 && OMERON_HAS_GUM=1 + command -v whiptail >/dev/null 2>&1 && OMERON_HAS_WHIPTAIL=1 + + if ((OMERON_HAS_GUM)); then + OMERON_TUI_MODE="gum" + elif ((OMERON_HAS_WHIPTAIL)); then + OMERON_TUI_MODE="whiptail" + else + OMERON_TUI_MODE="basic" fi } -tui_style() { - if command -v gum >/dev/null 2>&1; then - TUI_STYLE="gum" - else - TUI_STYLE="basic" +tui_install_gum() { + if ((OMERON_HAS_GUM)); then + return 0 fi + + if ! have pacman; then + return 1 + fi + + printf '\033[1;36mInstalling gum for a better TUI experience...\033[0m\n' + if sudo_run pacman -S --needed --noconfirm gum >/dev/null 2>&1; then + command -v gum >/dev/null 2>&1 && OMERON_HAS_GUM=1 + if ((OMERON_HAS_GUM)); then + OMERON_TUI_MODE="gum" + return 0 + fi + fi + return 1 +} + +_strip_format() { + local text="$1" + text="${text//#\{bold\}/}" + text="${text//#\{normal\}/}" + text="${text//#\{italic\}/}" + text="${text//#\{green\}/}" + text="${text//#\{yellow\}/}" + text="${text//#\{red\}/}" + text="${text//#\{blue\}/}" + text="${text//#\{cyan\}/}" + text="${text//#\{magenta\}/}" + text="${text//#\{white\}/}" + text="${text//#\{underline\}/}" + printf '%s\n' "$text" } tui_choose() { local prompt="$1" shift - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum choose "$@" - else - select __choice in "$@"; do - printf '%s\n' "$__choice" - break + elif [[ "$OMERON_TUI_MODE" == "whiptail" ]]; then + local i=0 + local items=() + for item in "$@"; do + items+=("$i" "$item") + ((i++)) done + whiptail --menu "$prompt" 20 60 10 "${items[@]}" 3>&1 1>&2 2>&3 + else + printf '\n==============================\n' + printf ' %s\n' "$(_strip_format "$prompt")" + printf '==============================\n' + local i=0 + for item in "$@"; do + printf ' [%d] %s\n' "$i" "$item" + ((i++)) + done + printf ' [x] Cancel\n' + printf '==============================\n' + printf ' Choice: ' + read -r choice + if [[ "$choice" == "x" ]]; then + return 1 + fi + if [[ "$choice" =~ ^[0-9]+$ ]] && ((choice < ${#@})); then + printf '%s\n' "${!choice}" + fi fi } tui_confirm() { local prompt="$1" + prompt="$(_strip_format "$prompt")" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum confirm "$prompt" + elif [[ "$OMERON_TUI_MODE" == "whiptail" ]]; then + whiptail --yesno "$prompt" 10 60 else - printf '%s [y/N]: ' "$prompt" >&2 + printf '\n>>> %s [Y/n]: ' "$prompt" read -r response + response="${response:-Y}" [[ "$response" =~ ^[yY](es)?$ ]] fi } tui_input() { local prompt="$1" + prompt="$(_strip_format "$prompt")" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum input --prompt "$prompt " + elif [[ "$OMERON_TUI_MODE" == "whiptail" ]]; then + whiptail --inputbox "$prompt" 10 60 3>&1 1>&2 2>&3 else - printf '%s: ' "$prompt" >&2 + printf '%s: ' "$prompt" read -r response printf '%s\n' "$response" fi @@ -57,11 +125,14 @@ tui_input() { tui_password() { local prompt="$1" + prompt="$(_strip_format "$prompt")" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum input --password --prompt "$prompt " + elif [[ "$OMERON_TUI_MODE" == "whiptail" ]]; then + whiptail --passwordbox "$prompt" 10 60 3>&1 1>&2 2>&3 else - printf '%s: ' "$prompt" >&2 + printf '%s: ' "$prompt" read -rs response printf '\n' printf '%s\n' "$response" @@ -71,21 +142,29 @@ tui_password() { tui_multiselect() { local prompt="$1" shift + prompt="$(_strip_format "$prompt")" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum choose --no-limit "$@" else - printf '%s (space-separated indices):\n' "$prompt" >&2 + printf '\n==============================\n' + printf ' %s (space-separated indices)\n' "$prompt" + printf '==============================\n' local i=0 local items=("$@") for item in "${items[@]}"; do - printf ' [%d] %s\n' "$i" "$item" >&2 + printf ' [%d] %s\n' "$i" "$item" ((i++)) done - printf '> ' >&2 + printf ' [x] Done\n' + printf '==============================\n' + printf ' Select: ' read -ra selections - for idx in "${selections[@]}"; do - printf '%s\n' "${items[$idx]}" + local selection + for selection in "${selections[@]}"; do + if [[ "$selection" =~ ^[0-9]+$ ]] && ((selection < ${#items[@]})); then + printf '%s\n' "${items[$selection]}" + fi done fi } @@ -93,69 +172,115 @@ tui_multiselect() { tui_spin() { local title="$1" shift + title="$(_strip_format "$title")" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum spin --title "$title" -- "$@" else - printf '%s... ' "$title" >&2 + printf ' ▶ %s ... ' "$title" "$@" - printf 'done\n' >&2 + local rc=$? + if ((rc == 0)); then + printf '\033[1;32mOK\033[0m\n' + else + printf '\033[1;31mFAILED\033[0m\n' + fi + return $rc fi } tui_header() { - local title="$1" + local title="$(_strip_format "$1")" + local len="${#title}" - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum style --foreground 212 --border-foreground 212 --border double --align center --width 60 --margin "1 2" --padding "1 2" "$title" else - printf '╔══════════════════════════════════════════════════╗\n' - printf '║ %s\n' "$title" - printf '╚══════════════════════════════════════════════════╝\n' + local width=50 + local pad=$(( (width - len) / 2 )) + [[ $pad -lt 2 ]] && pad=2 + + local line + printf -v line '%*s' "$width" '' && line="${line// /═}" + printf '\n' + printf '\033[1;36m%s\033[0m\n' "$line" + printf '\033[1;36m║\033[0m%*s%s%*s\033[1;36m║\033[0m\n' $pad '' "$title" $((width - pad - len)) '' + printf '\033[1;36m%s\033[0m\n' "$line" + printf '\n' fi } tui_status() { local ok="$1" local message="$2" + message="$(_strip_format "$message")" - if [[ "$TUI_STYLE" == "gum" ]]; then - if [[ "$ok" == "0" ]]; then - gum style --foreground 10 "✓ $message" + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then + if ((ok == 0)); then + gum style --foreground 10 " ✓ $message" else - gum style --foreground 9 "✗ $message" + gum style --foreground 9 " ✗ $message" fi else - if [[ "$ok" == "0" ]]; then - printf '✓ %s\n' "$message" + if ((ok == 0)); then + printf ' \033[1;32m✓\033[0m %s\n' "$message" else - printf '✗ %s\n' "$message" + printf ' \033[1;31m✗\033[0m %s\n' "$message" fi fi } -tui_file_pick() { - local directory="$1" - local pattern="$2" - - if [[ "$TUI_STYLE" == "gum" ]]; then - find "$directory" -maxdepth 1 -type f -name "$pattern" -printf '%f\n' | sort | gum choose - else - local files=() - while IFS= read -r -d '' f; do - files+=("$(basename "$f")") - done < <(find "$directory" -maxdepth 1 -type f -name "$pattern" -print0 | sort -z) - select __file in "${files[@]}"; do - printf '%s\n' "$__file" - break - done - fi -} - tui_format() { - if [[ "$TUI_STYLE" == "gum" ]]; then + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then gum format "$@" else - printf '%s\n' "$*" + local line + for line in "$@"; do + _strip_format "$line" + done fi } + +tui_info() { + local message="$(_strip_format "$1")" + printf ' \033[1;34m▶\033[0m %s\n' "$message" +} + +tui_success() { + local message="$(_strip_format "$1")" + printf ' \033[1;32m✓\033[0m %s\n' "$message" +} + +tui_warn() { + local message="$(_strip_format "$1")" + printf ' \033[1;33m⚠\033[0m %s\n' "$message" >&2 +} + +tui_error() { + local message="$(_strip_format "$1")" + printf ' \033[1;31m✗\033[0m %s\n' "$message" >&2 +} + +tui_bold() { + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then + gum style --bold "$1" + else + printf '\033[1m%s\033[0m' "$1" + fi +} + +tui_separator() { + if [[ "$OMERON_TUI_MODE" == "gum" ]]; then + gum style --foreground 240 "────────────────────────────────────────" + else + printf ' \033[2m────────────────────────────────────────\033[0m\n' + fi +} + +tui_list() { + local items=("$@") + local item + for item in "${items[@]}"; do + printf ' \033[1;36m•\033[0m %s\n' "$(_strip_format "$item")" + done +} diff --git a/modules/core/packages.sh b/modules/core/packages.sh index 841c12f..866d34c 100755 --- a/modules/core/packages.sh +++ b/modules/core/packages.sh @@ -10,7 +10,7 @@ module_should_skip() { return 1; } module_prereqs() { require pacman pacman is_arch || { - log_error "This module requires an Arch-based system" + tui_error "This module requires an Arch-based system" return 1 } } @@ -22,7 +22,7 @@ module_main() { local all_packages=() if ((OMERON_FRESH_INSTALL)); then - tui_format "#{bold}Fresh install mode — installing everything#{normal}" + tui_bold "Fresh install mode — installing everything" groups=( "hyprland" "gpu" @@ -34,7 +34,7 @@ module_main() { "development" ) else - tui_format "#{bold}Existing system — checking for missing packages#{normal}" + tui_bold "Existing system — checking for missing packages" groups=( "hyprland" "audio" @@ -64,37 +64,38 @@ module_main() { fi done - tui_format "" - tui_format "#{bold}Package Summary:#{normal}" - tui_format " Total packages: ${total}" - tui_format " Already installed: ${existing}" - tui_format " To install: ${missing}" - tui_format "" + tui_separator + tui_bold "Package Summary" + tui_info "Total packages: $(tui_bold "$total")" + tui_success "Already installed: $(tui_bold "$existing")" + if ((missing > 0)); then + tui_warn "To install: $(tui_bold "$missing")" + fi + printf '\n' if ((missing == 0)); then - log_success "All packages already installed" + tui_success "All packages already installed" return 0 fi if ! tui_confirm "Install ${missing} missing packages?"; then - log_info "Package installation skipped by user" + tui_info "Package installation skipped by user" return 0 fi if ((OMERON_FRESH_INSTALL)); then - log_info "Running system update first..." + tui_info "Running system update first..." sudo_run pacman -Syu --noconfirm 2>&1 | tail -3 || true fi local pacman_pkgs=() local aur_pkgs=() - local gpu_pkgs=() + local pkg for pkg in "${all_packages[@]}"; do if is_package_installed "$pkg"; then continue fi - if pacman -Si "$pkg" >/dev/null 2>&1; then pacman_pkgs+=("$pkg") else @@ -103,22 +104,22 @@ module_main() { done if ((${#pacman_pkgs[@]})); then - log_info "Installing ${#pacman_pkgs[@]} pacman packages..." + tui_info "Installing ${#pacman_pkgs[@]} pacman packages..." tui_spin "Installing core packages..." sudo_run pacman -S --needed --noconfirm "${pacman_pkgs[@]}" - log_success "Core packages installed" + tui_success "Core packages installed" fi if ((${#aur_pkgs[@]})); then if have paru || have yay; then - log_info "Installing ${#aur_pkgs[@]} AUR packages..." - install_aur "${aur_pkgs[@]}" || log_warn "Some AUR packages may not have been installed" + tui_info "Installing ${#aur_pkgs[@]} AUR packages..." + install_aur "${aur_pkgs[@]}" || tui_warn "Some AUR packages may not have been installed" else - log_warn "No AUR helper found. Install manually: ${aur_pkgs[*]}" + tui_warn "No AUR helper found. Install manually: ${aur_pkgs[*]}" fi fi - log_success "Package installation complete" - log_info "Installed: $((missing - ${#aur_pkgs[@]})) | AUR/optional: ${#aur_pkgs[@]}" + tui_success "Package installation complete" + tui_info "Installed: $((missing - ${#aur_pkgs[@]})) | AUR/optional: ${#aur_pkgs[@]}" } get_group_packages() { diff --git a/modules/core/preflight.sh b/modules/core/preflight.sh index b5e8234..447a83f 100755 --- a/modules/core/preflight.sh +++ b/modules/core/preflight.sh @@ -13,7 +13,7 @@ module_should_skip() { return 1; } module_prereqs() { require pacman pacman is_arch || { - log_error "This module requires an Arch-based system" + tui_error "This module requires an Arch-based system" return 1 } } @@ -25,50 +25,47 @@ module_main() { export OMERON_DETECTED_GPU system_summary + printf '\n' if is_fresh_install; then OMERON_FRESH_INSTALL=1 export OMERON_FRESH_INSTALL - tui_format "" - tui_format "#{bold}#{yellow}⚠ Fresh system detected!#{normal}" - tui_format "Hyprland is not installed and no desktop session is running." - tui_format "" + tui_warn "Fresh system detected!" + tui_info "Hyprland is not installed and no desktop session is running." + printf '\n' local gpu_name - gpu_name="$(lspci -nn 2>/dev/null | grep -i 'vga\|3d\|display' | sed 's/.*: //' | head -1 || echo "unknown")" + gpu_name="$(lspci -nn 2>/dev/null | grep -E '\[0300\]|\[0302\]|\[0380\]' | sed 's/.*: //' | head -1 || echo "unknown")" - tui_format "#{bold}This installation will:#{normal}" - tui_format " • Hyprland compositor + tools" - tui_format " • GPU drivers for: ${gpu_name}" - tui_format " • Audio system (PipeWire)" - tui_format " • Network services (NetworkManager)" - tui_format " • Fonts and icon themes" - tui_format " • Dotfiles deployment" - tui_format "" + tui_bold "This installation will:" + tui_list \ + "Hyprland compositor + tools" \ + "GPU drivers for: ${gpu_name}" \ + "Audio system (PipeWire)" \ + "Network services (NetworkManager)" \ + "Fonts and icon themes" \ + "Dotfiles deployment" + printf '\n' if ! tui_confirm "Proceed with full system setup?"; then - log_info "Fresh installation aborted by user" + tui_info "Fresh installation aborted by user" exit 0 fi if ! have paru && ! have yay; then - log_info "No AUR helper found. Installing paru..." + tui_info "No AUR helper found. Installing paru..." install_aur_helper fi - if ! have gum; then - log_info "Installing gum for better TUI..." - sudo_run pacman -S --needed --noconfirm gum 2>/dev/null || true - tui_style + if ((!OMERON_HAS_GUM)) && have pacman; then + tui_install_gum 2>/dev/null || true fi - log_success "Preflight complete — ready for full installation" + tui_success "Preflight complete — ready for full installation" else - tui_format "" - tui_format "#{bold}#{green}✓ Existing Hyprland system detected#{normal}" - tui_format "Will check for missing packages and updates." - tui_format "" + tui_success "Existing Hyprland system detected" + tui_info "Will check for missing packages and updates." fi } @@ -84,7 +81,7 @@ install_aur_helper() { local build_dir build_dir="$(mktemp -d)" - log_info "Building paru from AUR..." + tui_info "Building paru from AUR..." sudo_run pacman -S --needed --noconfirm rustup 2>/dev/null || true if have rustup; then @@ -93,10 +90,10 @@ install_aur_helper() { if git clone https://aur.archlinux.org/paru.git "$build_dir/paru" 2>/dev/null; then (cd "$build_dir/paru" && makepkg -si --needed --noconfirm) 2>&1 | tail -5 || { - log_warn "paru build failed, trying yay..." + tui_warn "paru build failed, trying yay..." if git clone https://aur.archlinux.org/yay.git "$build_dir/yay" 2>/dev/null; then (cd "$build_dir/yay" && makepkg -si --needed --noconfirm) 2>&1 | tail -5 || { - log_warn "yay build failed too. Install manually: paru -S paru-bin" + tui_warn "yay build failed too. Install manually: paru -S paru-bin" } fi } diff --git a/modules/homelab/setup.sh b/modules/homelab/setup.sh index 4c6e11b..e5b2fab 100755 --- a/modules/homelab/setup.sh +++ b/modules/homelab/setup.sh @@ -17,9 +17,9 @@ module_main() { local homelab_config_dir="$HOME/.config/homelab" local homelab_config_file="$homelab_config_dir/config.yaml" - tui_format "#{bold}Homelab Control Center Setup#{normal}" - tui_format "This configures SSH access and connection details to your Unraid server." - tui_format "" + tui_bold "Homelab Control Center Setup" + tui_info "This configures SSH access and connection details to your Unraid server." + printf '\n' local server_address server_username @@ -59,13 +59,12 @@ CONFIG log_success "Homelab configuration saved to $homelab_config_file" - tui_format "" - tui_format "#{bold}Configuration Summary:#{normal}" - tui_format " Server address: ${server_address}" - tui_format " SSH username: ${server_username}" - tui_format "" - tui_format "You can edit the configuration anytime at:" - tui_format " ${homelab_config_file}" + printf '\n' + tui_bold "Configuration Summary:" + tui_info " Server address: ${server_address}" + tui_info " SSH username: ${server_username}" + printf '\n' + tui_info "You can edit the configuration anytime at: ${homelab_config_file}" if tui_confirm "Test SSH connection to ${server_username}@${server_address}?"; then log_info "Testing SSH connection..." diff --git a/modules/optional/install.sh b/modules/optional/install.sh index dc2f6a7..60512db 100755 --- a/modules/optional/install.sh +++ b/modules/optional/install.sh @@ -14,14 +14,13 @@ module_prereqs() { module_main() { log_section "Optional Software Selection" - tui_format "#{bold}Select software to install:#{normal}" - tui_format "Use space to select, enter to confirm." - tui_format "" + tui_bold "Select optional software to install:" + tui_info "Use space (gum) or enter indices (basic) to select." + printf '\n' local choices choices="$( - gum choose --no-limit \ - --header "Select optional packages (space to toggle, enter to confirm)" \ + tui_multiselect "Software Selection" \ "Obsidian" \ "Neovim" \ "Visual Studio Code" \ @@ -31,7 +30,7 @@ module_main() { "VLC" \ "PipeWire Tools" \ "Docker" \ - "Blender" 2>&1 + "Blender" )" if [[ -z "$choices" ]]; then