# Creando Formularios Interactivos con Gum ## Introducción [Gum](https://github.com/charmbracelet/gum) es una herramienta de línea de comandos desarrollada por [Charm](https://charm.sh/) que permite crear interfaces de texto (TUI) elegantes y funcionales para scripts Bash. Con Gum, puedes mejorar dramáticamente la experiencia de usuario de tus scripts de shell, añadiendo formularios interactivos, menús, estilos y más. ![Ejemplo interfaz Gum](img/gum-overview.png) Este tutorial cubre cómo utilizar Gum para crear formularios interactivos en scripts de shell dentro del entorno MRDevs Tools. ## Requisitos Previos - MRDevs Tools instalado (bootstrap.sh ya instala Gum automáticamente) - Conocimientos básicos de shell scripting ## Componentes Básicos de Gum Gum ofrece varios comandos para crear diferentes tipos de elementos de interfaz: | Comando | Descripción | |---------------|--------------------------------------------| | `gum style` | Da formato al texto (color, negrita, etc.) | | `gum input` | Campo de entrada para texto | | `gum write` | Área de texto multilínea | | `gum confirm` | Diálogo de confirmación (Sí/No) | | `gum choose` | Menú de selección de opciones | | `gum filter` | Lista filtrable de opciones | | `gum spin` | Indicador de carga con mensaje | | `gum format` | Formatea texto (Markdown, código, etc.) | | `gum join` | Combina salidas en layouts | | `gum table` | Muestra datos en formato de tabla | | `gum pager` | Visualizador de texto paginado | ### 1. Formulario Básico de Registro Vamos a crear un formulario simple que solicite nombre, correo electrónico y contraseña: ```bash #!/bin/bash # Ejemplo de formulario básico con Gum # Título estilizado echo gum style --foreground 212 --bold --align center "Formulario de Registro" echo # Solicitar información gum style --foreground 99 "Por favor, ingresa tus datos:" echo nombre=$(gum input --placeholder "Tu nombre completo" --prompt "Nombre: " --width 40) email=$(gum input --placeholder "ejemplo@dominio.com" --prompt "Email: " --width 40) password=$(gum input --password --placeholder "Tu contraseña segura" --prompt "Contraseña: " --width 40) # Confirmar datos echo gum style --foreground 99 "Confirma tus datos:" echo "Nombre: $nombre" echo "Email: $email" echo "Contraseña: $(echo $password | sed 's/./*/g')" # Confirmación echo if gum confirm "¿Los datos son correctos?"; then gum style --foreground 82 "✓ Usuario registrado correctamente." else gum style --foreground 196 "✗ Proceso cancelado." fi ``` ![Formulario Básico de Registro](img/gum-registro.png) ### 2. Selector de Proyecto Creemos un selector para elegir el tipo de proyecto a crear: ```bash #!/bin/bash # Selector de tipo de proyecto echo gum style --foreground 212 --bold "Selección de Tipo de Proyecto" echo # Definir opciones TIPOS=("Web Frontend" "API Backend" "Aplicación Móvil" "Biblioteca/SDK" "Base de Datos" "DevOps/Infraestructura") # Usar gum choose para selección tipo_seleccionado=$(gum choose --height 10 --cursor-prefix "[ ] " --selected-prefix "[✓] " "${TIPOS[@]}") # Verificar que se seleccionó un tipo if [ -n "$tipo_seleccionado" ]; then echo gum style --foreground 82 "Has seleccionado: $tipo_seleccionado" # Solicitar nombre del proyecto echo nombre_proyecto=$(gum input --width 40 --placeholder "mi-nuevo-proyecto" --prompt "Nombre del proyecto: ") # Descripción multilínea echo gum style "Escribe una breve descripción del proyecto:" descripcion=$(gum write --placeholder "Describe tu proyecto aquí..." --width 60 --height 5) # Resumen echo gum style --foreground 99 --bold "Resumen del Proyecto:" echo echo "Tipo: $tipo_seleccionado" echo "Nombre: $nombre_proyecto" echo -e "Descripción:\n$descripcion" # Confirmación echo if gum confirm "¿Deseas crear este proyecto?"; then gum spin --spinner dot --title "Creando proyecto..." -- sleep 2 echo gum style --foreground 82 "✓ Proyecto '$nombre_proyecto' creado con éxito." else echo gum style --foreground 196 "✗ Operación cancelada." fi else gum style --foreground 196 "✗ No se seleccionó ningún tipo de proyecto." fi ``` ![Selector de Tipo de Proyecto](img/gum-selector.png) ### 3. Utilidad de Configuración del Sistema Este ejemplo muestra cómo crear una utilidad para configurar aspectos del sistema: ```bash #!/bin/bash # Utilidad de configuración del sistema # Función para mostrar el encabezado show_header() { gum style \ --foreground 212 --border double --border-foreground 99 \ --align center --width 50 --margin "1 0" --padding "1 2" \ "Utilidad de Configuración del Sistema" } # Función para mostrar el menú principal show_menu() { gum style --foreground 99 "Selecciona una opción:" gum choose --height 10 \ "1. Configurar Red" \ "2. Gestionar Usuarios" \ "3. Servicios del Sistema" \ "4. Actualizaciones" \ "5. Salir" } # Simular configuración de red config_network() { gum style --foreground 212 --bold "Configuración de Red" # Elegir tipo de conexión tipo_red=$(gum choose "Ethernet" "WiFi" "VPN" "Volver") if [ "$tipo_red" = "Volver" ]; then return fi gum style "Has seleccionado: $tipo_red" if [ "$tipo_red" = "WiFi" ]; then # Simulando escaneo de redes gum spin --spinner dot --title "Escaneando redes WiFi..." -- sleep 2 # Elegir red WiFi red=$(gum filter --placeholder "Buscar red..." --height 10 <<< "Red_Casa Red_Oficina Red_Invitados Red_Vecino WiFi_5G WiFi_IoT") if [ -n "$red" ]; then password=$(gum input --password --prompt "Contraseña para $red: ") gum spin --spinner dot --title "Conectando a $red..." -- sleep 2 gum style --foreground 82 "✓ Conectado a $red correctamente." fi else gum style --foreground 99 "Esta función está en desarrollo." fi gum input --placeholder "Presiona Enter para continuar..." } # Función principal main() { clear show_header while true; do echo opcion=$(show_menu) case $opcion in "1. Configurar Red") clear show_header config_network clear show_header ;; "5. Salir") clear gum style --foreground 82 "¡Gracias por usar la Utilidad de Configuración!" exit 0 ;; *) clear show_header gum style --foreground 99 "Esta función está en desarrollo." gum input --placeholder "Presiona Enter para continuar..." clear show_header ;; esac done } # Ejecutar la aplicación main ``` ![Utilidad de Configuración del Sistema](img/gum-config.png) ## Técnicas Avanzadas ### Layouts con `gum join` Puedes crear layouts horizontales y verticales con `gum join`: ```bash # Layout horizontal con columnas gum join --horizontal \ "$(gum style --padding "1 2" --border normal --width 20 "Panel 1")" \ "$(gum style --padding "1 2" --border normal --width 20 "Panel 2")" \ "$(gum style --padding "1 2" --border normal --width 20 "Panel 3")" # Layout vertical con filas gum join --vertical \ "$(gum style --padding "1 2" --border normal --width 50 "Fila 1")" \ "$(gum style --padding "1 2" --border normal --width 50 "Fila 2")" \ "$(gum style --padding "1 2" --border normal --width 50 "Fila 3")" ``` ![Layouts con Gum Join](img/gum-layouts.png) ### Tablas de Datos Las tablas son útiles para mostrar datos estructurados: ```bash # Crear una tabla echo -e "NOMBRE\tROL\tDEPARTAMENTO\nJuan Pérez\tDesarrollador\tTecnología\nAna García\tDiseñadora\tMarketing\nCarlos López\tGerente\tAdministración" | \ gum table --widths 20,15,20 --height 10 ``` ![Tablas de Datos](img/gum-table.png) ### Filtrar Listas Largas Para buscar en listas extensas: ```bash # Lista con filtro de búsqueda cat /etc/passwd | gum filter --placeholder "Buscar usuario..." --height 15 ``` ### Personalización con Temas Puedes personalizar colores y estilos con variables de entorno: ```bash # Configurar tema export GUM_INPUT_CURSOR_FOREGROUND="#FF5F87" export GUM_INPUT_PROMPT_FOREGROUND="#5F87FF" export GUM_CONFIRM_SELECTED_BACKGROUND="#5F87FF" export GUM_CONFIRM_UNSELECTED_BACKGROUND="#FF5F87" # Probar con el tema personalizado gum input --prompt "Nombre: " gum confirm "¿Continuar?" ``` ### Ejemplo Práctico: Asistente de Configuración de Proyecto Este ejemplo muestra cómo usar Gum para crear un asistente para inicializar proyectos: ```bash #!/bin/bash # Asistente de configuración de proyecto con Gum SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/lib/base.lib" # Asegurar que existe el directorio para guardar los proyectos PROJECTS_DIR="$HOME/projects" mkdir -p "$PROJECTS_DIR" # Función para el encabezado show_header() { gum style \ --foreground "#00AAFF" --border double --border-foreground "#FF00AA" \ --align center --width 70 --margin "1 0" --padding "1 2" \ "🚀 Asistente de Inicialización de Proyectos 🚀" } # Función para mostrar pasos del proceso show_step() { local step=$1 local total=$2 local title=$3 gum style \ --foreground "#FFAA00" --bold \ "[$step/$total] $title" echo } # Función principal main() { clear show_header # Paso 1: Nombre del proyecto show_step 1 5 "Nombre del Proyecto" project_name=$(gum input --placeholder "mi-nuevo-proyecto" --prompt "Nombre: " --width 50) if [ -z "$project_name" ]; then gum style --foreground "#FF0000" "❌ El nombre del proyecto no puede estar vacío." exit 1 fi project_path="$PROJECTS_DIR/$project_name" if [ -d "$project_path" ]; then overwrite=$(gum confirm "El proyecto ya existe. ¿Deseas sobrescribirlo?") if [ $? -ne 0 ]; then gum style --foreground "#FF0000" "Operación cancelada." exit 0 fi rm -rf "$project_path" fi # Paso 2: Tipo de proyecto clear show_header show_step 2 5 "Tipo de Proyecto" project_type=$(gum choose "web" "api" "cli" "library" "mobile") # Paso 3: Lenguaje de programación clear show_header show_step 3 5 "Lenguaje de Programación" languages=() case $project_type in "web") languages=("JavaScript" "TypeScript" "Python" "PHP" "Ruby") ;; "api") languages=("JavaScript" "TypeScript" "Python" "Go" "Java" "Ruby") ;; "cli") languages=("Python" "Go" "Rust" "C" "C++") ;; "library") languages=("JavaScript" "TypeScript" "Python" "C++" "Java") ;; "mobile") languages=("Kotlin" "Swift" "React Native" "Flutter") ;; esac language=$(gum choose "${languages[@]}") # Paso 4: Descripción clear show_header show_step 4 5 "Descripción del Proyecto" gum style "Escribe una breve descripción del proyecto:" description=$(gum write --placeholder "Describe tu proyecto aquí..." --width 70 --height 5) # Paso 5: Confirmar y crear clear show_header show_step 5 5 "Confirmación" gum style --foreground "#00AAFF" "Resumen del Proyecto:" echo gum style --bold "Nombre: " --no-bold "$project_name" gum style --bold "Tipo: " --no-bold "$project_type" gum style --bold "Lenguaje: " --no-bold "$language" gum style --bold "Ruta: " --no-bold "$project_path" echo gum style --bold "Descripción:" echo "$description" echo create=$(gum confirm "¿Crear este proyecto?") if [ $? -ne 0 ]; then gum style --foreground "#FF0000" "Operación cancelada." exit 0 fi # Crear proyecto gum spin --spinner dot --title "Creando estructura del proyecto..." -- bash -c " mkdir -p \"$project_path\" cd \"$project_path\" echo \"# $project_name\" > README.md echo \"$description\" >> README.md # Crear estructura básica según el tipo de proyecto case $project_type in \"web\") mkdir -p src/assets src/components src/styles touch src/index.js src/styles/main.css ;; \"api\") mkdir -p src/controllers src/models src/routes touch src/app.js src/config.js ;; \"cli\") mkdir -p src/commands src/utils touch src/main.js src/config.js ;; \"library\") mkdir -p src/lib tests examples touch src/index.js ;; \"mobile\") mkdir -p src/screens src/components src/assets touch src/App.js ;; esac # Inicializar Git git init > /dev/null 2>&1 echo 'node_modules\n.DS_Store\n*.log' > .gitignore git add . > /dev/null 2>&1 git commit -m \"Initial commit\" > /dev/null 2>&1 " # Mostrar resumen final clear show_header gum style --foreground "#00FF00" "✅ Proyecto creado exitosamente:" echo gum style --bold "Ubicación: " --no-bold "$project_path" gum style --bold "Estructura:" echo find "$project_path" -type f -o -type d | grep -v ".git" | sort | sed "s|$project_path|└── proyecto|" echo gum style --foreground "#00AAFF" "Siguientes pasos:" echo gum style "1. Navega a tu proyecto: cd $project_path" gum style "2. Inicia el desarrollo con tu IDE favorito" gum style "3. Consulta la documentación en el README.md" } # Ejecutar programa main ``` ## Consejos y Mejores Prácticas 1. **Verificación de instalación**: Siempre verifica que Gum esté instalado antes de usarlo: ```bash command -v gum >/dev/null 2>&1 || { echo "Gum no está instalado"; exit 1; } ``` 2. **Personalización de colores**: Usa variables de entorno para personalizar colores: ```bash export GUM_INPUT_PROMPT_FOREGROUND="#5F87FF" ``` 3. **Reutilización**: Crea funciones para elementos comunes: ```bash show_title() { gum style --foreground 212 --bold --align center "$1" } ``` 4. **Validación de entrada**: Siempre valida las entradas del usuario: ```bash if [[ -z "$input" ]]; then gum style --foreground 196 "Error: Campo requerido" fi ``` 5. **Confirmaciones**: Usa confirmaciones antes de acciones irreversibles: ```bash if gum confirm "¿Estás seguro?"; then # acción peligrosa fi ``` 6. **Spinners para operaciones largas**: Muestra progreso durante operaciones que toman tiempo: ```bash gum spin --spinner dot --title "Procesando..." -- sleep 3 ``` 7. **Anchura consistente**: Mantén una anchura consistente en tus interfaces: ```bash WIDTH=50 gum style --width $WIDTH "Texto 1" gum input --width $WIDTH ``` ## Esquemas de Color y Estilos Gum soporta colores hexadecimales y códigos ANSI: ```bash # Colores hexadecimales gum style --foreground "#FF5F87" "Texto en rosa" # Colores ANSI gum style --foreground 212 "Texto en púrpura" ``` Estilos de texto disponibles: - `--bold`: Texto en negrita - `--italic`: Texto en cursiva - `--strikethrough`: Texto tachado - `--underline`: Texto subrayado Estilos de borde: - `--border normal`: Borde simple - `--border double`: Borde doble - `--border rounded`: Borde redondeado - `--border thick`: Borde grueso ## Conclusión Gum es una herramienta poderosa para elevar la experiencia de usuario en tus scripts de shell. Permite crear interfaces atractivas y funcionales sin salir de la terminal. En MRDevs Tools, Gum está integrado y listo para usarse, lo que te permite crear flujos de trabajo más intuitivos y profesionales. ## Recursos Adicionales - [Documentación oficial de Gum](https://github.com/charmbracelet/gum) - [Charm.sh](https://charm.sh/) - Creadores de Gum y otras herramientas TUI - [Lip Gloss](https://github.com/charmbracelet/lipgloss) - Biblioteca para estilos en Go (base de Gum) - [Bubble Tea](https://github.com/charmbracelet/bubbletea) - Framework TUI en Go (usado por Gum) --- Creado por Cortana Rosero One para MRDevs Tools. Última actualización: 2025/04/04