feat: Enhance Zsh configuration and setup scripts with improved plugin management and GNOME Keyring integration

This commit is contained in:
Marco Gallegos
2025-11-18 13:15:06 -06:00
parent ee8ff3c5ef
commit de2e8071ab
7 changed files with 257 additions and 37 deletions

12
.zshrc
View File

@@ -38,9 +38,17 @@ zstyle ':completion:*' menu select
# Cargar plugins específicos (zsh-autosuggestions y zsh-syntax-highlighting)
[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && \
source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh"
if [ ! -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && \
[ -r "/usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ]; then
source "/usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh"
fi
[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && \
source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
if [ ! -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && \
[ -r "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]; then
source "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
fi
# --- Oh My Posh --------------------------------------------------------------
# Asegúrate de que Oh My Posh esté instalado y el tema 'catppuccin_frappe.omp.json'
@@ -289,9 +297,9 @@ ytls() {
# --- GNOME Keyring -----------------------------------------------------------
# Iniciar gnome-keyring-daemon si la sesión es gráfica y no está corriendo
if [ -n "$DESKTOP_SESSION" ]; then
if [ -n "$DESKTOP_SESSION" ] && command -v gnome-keyring-daemon >/dev/null 2>&1; then
if ! pgrep -u "$USER" gnome-keyring-daemon > /dev/null 2>&1; then
eval $(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh 2>/dev/null)
eval "$(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh 2>/dev/null)" || true
fi
export SSH_AUTH_SOCK GPG_AGENT_INFO GNOME_KEYRING_CONTROL GNOME_KEYRING_PID
fi

View File

@@ -56,14 +56,14 @@ Selecciona las opciones que deseas instalar:
5) 🖨️ Configurar Impresoras (CUPS)
6) 🖱️ Instalar Tema de Cursor (Bibata)
7) 🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.)
8) 🎬 Instalar DaVinci Resolve (Intel Edition)
A) ✅ Instalar Todo (opciones 1, 2, 3, 4, 5, 6, 8)
F) 💾 Formatear un Disco (FAT32, exFAT, NTFS, ext4)
F) 💾 Habilitar Formatos FAT/exFAT/NTFS/ext4
H) 🎨 Instalar Configuración de Hyprland
R) 🎬 Instalar DaVinci Resolve (Intel Edition)
A) ✅ Instalar Todo (opciones 1, 2, 3, 4, 5, 6, 7, F, H)
0) 🚪 Salir
```
> **Nota:** La opción `A) Instalar Todo` ejecuta los módulos 1, 2, 3, 4, 5, 6 y 8. Antes de usarla asegúrate de haber descargado manualmente el instalador de DaVinci Resolve (ZIP) en `~/Downloads/`.
> **Nota:** La opción `A) Instalar Todo` ejecuta los módulos 1, 2, 3, 4, 5, 6, 7, F y H. DaVinci Resolve (`R`) no se incluye aquí; instálalo manualmente cuando ya tengas el ZIP en `~/Downloads/`.
## 📋 Módulos Disponibles
@@ -95,7 +95,11 @@ Selecciona las opciones que deseas instalar:
### 7. 🎨 Gestor de Iconos (`icon_manager.sh`)
- Menú interactivo para instalar y cambiar entre temas de iconos como Papirus, Tela y Candy.
### 8. 🎬 DaVinci Resolve (`davinci-resolve.sh`)
### F. 💾 Soporte de Formatos (`disk-format.sh`)
- Instala utilidades para FAT32, exFAT, NTFS y ext4
- Añade herramientas gráficas (GParted, GNOME Disks) para formateo manual
### R. 🎬 DaVinci Resolve (`davinci-resolve.sh`)
- Configuración de librerías y wrapper
## 🔧 Ejecutar Módulos Individualmente

View File

@@ -31,6 +31,7 @@ run_module_main() {
local PACMAN_BASE=(
git curl wget base-devel unzip htop fastfetch btop
vim nano tmux xdg-utils xdg-user-dirs stow
gnome-keyring libsecret seahorse openssh rsync
)
local PACMAN_MULTIMEDIA=(
vlc vlc-plugins-all libdvdcss audacity inkscape
@@ -145,6 +146,71 @@ run_module_main() {
# Configurar servicios
log_info "Configurando servicios..."
log_info "Configurando GNOME Keyring como agente de credenciales..."
mkdir -p "${HOME}/.config/environment.d"
cat <<'EOF' > "${HOME}/.config/environment.d/10-gnome-keyring.conf"
SSH_AUTH_SOCK=/run/user/$UID/keyring/ssh
EOF
if systemctl --user enable --now gnome-keyring-daemon.socket gnome-keyring-daemon.service >/dev/null 2>&1; then
log_success "GNOME Keyring listo para gestionar contraseñas y claves SSH."
else
log_warning "No se pudo habilitar gnome-keyring-daemon en systemd de usuario. Verifica que tu sesión use systemd (--user)."
fi
if command_exists gnome-keyring-daemon; then
local keyring_eval
keyring_eval="$(gnome-keyring-daemon --start --components=secrets,ssh 2>/dev/null)" || keyring_eval=""
if [[ -n "$keyring_eval" ]]; then
eval "$keyring_eval"
fi
fi
local keyring_socket="/run/user/$UID/keyring/ssh"
if [[ -S "$keyring_socket" ]]; then
export SSH_AUTH_SOCK="$keyring_socket"
fi
log_info "Vuelve a iniciar sesión para que las variables de entorno del keyring se apliquen."
if command_exists ssh-add; then
local ssh_dir="${HOME}/.ssh"
if [[ -d "$ssh_dir" ]]; then
mapfile -t ssh_private_keys < <(find "$ssh_dir" -maxdepth 1 -type f -name "id_*" ! -name "*.pub" ! -name "*-cert.pub" 2>/dev/null)
if [[ ${#ssh_private_keys[@]} -gt 0 ]]; then
log_info "Agregando claves SSH detectadas al keyring (se solicitará la passphrase si aplica)..."
for key_path in "${ssh_private_keys[@]}"; do
if [[ ! -r "$key_path" ]]; then
log_warning "No se puede leer la clave $(basename "$key_path"); revísala manualmente."
continue
fi
if ssh-keygen -y -f "$key_path" >/dev/null 2>&1; then
log_info "Registrando clave $(basename "$key_path")..."
local spinner_was_active=0
if [[ -n "${SPINNER_PID:-}" ]]; then
spinner_was_active=1
fi
if declare -F pause_spinner >/dev/null; then
pause_spinner
fi
if SSH_AUTH_SOCK="$SSH_AUTH_SOCK" ssh-add "$key_path"; then
log_success "Clave $(basename "$key_path") añadida al keyring."
else
log_warning "No se pudo añadir la clave $(basename "$key_path")."
fi
if (( spinner_was_active )) && declare -F resume_spinner >/dev/null; then
resume_spinner
fi
else
log_warning "La clave $(basename "$key_path") parece inválida. Se omite."
fi
done
else
log_info "No se encontraron claves privadas SSH en ${ssh_dir}."
fi
else
log_info "No se detectó el directorio ~/.ssh; omitiendo carga de claves."
fi
else
log_warning "ssh-add no está disponible; no se pueden registrar claves en el keyring."
fi
# Habilitar keyd si está instalado
if command_exists keyd; then
log_info "Habilitando servicio keyd..."

View File

@@ -14,19 +14,29 @@ NC='\033[0m' # No Color
BOLD='\033[1m'
# Funciones de logging
_maybe_clear_spinner() {
if declare -F spinner_clear_line >/dev/null; then
spinner_clear_line
fi
}
log_info() {
_maybe_clear_spinner
echo -e "${BLUE}${NC} ${BOLD}$1${NC}"
}
log_success() {
_maybe_clear_spinner
echo -e "${GREEN}${NC} ${GREEN}$1${NC}"
}
log_warning() {
_maybe_clear_spinner
echo -e "${YELLOW}${NC} ${YELLOW}$1${NC}"
}
log_error() {
_maybe_clear_spinner
echo -e "${RED}${NC} ${RED}$1${NC}"
}

0
modules/disk-format.sh Normal file → Executable file
View File

View File

@@ -29,6 +29,7 @@ install_zsh() {
# --- 1. Instalar paquetes necesarios desde Pacman ---
log_info "Instalando Zsh y herramientas esenciales..."
local pkgs=(
git
zsh
zsh-completions
zsh-syntax-highlighting
@@ -80,6 +81,34 @@ install_zsh() {
log_info "Oh My Zsh ya está instalado."
fi
# Asegurar plugins personalizados de Oh My Zsh (zsh-autosuggestions, zsh-syntax-highlighting)
local zsh_custom="${target_ohmyzsh_dir}/custom"
local zsh_custom_plugins="${zsh_custom}/plugins"
mkdir -p "$zsh_custom_plugins"
ensure_omz_plugin() {
local name="$1"
local repo="$2"
local plugin_path="${zsh_custom_plugins}/${name}"
if [[ -d "${plugin_path}/.git" ]]; then
log_info "Actualizando plugin ${name}..."
git -C "$plugin_path" pull --ff-only >/dev/null 2>&1 || true
elif [[ -d "$plugin_path" ]]; then
log_info "Plugin ${name} ya existe."
else
log_info "Clonando plugin ${name}..."
if git clone --depth 1 "$repo" "$plugin_path" >/dev/null 2>&1; then
log_success "Plugin ${name} instalado."
else
log_warning "No se pudo clonar ${name}. Se usará la versión de los paquetes del sistema."
fi
fi
}
ensure_omz_plugin "zsh-autosuggestions" "https://github.com/zsh-users/zsh-autosuggestions.git"
ensure_omz_plugin "zsh-syntax-highlighting" "https://github.com/zsh-users/zsh-syntax-highlighting.git"
# --- 3. Descargar y configurar el .zshrc personalizado ---
log_info "Actualizando configuración .zshrc..."
local repo_zshrc_path="${SCRIPT_DIR_ROOT}/.zshrc"
@@ -145,6 +174,14 @@ install_zsh() {
fi
fi
if command_exists oh-my-posh; then
local omp_completion_dir="${target_home}/.local/share/zsh/site-functions"
mkdir -p "$omp_completion_dir"
if oh-my-posh completion zsh > "${omp_completion_dir}/_oh-my-posh" 2>/dev/null; then
log_success "Autocompletado de Oh My Posh actualizado."
fi
fi
# --- 5. Cambiar el shell por defecto a Zsh para el usuario actual ---
local current_shell
current_shell="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f7)"

View File

@@ -9,6 +9,7 @@ set -u
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULES_DIR="${SCRIPT_DIR}/modules"
REPO_BASE="https://raw.githubusercontent.com/marcogll/omarchy_setup/main"
SUDO_PASSWORD=""
# Verificar que los módulos existen
if [[ ! -d "${MODULES_DIR}" ]] || [[ ! -f "${MODULES_DIR}/common.sh" ]]; then
@@ -35,23 +36,59 @@ chmod +x "${MODULES_DIR}"/*.sh 2>/dev/null || true
SPINNER_PID=
SPINNER_DEVICE_ACTIVE=
SPINNER_MESSAGE=
spinner_clear_line() {
local device="${SPINNER_DEVICE_ACTIVE:-/dev/tty}"
if [[ ! -w "$device" ]]; then
device="/dev/null"
fi
printf '\r\033[K' >"$device" 2>/dev/null || true
}
pause_spinner() {
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 || true
wait "$SPINNER_PID" &>/dev/null || true
fi
spinner_clear_line
printf '\033[?25h' >"$device" 2>/dev/null || true
SPINNER_PID=
}
resume_spinner() {
if [[ -n "$SPINNER_MESSAGE" ]]; then
start_spinner "$SPINNER_MESSAGE"
fi
}
# Inicia una animación de spinner en segundo plano
# Uso: start_spinner "Mensaje..."
start_spinner() {
local message="$1"
if [[ -n "$SPINNER_PID" ]]; then
pause_spinner
fi
local device="/dev/tty"
if [[ ! -w "$device" ]]; then
device="/dev/null"
fi
SPINNER_DEVICE_ACTIVE="$device"
SPINNER_MESSAGE="$message"
(
local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
local dev="$device"
local msg="$message"
while :; do
for (( i=0; i<${#chars}; i++ )); do
printf '\r\033[K%s %s' "${CYAN}${chars:$i:1}${NC}" "$message" >"$dev"
printf '\r\033[K%s %s' "${CYAN}${chars:$i:1}${NC}" "$msg" >"$dev"
sleep 0.1
done
done
@@ -67,28 +104,60 @@ 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
printf '\r\033[K' >"$device"
pause_spinner
if [[ $exit_code -eq 0 ]]; then
log_success "$success_msg"
else
log_error "$error_msg"
fi
# Restaurar cursor
printf '\033[?25h' >"$device" 2>/dev/null || true
SPINNER_PID=
SPINNER_DEVICE_ACTIVE=
SPINNER_MESSAGE=
}
ensure_sudo_session() {
if sudo -n true 2>/dev/null; then
return 0
fi
if [[ -n "${SUDO_PASSWORD:-}" ]]; then
if printf '%s\n' "$SUDO_PASSWORD" | sudo -S -v >/dev/null 2>&1; then
return 0
fi
SUDO_PASSWORD=""
log_warning "La contraseña de sudo almacenada no es válida. Se solicitará nuevamente."
fi
pause_spinner
local attempts=0
while (( attempts < 3 )); do
if (( attempts == 0 )); then
log_info "Se requiere autenticación de sudo para continuar."
else
log_info "Intenta ingresar la contraseña nuevamente."
fi
local password_input=""
read -s -p "Contraseña de sudo: " password_input
echo ""
if [[ -z "$password_input" ]]; then
log_warning "La contraseña no puede estar vacía."
elif printf '%s\n' "$password_input" | sudo -S -v >/dev/null 2>&1; then
SUDO_PASSWORD="$password_input"
log_success "Sesión de sudo autenticada."
return 0
else
log_error "Contraseña de sudo incorrecta."
fi
((attempts++))
done
log_error "No se pudo autenticar con sudo después de varios intentos."
return 1
}
# --- Definición de Módulos ---
@@ -101,17 +170,17 @@ MODULES=(
["1"]="apps;run_module_main;📦 Instalar Aplicaciones (VS Code, VLC, drivers, etc.);bg"
["2"]="zsh-config;install_zsh;🐚 Configurar Zsh (shell, plugins, config);bg"
["3"]="docker;install_docker;🐳 Instalar Docker y Portainer;fg"
["4"]="zerotier;install_zerotier;🌐 Instalar ZeroTier VPN;bg"
["4"]="zerotier;install_zerotier;🌐 Instalar ZeroTier VPN;fg"
["5"]="printer;install_printer;🖨️ Configurar Impresoras (CUPS);bg"
["6"]="mouse_cursor;install_mouse_cursor;🖱️ Instalar Tema de Cursor (Bibata);bg"
["7"]="icon_manager;run_module_main;🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.);fg"
["8"]="davinci-resolve;install_davinci_resolve;🎬 Instalar DaVinci Resolve (Intel Edition);fg"
["H"]="hyprland-config;run_module_main;🎨 Instalar Configuración de Hyprland;bg"
["F"]="disk-format;run_module_main;💾 Habilitar Formatos FAT/exFAT/NTFS/ext4;bg"
["R"]="davinci-resolve;install_davinci_resolve;🎬 Instalar DaVinci Resolve (Intel Edition);fg"
["H"]="hyprland-config;run_module_main;🎨 Instalar Configuración de Hyprland;bg"
)
# Módulos a incluir en la opción "Instalar Todo"
INSTALL_ALL_CHOICES=("1" "2" "3" "4" "5" "6" "7" "8" "H")
INSTALL_ALL_CHOICES=("1" "2" "3" "4" "5" "6" "7" "F" "H")
# Función para mostrar el menú
show_menu() {
@@ -129,7 +198,7 @@ show_menu() {
echo -e " ${GREEN}${key})${NC} ${description}"
done | sort -V
echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (1, 2, 3, 4, 5, 6, 7, 8, H)"
echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (1, 2, 3, 4, 5, 6, 7, F, H)"
echo -e " ${GREEN}0)${NC} 🚪 Salir"
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
@@ -203,8 +272,16 @@ install_all() {
local failed=()
for choice in "${INSTALL_ALL_CHOICES[@]}"; do
if [[ "$choice" == "R" ]]; then
continue
fi
IFS=';' read -r module_file _ description type <<< "${MODULES[$choice]}"
if ! ensure_sudo_session; then
failed+=("${module_file}")
continue
fi
# Separador visual para cada módulo
echo -e "\n${MAGENTA}────────────────────────────────────────────────────────────${NC}"
log_step "Iniciando Módulo: ${description}"
@@ -237,9 +314,9 @@ install_all() {
# Función principal
main() {
# Limpieza al salir: detener el spinner y restaurar el cursor
trap 'stop_spinner 1 "Script interrumpido." >/dev/null 2>&1; exit 1' INT TERM
trap 'stop_spinner 1 "Script interrumpido." >/dev/null 2>&1; unset SUDO_PASSWORD; exit 1' INT TERM
# Limpieza final al salir normalmente
trap 'tput cnorm' EXIT
trap 'tput cnorm; unset SUDO_PASSWORD' EXIT
# Verificar que estamos en Arch Linux
if [[ ! -f /etc/arch-release ]]; then
@@ -248,15 +325,15 @@ main() {
fi
# Verificar permisos de sudo
if ! sudo -n true 2>/dev/null; then
log_info "Este script requiere permisos de sudo"
sudo -v
if ! ensure_sudo_session; then
log_error "No se pudieron obtener privilegios de sudo. Saliendo."
exit 1
fi
# Mantener sudo activo en background
local parent_pid=$$
(while true; do
sudo -n true
sudo -n true >/dev/null 2>&1
sleep 60
kill -0 "$parent_pid" || exit
done 2>/dev/null) &
@@ -265,6 +342,10 @@ main() {
# Exportar funciones para que los submódulos las puedan usar
export -f start_spinner
export -f stop_spinner
export -f pause_spinner
export -f resume_spinner
export -f spinner_clear_line
export -f ensure_sudo_session
while true; do
show_menu
@@ -275,7 +356,7 @@ main() {
IFS=';' read -r _ _ description type <<< "${MODULES[$choice]}"
# Manejo especial para DaVinci Resolve
if [[ "$choice" == "8" ]]; then
if [[ "$choice" == "R" ]]; then
log_warning "DaVinci Resolve requiere el ZIP de instalación en ~/Downloads/"
echo -ne "${BOLD}¿Continuar con la instalación? [s/N]: ${NC} "
read -r confirm
@@ -286,6 +367,11 @@ main() {
fi
fi
if ! ensure_sudo_session; then
read -p "Presiona Enter para continuar..."
continue
fi
if [[ "$type" == "bg" ]]; then
spinner_msg="${description#* }..." # "Instalar Apps..."
start_spinner "${spinner_msg}"
@@ -300,11 +386,14 @@ main() {
fi
echo ""
if declare -F pause_spinner >/dev/null; then
pause_spinner
fi
read -p "Presiona Enter para continuar..."
elif [[ "$choice" == "A" ]]; then
log_warning "La opción 'Instalar Todo' ejecutará los módulos: 1, 2, 3, 4, 5, 6, 7, 8 y H."
log_warning "DaVinci Resolve requiere que el ZIP de instalación esté en ~/Downloads/."
log_warning "La opción 'Instalar Todo' ejecutará los módulos: 1, 2, 3, 4, 5, 6, 7, F y H."
log_info "DaVinci Resolve (opción R) no se ejecutará en este lote; instálalo aparte cuando ya tengas el ZIP."
echo -ne "${BOLD}¿Confirmas que deseas instalar todas las opciones ahora? [s/N]: ${NC}"
read -r confirm
if [[ "${confirm}" =~ ^[SsYy]$ ]]; then
@@ -313,12 +402,18 @@ main() {
log_info "Instalación cancelada"
fi
echo ""
if declare -F pause_spinner >/dev/null; then
pause_spinner
fi
read -p "Presiona Enter para continuar..."
elif [[ "$choice" == "0" ]]; then
log_info "Saliendo..."
exit 0
else
log_error "Opción inválida. Presiona Enter para continuar..."
if declare -F pause_spinner >/dev/null; then
pause_spinner
fi
read -r
fi
done