Tu terminal REACCIONA a todo. Eventos personalizados en Fish Vistas: 31

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.

0:00 / 0:00

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 echo por 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 el emit.
  • 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>. Utilizando grep seguido 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.

Deja una respuesta