Cómo proporcionar sugerencias de autocompletar que no coinciden con el prefijo en la finalización de zsh

Cómo proporcionar sugerencias de autocompletar que no coinciden con el prefijo en la finalización de zsh

Tengo una función de finalización automática de zsh para un comando llamado gdque realiza una búsqueda difusa basada en el $words[CURRENT]valor y las sugerencias de devolución. La búsqueda funciona bien pero zsh no muestra ningún candidato porque el texto ingresado no es un prefijo de la sugerencia.

p.ej

% gd hw

Podría generar la finalizaciónoh hello there, world

Pero zsh no lo mostrará porque hwno se encuentra al comienzo de la sugerencia.

¿Puedo hacer que zsh ofrezca la sugerencia como algo que reemplazaría la palabra actual cuando se elija?

Aquí hay una versión simplificada de mi secuencia de comandos de finalización en un archivo llamado _gdque está en mi fpath:

#compdef gd

_gd() {
  local -a list

  clue="$words[CURRENT]"

      pattern=""
      for i in $(seq $#clue)
      do
        pattern="$pattern.*${clue[i]}"
      done
      while read dir
      do
        list=( $list $dir )
      done <<<$(grep "$pattern" ~/.recent-dirs)

  _describe gd list
}

Respuesta1

Deshágase de esa _gdfunción y simplemente agregue lo siguiente a su .zshrcarchivo:

autoload -Uz compinit
compinit
zstyle ':completion:*' matcher-list 'r:|?=**'

Esto le indica al código de finalización que permita cualquier número adicional entre y alrededor de lo que ha escrito. Con esto, Zsh ahora puede completar de forma difusacualquier cosa.

  • r:X|Y=Zbusca todas las subcadenas no superpuestas que coincidan con el patrón XYy las convierte en la parte que coincide conX tambiéncoincide con cualquier cosa que coincida por patrón Zal verificar si hay terminaciones coincidentes.
  • ?coincide con cualquier carácter.
  • Si Xo Yes igual a *, coincide con cualquier número de caracteres consecutivos.
  • Si Zes igual *, coincide con cualquier número de caracteres consecutivos.exceptocualquier cosa que coincida con Y.
  • Si Zes igual **, coincide con cualquier número de caracteres consecutivos.
  • En r:|?=**, Xes igual a la cadena vacía.
  • De forma predeterminada, Zsh ya agrega un comodín al final de su entrada, completando así el círculo para una coincidencia aproximada completa.

Puedes encontrar la documentación aquí:http://zsh.sourceforge.net/Doc/Release/Completion-Widgets.html#Completion-Matching-Control

Respuesta2

Esto es un truco mientras espero respuestas más sabias...

Lo que hice fue hacer que mi generador de sugerencias produjera sugerencias como:

hw»oh hello there, world

Debido a que el comando (en realidad una función) está bajo mi control, simplemente elimino la basura al principio:

input="${input#*»}"

Pero sería bueno saber cómo hacerlo correctamente.

información relacionada