12 puntos por GN⁺ 2025-08-13 | Aún no hay comentarios. | Compartir por WhatsApp
  • Introducción a cómo implementar una función de autocompletación con tabulador en Bash y Zsh que muestra descripciones incluso para palabras ya completadas
  • Bash y Zsh usan APIs de autocompletación distintas, y solo Zsh ofrece por defecto la función de mostrar descripciones en la autocompletación
  • Se implementa una estructura que genera candidatos con _generate_foo_completions y los devuelve con COMPREPLY en Bash y compadd en Zsh
  • Para implementar en Bash la función de descripciones de Zsh, se incluyen las descripciones en las cadenas candidatas y solo se eliminan cuando hay un único candidato
  • Incluso cuando hay un solo candidato, se mejora el comportamiento agregando ambigüedad intencionalmente para que al presionar <TAB> se muestre la descripción
  • El script final ofrece la misma experiencia de usuario en ambos shells y soporta completado parcial, completado total y visualización de descripciones de candidatos

Contexto del problema

  • La autocompletación con tabulador (tab-completion) es útil para explorar comandos o flags, y ayuda especialmente cuando se usa por primera vez una API o una herramienta CLI
  • Zsh por defecto solo muestra descripciones cuando hay varios candidatos, y Bash solo puede hacerlo mediante configuración adicional
  • Sin embargo, para una palabra ya completada, ninguno de los dos shells muestra descripciones
  • Por eso, para ver una descripción, el usuario debe pasar por un proceso incómodo como este
    • borrar algunos caracteres para que coincidan varios candidatos
    • presionar la tecla <TAB> para revisar la lista de candidatos
    • buscar visualmente la descripción deseada
    • volver a escribir los caracteres eliminados para ejecutar el comando

Resumen de la solución

  • Incluso cuando hay un solo candidato, se agrega un candidato ficticio (dummy completion) para volver ambigua la lista
  • De este modo, tanto Bash como Zsh muestran la lista de candidatos junto con sus descripciones
  • Eso sí, hay que evitar que el texto de la descripción se inserte en el comando real

Conceptos básicos

  • La autocompletación con tabulador funciona recibiendo la palabra actual y la posición del cursor al presionar <TAB>, y devolviendo una lista de candidatos posibles
  • Bash: asigna los candidatos al arreglo COMPREPLY
  • Zsh: registra los candidatos con el comando compadd
  • La función _generate_foo_completions imprime cadenas candidatas, y en un caso real puede generarlas dinámicamente según el estado del CLI

Soporte simultáneo para Bash y Zsh

  • Se implementa para cada shell con las funciones _complete_foo_bash y _complete_foo_zsh
  • Se distingue con if [ -n "${ZSH_VERSION:-}" ]; then ... elif [ -n "${BASH_VERSION:-}" ]; then ... fi
  • El usuario aplica el script registrándolo en .bashrc o .zshrc

Mostrar descripciones en Zsh

  • Se usa el formato nombre: descripción en las cadenas candidatas
  • Zsh: compadd -d raw -- $trimmed para pasar nombre y descripción como arreglos paralelos
  • Bash: solo se pasan a COMPREPLY los candidatos sin la parte de la descripción (por defecto no soporta descripciones)

Implementar descripciones en Bash

  • Cuando hay varios candidatos, se muestran tal cual las cadenas que incluyen la descripción
  • Cuando hay un solo candidato, solo entonces se elimina la descripción
  • Se aprovecha el comportamiento de autocompletación de Bash, que inserta solo el prefijo común, para evitar que la descripción forme parte de la entrada real

Mostrar descripciones incluso con un solo candidato

  • Para mostrar la descripción incluso al presionar <TAB> sobre una palabra ya completada, se agrega un candidato ficticio que introduce ambigüedad
  • Zsh: se agrega el candidato ficticio tanto a los dos arreglos paralelos (raw, trimmed)
  • Bash: cuando hay un solo candidato, se agrega solo el nombre a trimmed

Resultado final

  • Con varios candidatos, se muestran tanto el nombre como la descripción
  • Incluso con un solo candidato, la descripción puede verse con <TAB>
  • Bash y Zsh ofrecen la misma experiencia
  • Ejemplo de uso:
    $ foo <TAB>  
    apple: a common fruit banana: starchy and high in potassium  
    apricot: sour fruit... cherry: small and sweet...  
    

Aún no hay comentarios.

Aún no hay comentarios.