diff --git a/modules/apps.sh b/modules/apps.sh index 77ffd96..de306b9 100755 --- a/modules/apps.sh +++ b/modules/apps.sh @@ -116,8 +116,6 @@ run_module_main() { log_warning "Algunos paquetes OpenCL no se pudieron instalar" } - AUR_HELPER=$(ensure_aur_helper) - if [[ ! -f /etc/OpenCL/vendors/intel.icd ]] && [[ -f /usr/lib/intel-opencl/libigdrcl.so ]]; then log_info "Configurando OpenCL para Intel..." sudo mkdir -p /etc/OpenCL/vendors @@ -139,19 +137,10 @@ run_module_main() { fi log_info "Instalando aplicaciones desde AUR..." - - for pkg in "${AUR_PACKAGES[@]}"; do - log_info "Instalando ${pkg}..." - if [ "$AUR_HELPER" = "yay" ]; then - yay -S --noconfirm "$pkg" || { - log_warning "No se pudo instalar ${pkg} desde AUR" - } - elif [ "$AUR_HELPER" = "paru" ]; then - paru -S --noconfirm "$pkg" || { - log_warning "No se pudo instalar ${pkg} desde AUR" - } - fi - done + log_warning "Este paso puede tardar varios minutos; qt5-webengine y teamviewer descargan y compilan bastante." + if ! aur_install_packages "${AUR_PACKAGES[@]}"; then + log_warning "Algunas aplicaciones de AUR no se pudieron instalar automáticamente." + fi # Configurar servicios log_info "Configurando servicios..." diff --git a/modules/common.sh b/modules/common.sh index 3a715c0..b062ab7 100755 --- a/modules/common.sh +++ b/modules/common.sh @@ -67,10 +67,16 @@ check_and_install_pkg() { # pacman -Q es más fiable para paquetes individuales. if ! pacman -Q "$pkg_name" &>/dev/null; then log_info "Instalando ${pkg_name}..." - sudo pacman -S --noconfirm --needed "$pkg_name" || log_warning "No se pudo instalar ${pkg_name}." + if sudo pacman -S --noconfirm --needed "$pkg_name"; then + return 0 + else + log_warning "No se pudo instalar ${pkg_name}." + return 1 + fi else log_info "${pkg_name} ya está instalado." fi + return 0 } @@ -93,6 +99,42 @@ ensure_aur_helper() { fi } +aur_install_packages() { + local packages=("$@") + if [[ ${#packages[@]} -eq 0 ]]; then + return 0 + fi + + local helper="${AUR_HELPER_CMD:-}" + if [[ -z "$helper" ]]; then + helper="$(ensure_aur_helper)" || helper="" + fi + + if [[ -z "$helper" ]]; then + log_error "No se pudo determinar un helper de AUR disponible." + return 1 + fi + + local -a base_flags=(--noconfirm --needed --noeditmenu --nodiffmenu --nocleanmenu) + AUR_HELPER_CMD="$helper" + local status=0 + case "$helper" in + yay) + "$helper" -S "${base_flags[@]}" --answerdiff None --answerclean All --answeredit None --mflags "--noconfirm" --cleanafter "${packages[@]}" + status=$? + ;; + paru) + "$helper" -S "${base_flags[@]}" --skipreview --cleanafter --mflags "--noconfirm" "${packages[@]}" + status=$? + ;; + *) + log_error "Helper AUR desconocido: ${helper}" + return 1 + ;; + esac + return $status +} + # Función para actualizar sistema update_system() { log_step "Actualizando sistema" diff --git a/modules/davinci-resolve.sh b/modules/davinci-resolve.sh index 27923f2..94e35c8 100755 --- a/modules/davinci-resolve.sh +++ b/modules/davinci-resolve.sh @@ -120,14 +120,12 @@ install_davinci_resolve() { stop_spinner $? "Dependencias de Pacman instaladas." # Instalar dependencias de AUR - local AUR_HELPER - AUR_HELPER=$(ensure_aur_helper) - if [[ -n "$AUR_HELPER" ]]; then - start_spinner "Instalando dependencias de AUR con ${AUR_HELPER}..." - "$AUR_HELPER" -S --needed --noconfirm "${AUR_DEPS[@]}" &> /dev/null - stop_spinner $? "Dependencias de AUR instaladas." + start_spinner "Instalando dependencias de AUR..." + if aur_install_packages "${AUR_DEPS[@]}"; then + stop_spinner 0 "Dependencias de AUR instaladas." else - log_error "No se encontró un ayudante de AUR (yay, paru). No se pueden instalar paquetes como 'intel-compute-runtime'." + stop_spinner 1 "Falló la instalación de dependencias de AUR." + log_error "No se pudieron instalar paquetes como 'intel-compute-runtime' desde AUR." return 1 fi diff --git a/modules/printer.sh b/modules/printer.sh index ed7c3fa..97fd24d 100755 --- a/modules/printer.sh +++ b/modules/printer.sh @@ -8,50 +8,64 @@ source "${SCRIPT_DIR}/common.sh" install_printer() { log_step "Configuración de Impresoras (CUPS)" - - # Instalar CUPS y drivers comunes - log_info "Instalando CUPS y drivers de impresora..." - sudo pacman -S --noconfirm --needed \ - cups cups-pdf \ - ghostscript gsfonts \ - gutenprint foomatic-db-engine foomatic-db foomatic-db-ppds foomatic-db-nonfree-ppds foomatic-db-nonfree \ - system-config-printer \ - avahi || { - log_error "Error al instalar CUPS" - return 1 - } - - # Instalar drivers específicos desde AUR (para Epson) - log_info "Buscando drivers de Epson en AUR..." - local AUR_DRIVERS=("epson-inkjet-printer-escpr" "epson-inkjet-printer-escpr2") - local AUR_HELPER - AUR_HELPER=$(ensure_aur_helper) - if [[ -n "$AUR_HELPER" ]]; then - log_info "Instalando drivers de Epson con ${AUR_HELPER}..." - "$AUR_HELPER" -S --noconfirm --needed "${AUR_DRIVERS[@]}" || log_warning "No se pudieron instalar todos los drivers de Epson desde AUR." + local target_user="${SUDO_USER:-$USER}" + + log_info "Instalando CUPS y paquetes base..." + local base_pkgs=( + cups cups-pdf cups-filters + ghostscript gsfonts + gutenprint + foomatic-db-engine foomatic-db foomatic-db-ppds + foomatic-db-nonfree foomatic-db-nonfree-ppds + system-config-printer + avahi nss-mdns + ) + local pkg_failed=false + for pkg in "${base_pkgs[@]}"; do + if ! check_and_install_pkg "$pkg"; then + pkg_failed=true + fi + done + if [[ "$pkg_failed" == true ]]; then + log_warning "Algunos paquetes base no pudieron instalarse. Revisa los mensajes anteriores." + fi + + log_info "Instalando drivers para Epson (ESC/P-R)..." + local aur_drivers=("epson-inkjet-printer-escpr" "epson-inkjet-printer-escpr2" "epson-printer-utility") + if ! aur_install_packages "${aur_drivers[@]}"; then + log_warning "No se pudieron instalar todos los drivers de Epson de forma automática. Revisa 'epson-inkjet-printer-escpr2' y 'epson-printer-utility' manualmente." + fi + + log_info "Verificando servicios de impresión..." + local services=("cups.service" "avahi-daemon.service") + for svc in "${services[@]}"; do + if sudo systemctl is-enabled "$svc" &>/dev/null; then + log_info "${svc} ya está habilitado." + else + sudo systemctl enable "$svc" + log_success "${svc} habilitado." + fi + + if sudo systemctl is-active "$svc" &>/dev/null; then + log_info "${svc} ya está en ejecución." + else + sudo systemctl start "$svc" + log_success "${svc} iniciado." + fi + done + + if ! id -nG "$target_user" | grep -qw lp; then + log_info "Agregando usuario ${target_user} al grupo lp..." + sudo usermod -aG lp "$target_user" else - log_error "No se encontró un ayudante de AUR (yay, paru). No se pueden instalar los drivers de Epson." - # No retornamos error, el resto de la configuración puede continuar + log_info "El usuario ${target_user} ya pertenece al grupo lp." fi - # Habilitar y iniciar servicios - log_info "Habilitando servicios de impresora..." - sudo systemctl enable cups.service - sudo systemctl enable avahi-daemon.service - sudo systemctl start cups.service - sudo systemctl start avahi-daemon.service - - # Agregar usuario al grupo lp (si no está ya) - if ! groups "$USER" | grep -q lp; then - log_info "Agregando usuario al grupo lp..." - sudo usermod -aG lp "$USER" - fi - - log_success "CUPS instalado y configurado" - log_info "Accede a la interfaz web de CUPS en: http://localhost:631" - log_info "O usa: system-config-printer para configurar impresoras" - + log_success "Dependencias de impresión instaladas." + log_info "Añade tu impresora Epson L4150 desde http://localhost:631 o con 'system-config-printer'." + log_info "El módulo no configura impresoras automáticamente; solo deja listas las dependencias." + return 0 } diff --git a/modules/zsh-config.sh b/modules/zsh-config.sh index fde477a..244bac4 100755 --- a/modules/zsh-config.sh +++ b/modules/zsh-config.sh @@ -5,6 +5,7 @@ # Asegurarse de que las funciones comunes están cargadas SCRIPT_DIR_MODULE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SCRIPT_DIR_ROOT="$(cd "${SCRIPT_DIR_MODULE}/.." && pwd)" if [[ -f "${SCRIPT_DIR_MODULE}/common.sh" ]]; then source "${SCRIPT_DIR_MODULE}/common.sh" else @@ -15,6 +16,16 @@ fi install_zsh() { log_step "Configuración Completa de Zsh" + local target_user="${SUDO_USER:-$USER}" + local target_home="$HOME" + if [[ -n "${SUDO_USER:-}" ]]; then + target_home="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f6)" + if [[ -z "$target_home" ]]; then + target_home="$(eval echo "~${target_user}")" + fi + fi + target_home="${target_home:-$HOME}" + # --- 1. Instalar paquetes necesarios desde Pacman --- log_info "Instalando Zsh y herramientas esenciales..." local pkgs=( @@ -22,7 +33,6 @@ install_zsh() { zsh-completions zsh-syntax-highlighting zsh-autosuggestions - oh-my-posh # Para el prompt zoxide # Navegación inteligente fastfetch # Información del sistema yt-dlp # Descarga de videos/audio @@ -31,13 +41,38 @@ install_zsh() { for pkg in "${pkgs[@]}"; do check_and_install_pkg "$pkg" done + + # Instalar Oh My Posh con fallback a AUR si es necesario + if ! command_exists oh-my-posh; then + log_info "Instalando Oh My Posh..." + if command_exists pacman && sudo pacman -S --noconfirm --needed oh-my-posh 2>/dev/null; then + log_success "Oh My Posh instalado desde pacman." + else + log_warning "Pacman no pudo instalar oh-my-posh. Intentando con un helper AUR..." + if aur_install_packages "oh-my-posh-bin"; then + log_success "Oh My Posh instalado usando helper AUR (${AUR_HELPER_CMD})." + else + log_warning "No se pudo instalar Oh My Posh mediante pacman ni AUR." + log_info "Descargando instalador oficial de Oh My Posh..." + if curl -fsSL https://ohmyposh.dev/install.sh | sudo bash -s -- -d /usr/local/bin; then + log_success "Oh My Posh instalado usando el script oficial." + else + log_error "Fallo la instalación de Oh My Posh usando el script oficial." + return 1 + fi + fi + fi + else + log_info "Oh My Posh ya está instalado." + fi # --- 2. Instalar Oh My Zsh (si no existe) --- - if [[ ! -d "$HOME/.oh-my-zsh" ]]; then + local target_ohmyzsh_dir="${target_home}/.oh-my-zsh" + if [[ ! -d "$target_ohmyzsh_dir" ]]; then log_info "Instalando Oh My Zsh..." # Usar RUNZSH=no para evitar que inicie un nuevo shell y CHSH=no para no cambiar el shell aún - sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc - if [[ $? -ne 0 ]]; then + if ! env HOME="$target_home" RUNZSH=no CHSH=no \ + sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc; then log_error "Falló la instalación de Oh My Zsh." return 1 fi @@ -46,39 +81,84 @@ install_zsh() { fi # --- 3. Descargar y configurar el .zshrc personalizado --- - log_info "Descargando configuración .zshrc desde el repositorio..." - # Crear copia de seguridad antes de sobrescribir - backup_file "$HOME/.zshrc" || return 1 + log_info "Actualizando configuración .zshrc..." + local repo_zshrc_path="${SCRIPT_DIR_ROOT}/.zshrc" + local tmp_download="${target_home}/.zshrc.omarchy-tmp" + local source_file="" - if curl -fsSL "${REPO_BASE}/.zshrc" -o "$HOME/.zshrc.omarchy-tmp" && [[ -s "$HOME/.zshrc.omarchy-tmp" ]]; then - mv "$HOME/.zshrc.omarchy-tmp" "$HOME/.zshrc" - log_success "Archivo .zshrc actualizado." + if curl -fsSL "${REPO_BASE}/.zshrc" -o "$tmp_download" && [[ -s "$tmp_download" ]]; then + source_file="$tmp_download" + log_success "Configuración .zshrc descargada desde el repositorio remoto." else - log_error "No se pudo descargar el archivo .zshrc." - return 1 + rm -f "$tmp_download" + if [[ -f "$repo_zshrc_path" ]]; then + log_warning "No se pudo descargar .zshrc. Usando la copia local del repositorio." + source_file="$repo_zshrc_path" + else + log_error "No se pudo obtener la configuración .zshrc (sin red y sin copia local)." + return 1 + fi + fi + + # Crear copia de seguridad antes de sobrescribir + backup_file "${target_home}/.zshrc" || { rm -f "$tmp_download"; return 1; } + + if [[ "$source_file" == "$tmp_download" ]]; then + if mv "$tmp_download" "${target_home}/.zshrc"; then + log_success "Archivo .zshrc actualizado." + else + rm -f "$tmp_download" + log_error "No se pudo mover el archivo .zshrc descargado." + return 1 + fi + else + if cp "$source_file" "${target_home}/.zshrc"; then + log_success "Archivo .zshrc actualizado desde la copia local." + else + log_error "No se pudo copiar la configuración .zshrc local." + return 1 + fi fi # --- 4. Descargar el tema de Oh My Posh --- log_info "Configurando tema de Oh My Posh (Catppuccin Frappe)..." - local posh_themes_dir="$HOME/.poshthemes" + local posh_themes_dir="${target_home}/.poshthemes" local theme_file="$posh_themes_dir/catppuccin_frappe.omp.json" + local posh_theme_local="${SCRIPT_DIR_ROOT}/themes/catppuccin_frappe.omp.json" mkdir -p "$posh_themes_dir" if curl -fsSL "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/catppuccin_frappe.omp.json" -o "$theme_file"; then + chmod 644 "$theme_file" 2>/dev/null || true log_success "Tema Catppuccin Frappe descargado en $theme_file" else - log_error "No se pudo descargar el tema de Oh My Posh." - # No retornamos error, el .zshrc tiene un fallback + rm -f "$theme_file" + if [[ -f "$posh_theme_local" ]]; then + if cp "$posh_theme_local" "$theme_file"; then + chmod 644 "$theme_file" 2>/dev/null || true + log_warning "No se pudo descargar el tema remoto. Se utilizó la copia incluida en el repositorio." + else + log_error "No se pudo copiar la versión local del tema Catppuccin." + fi + else + log_error "No se pudo descargar el tema de Oh My Posh y no hay copia local disponible." + # No retornamos error, el .zshrc tiene un fallback + fi fi # --- 5. Cambiar el shell por defecto a Zsh para el usuario actual --- - if [[ "$(basename "$SHELL")" != "zsh" ]]; then + local current_shell + current_shell="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f7)" + current_shell="${current_shell:-$SHELL}" + if [[ "$(basename "$current_shell")" != "zsh" ]]; then log_info "Cambiando el shell por defecto a Zsh..." - # chsh requiere la contraseña del usuario - if chsh -s "$(which zsh)"; then + local zsh_path + zsh_path="$(command -v zsh)" + if [[ -z "$zsh_path" ]]; then + log_error "No se encontró la ruta de Zsh. Aborta el cambio de shell." + elif sudo -n chsh -s "$zsh_path" "$target_user"; then log_success "Shell cambiado a Zsh. El cambio será efectivo en el próximo inicio de sesión." else - log_error "No se pudo cambiar el shell. Por favor, ejecute 'chsh -s $(which zsh)' manualmente." + log_error "No se pudo cambiar el shell automáticamente. Ejecuta 'sudo chsh -s \"$zsh_path\" $target_user' manualmente." fi else log_info "Zsh ya es el shell por defecto." @@ -90,9 +170,9 @@ install_zsh() { if [ -t 1 ]; then exec zsh fi' - if [[ -f "$HOME/.bashrc" ]] && ! grep -q "exec zsh" "$HOME/.bashrc"; then + if [[ -f "${target_home}/.bashrc" ]] && ! grep -q "exec zsh" "${target_home}/.bashrc"; then log_info "Configurando .bashrc para iniciar Zsh automáticamente..." - echo "$bashrc_zsh_loader" >> "$HOME/.bashrc" + echo "$bashrc_zsh_loader" >> "${target_home}/.bashrc" else log_info ".bashrc ya está configurado para lanzar Zsh." fi diff --git a/omarchy-setup.sh b/omarchy-setup.sh index e78b13f..4a4ea9d 100755 --- a/omarchy-setup.sh +++ b/omarchy-setup.sh @@ -34,22 +34,31 @@ chmod +x "${MODULES_DIR}"/*.sh 2>/dev/null || true # --- Funciones de UI Mejorada (Spinner y Barra de Progreso) --- SPINNER_PID= +SPINNER_DEVICE_ACTIVE= # Inicia una animación de spinner en segundo plano # Uso: start_spinner "Mensaje..." start_spinner() { + local message="$1" + local device="/dev/tty" + if [[ ! -w "$device" ]]; then + device="/dev/null" + fi + SPINNER_DEVICE_ACTIVE="$device" + ( local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" + local dev="$device" while :; do for (( i=0; i<${#chars}; i++ )); do - echo -ne "${CYAN}${chars:$i:1}${NC} $1\r" + printf '\r\033[K%s %s' "${CYAN}${chars:$i:1}${NC}" "$message" >"$dev" sleep 0.1 done done ) & SPINNER_PID=$! - # Ocultar cursor - tput civis + # Ocultar cursor en la terminal, si es posible + printf '\033[?25l' >"$device" 2>/dev/null || true } # Detiene el spinner y muestra un mensaje de finalización @@ -58,14 +67,18 @@ stop_spinner() { local exit_code=$1 local success_msg=$2 local error_msg=${3:-"Ocurrió un error"} - + local device="${SPINNER_DEVICE_ACTIVE:-/dev/tty}" + if [[ ! -w "$device" ]]; then + device="/dev/null" + fi + if [[ -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then kill "$SPINNER_PID" &>/dev/null wait "$SPINNER_PID" &>/dev/null fi # Limpiar la línea del spinner - echo -ne "\r\033[K" + printf '\r\033[K' >"$device" if [[ $exit_code -eq 0 ]]; then log_success "$success_msg" @@ -73,8 +86,9 @@ stop_spinner() { log_error "$error_msg" fi # Restaurar cursor - tput cnorm + printf '\033[?25h' >"$device" 2>/dev/null || true SPINNER_PID= + SPINNER_DEVICE_ACTIVE= } # --- Definición de Módulos --- diff --git a/themes/catppuccin_frappe.omp.json b/themes/catppuccin_frappe.omp.json new file mode 100644 index 0000000..5059aa5 --- /dev/null +++ b/themes/catppuccin_frappe.omp.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json", + "final_space": true, + "console_title_template": "{{ .Folder }}", + "blocks": [ + { + "type": "prompt", + "alignment": "left", + "segments": [ + { + "type": "text", + "style": "plain", + "foreground": "#c6d0f5", + "background": "#303446", + "properties": { + "text": "omarchy" + } + }, + { + "type": "path", + "style": "plain", + "foreground": "#303446", + "background": "#81c8be", + "properties": { + "style": "folder", + "enable_hyperlink": true + } + }, + { + "type": "git", + "style": "plain", + "foreground": "#303446", + "background": "#f4b8e4", + "properties": { + "branch_icon": "", + "display_status": true, + "display_upstream_icon": true, + "template": "git {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }} *{{ end }}" + } + } + ] + }, + { + "type": "prompt", + "alignment": "right", + "segments": [ + { + "type": "executiontime", + "style": "plain", + "foreground": "#c6d0f5", + "background": "#626880", + "properties": { + "template": "{{ if gt .Milliseconds 500 }}time {{ .FormattedMs }}{{ end }}" + } + }, + { + "type": "time", + "style": "plain", + "foreground": "#303446", + "background": "#e5c890", + "properties": { + "time_format": "15:04" + } + } + ] + } + ] +}