GNU/Linux >> Tutoriales Linux >  >> Linux

¿Autocompletar Zsh dinámico para comandos personalizados?

Estoy tratando de escribir funciones de finalización para algunas funciones personalizadas que escribí, pero parece que tengo problemas incluso con las más básicas.

Una función de ejemplo es:

function eb_instances() {
    if [ "$#" -ne 2 ]; then
        echo "Usage eb_instances <aws profile name> <environment name>"
        echo "e.g.:"
        echo " eb_instances production kraken-prod-api"
        return 1
    fi

    aws ec2 describe-instances --filters  "Name=instance-state-name,Values=running"   "Name=tag:Name,Values=$2" --profile=$1 --output=json | jq -r ".Reservations[].Instances[].PrivateIpAddress"
}

Esto tiene dos argumentos posicionales, <aws profile name> y <environment name>

Quiero las opciones de finalización para <aws profile name> para estar disponible dinámicamente ejecutando
sed -n -E 's/[([a-zA-Z0-9_-]+)]/1/p' ~/.aws/credentials | tr \n ' ' y las terminaciones para <environment name> para estar disponible dinámicamente al ejecutar otra función que he llamado eb_names .

Estoy encontrando la documentación bastante escasa y difícil de seguir. También he visto el repositorio zsh-completions para comandos similares, pero parece que no puedo encontrar algo similar a lo que necesito.

¡Cualquier ayuda para empezar sería muy apreciada!

Actualizar

Basado en la respuesta de @cuonglm, usé:

#compdef ebinstances

_ebinstances() {
  local state

  _arguments 
    '1: :->aws_profile'
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:($(sed -n -E "s/[([a-zA-Z0-9_-]+)]/1/p" ~/.aws/credentials | tr \n " "))' ;;
              (*) compadd "[email protected]" foo bar
  esac
}

_ebinstances "[email protected]"

Lo que olvidé mencionar en la pregunta original fue que también quería que la finalización del segundo argumento dependiera del primero (ambos se basan dinámicamente en la ejecución de algún código), por ejemplo:

$ eb_instances <cursor>TAB
cuonglm  test

obtiene las terminaciones que quiero. Una vez que seleccione, diga el primero e intente completar automáticamente:

$ eb_instances cuonglm <cursor>TAB

Quiero generar las opciones de finalización ejecutando eb_names cuonglm y, si es posible, también, profundizar en las finalizaciones, por ejemplo, si el candidato correcto era foo-bar ,

$ eb_instances cuonglm foo<cursor>TAB

Quiero generar las opciones de finalización ejecutando eb_names cuonglm foo

Respuesta aceptada:

Al principio, el sistema de finalización zsh parece ser muy complejo y difícil de entender. Vamos a probar un ejemplo.

Lo primero que debes saber, zsh el sistema de finalización cargará las funciones de finalización desde $fpath . Asegúrese de que su directorio de finalizaciones aparezca en:

print -rl -- $fpath

(Si usó oh-my-zsh, hay .oh-my-zsh/completions existía en $fpath , puede simplemente crearlo y poner sus funciones de finalización allí)

Ahora, debe crear un archivo de finalización para su función, su nombre debe comenzar con un guión bajo _ , más el nombre de su función. En tu caso, su nombre es _eb_instances .

Agregue estas líneas a _eb_instances archivo:

#compdef eb_instances

_eb_instances() {
  local state

  _arguments 
    '1: :->aws_profile'
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
              (*) compadd "[email protected]" prod staging dev
  esac
}

_eb_instances "[email protected]"

Estás listo. Guarde el archivo e inicie una nueva sesión para probar la finalización. Verá algo como esto:

$ eb_instances <cursor>TAB
cuonglm  test

$ eb_instances cuonglm <cursor>TAB
dev      prod     staging

Puede leer la documentación del sistema de finalización zsh sobre _arguments función, state variable. También debe cambiar (cuonglm test) con tu sed comando y cambio prod staging dev a sus eb_names función.

Relacionado:Linux:¿cómo obtener de manera confiable el nombre del sistema operativo?

Si desea generar el segundo argumento basado en el primer argumento pasado, puede usar $words[2] variables:

case $state in
  (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
            (*) compadd "[email protected]" $(echo $words[2]) ;;
esac

Reemplazar echo con su función real, en su caso, es $(eb_names $words[2]) .

Si todavía te cuesta lograr esto, simplemente define _eb_instances y eb_instances en su .zshrc luego llame a la finalización como:

compdef _eb_instances eb_instances

Debe inicializar el sistema de finalización con:

autoload -U compinit
compinit

(Si usaste oh-my-zsh , ha sido cargado)


Linux
  1. Hoja de referencia de comandos de Linux

  2. Nombre del lanzamiento de Fedora 11 – Vota por él

  3. ¿Cómo asignar nombre a una pantalla?

  4. Cómo establecer la ruta para los comandos sudo

  5. Pestaña Autocompletar para nuevo usuario

Comandos de FreeDOS para fanáticos de Linux

Cómo usar comandos personalizados en LibreOffice

Más de 20 comandos FFmpeg para principiantes

40 comandos importantes de Docker para desarrolladores de software

50 comandos esenciales de Nmap para administradores de sistemas

Comandos para la Gestión de Procesos en Linux