Después de lo que vimos en el episodio 785, titulado Tu Terminal ahora es mucho mas inteligente (gracias a Fish), nos quedamos con el potencial y las posibilidades que nos ofrecía Fish directamente de caja. Pero como te adelanté ya en ese episodio, esto podía ir a mas, en el sentido de que Fish te da la posibilidad de definir tus propios eventos. Es decir, no solo puede responder a los eventos integrados, sino que además te permite crear y disparar tus propios eventos personalizados. Y esto es precisamente lo que veremos en este episodio. No solo a crear tus propios eventos y como utilizar estos eventos, sino algunos ejemplos prácticos y casos de uso.
Tu terminal REACCIONA a todo. Eventos personalizados en Fish
La gran ventaja que te ofrece crear y utilizar tus propios eventos, es que puedes desacoplar simplificar enormemente tus funciones, y de la misma manera puedes hacer con tu configuración de config.fish.
Cómo funciona: emit y --on-event
Para trabajar con tus propios eventos en fish, necesitas de dos piezas,
- El emisor (
emit), que es el que dispara el evento. - El receptor (
--on-event), es la función que se encarga de escuchar el evento, de forma que cuando se produce realiza alguna tarea.
Ejemplo práctico. Un sistema de notificaciones
Imagina que tienes varios scripts que realizan tareas pesadas (copias de seguridad, compilación de Rust, despliegue de contenedores) y quieres que todos envíen una notificación al terminar, pero sin repetir el código de notificación en cada sitio.
Definir la función receptora
El pimer paso es definir la función que escucha. Esta función vivirá en tu config.fish o en un archivo dentro de ~/.config/fish/conf.d/. Aquí sucedía exactamente igual que en los casos que te comenté en el episodio anterior. Esta función se tiene que cargar al inicio.
function al_finalizar_tarea --on-event tarea_completada
# Recibe argumentos pasados por el emit
set -l nombre_tarea $argv[1]
set -l estado $argv[2]
echo "--- [Notificación del Sistema] ---"
echo "La tarea '$nombre_tarea' finalizó con estado: $estado"
# Envías la notificación al sistema
notify-send "Tarea terminada" "$nombre_tarea: $estado"
end
Disparar el evento desde cualquier sitio
Ahora, en cualquier script o incluso directamente en la terminal, puedes lanzar el evento,
# Simulamos una tarea
echo "Compilando proyecto..."
sleep 2
# Disparamos nuestro evento personalizado con argumentos
emit tarea_completada "Compilación Rust" "Éxito"
Ventajas de usar eventos personalizados
Como ya te puedes imaginar, esto de crear tus propios eventos, tiene muchas y grandes ventajas. Pero, no solo crear eventos, sino tener distintos oyentes para esos eventos. Algunas de las ventajas son las siguientes,
- Desacoplamiento. El script que se está ejecutanto no necesita saber cómo se envía la notificación. Solo dice he terminado. Si mañana decides cambiar
echopor un envío a Telegram, solo cambias la función receptora. - Múltiples receptores. Puedes tener varias funciones escuchando el mismo evento
tarea_completada. Una podría guardar un log en un archivo y otra enviarte un correo, y ambas se ejecutarán automáticamente al hacer elemit. - Limpieza de código. Evitas pasar variables globales de un lado a otro para comunicar estados entre funciones.
Comandos útiles para depurar eventos
Si empiezas a crear muchos eventos, estos comandos te salvarán la vida:
functions. Para ver qué funciones están registradas.functions --handlers. Te muestra específicamente qué funciones están escuchando qué eventos en ese momento.functions --handlers | grep <evento>. Utilizandogrepseguido del nombre del evento puedes ver que funciones escuchan o gestionan ese evento.
# Ejemplo para ver tus manejadores activos
functions --handlers
Un ejemplo mas completo
Se trata de reaccionar a distintos eventos, y según cada evento se realizan unas acciones u otras. Por ejemplo,
El Núcleo: El «Watcher» (Observador)
Esta función monitorea los cambios y simplemente «anuncia» que algo ha pasado.
function watch_rust_project
echo "Monitoreando el proyecto Rust..."
# Usamos fswatch para detectar cambios en la carpeta src/
fswatch -o src/ | while read -l event
echo "¡Cambio detectado! Iniciando compilación..."
emit rust_file_changed
end
end
El Constructor: handle_build
Esta función reacciona al cambio de archivos. Si la compilación tiene éxito, lanza un nuevo evento.
function handle_build --on-event rust_file_changed
if cargo build --release
set -l bin_path "./target/release/mi_mcp_skill"
emit build_success $bin_path
else
emit build_failure $status
end
end
El Desplegador: update_container
A esta función solo le importa cuando hay un binario nuevo listo. Aquí es donde entra Podman.
function update_container --on-event build_success
set -l bin_path $argv[1]
echo "Actualizando contenedor Podman con $bin_path..."
# Comandos de Podman para copiar el binario y reiniciar
podman cp $bin_path mcp_container:/usr/local/bin/
podman restart mcp_container
emit deployment_complete "Producción"
end
El Notificador: log_deployment
Un tercer receptor que escucha el evento final para llevar un registro.
function log_deployment --on-event deployment_complete
set -l entorno $argv[1]
echo "[$(date)] Despliegue exitoso en $entorno" >> ~/dev_history.log
end
Conclusión
Realmente tienes una opción muy potente para simplificar tus scripts y para llevarlos a un plano superior. Puedes encadenar acciones o incluso realizarlas en paralelo. Lo cierto es que esto abre todo un mundo de opciones y posibilidades, dejando el código sencillo y utilizando y exprimiendo al máximo las posibilidades que te ofrece Fish.