NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.05k stars 14.04k forks source link

`zsh` autocompletion for `awscli2` is unable to be autoloaded #275770

Open abennett opened 10 months ago

abennett commented 10 months ago

Describe the bug

The postInstall step of awscli2 is generating an autocompletion file incompatible with zsh compdef. The file it's currently generating is a file that needs to be sourced, not a #compdef file that will be autoloaded by zsh.

https://github.com/NixOS/nixpkgs/blob/057f9aecfb71c4437d2b27d3323df7f93c010b7e/pkgs/tools/admin/awscli2/default.nix#L97-L99

Steps To Reproduce

Steps to reproduce the behavior:

  1. Enable zsh autocompletion
  2. Install awscli2
  3. Attempt to tab complete the command

Expected behavior

Tab completions works as expected for the various aws subcommands and options.

Additional context

I appreciate your work!

Here's what the _aws autocompletion file looks like. Even looking at the aws docs for autocompletion, it looks like they are also expecting a sourcing of the file. I'm not familiar with the zsh autocompletion system enough to propose a solution offhand.

# Source this file to activate auto completion for zsh using the bash
# compatibility helper.  Make sure to run `compinit` before, which should be
# given usually.
#
# % source /path/to/zsh_complete.sh
#
# Typically that would be called somewhere in your .zshrc.
#
# Note, the overwrite of _bash_complete() is to export COMP_LINE and COMP_POINT
# That is only required for zsh <= edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570
#
# https://github.com/zsh-users/zsh/commit/edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570
#
# zsh releases prior to that version do not export the required env variables!

autoload -Uz bashcompinit
bashcompinit -i

_bash_complete() {
  local ret=1
  local -a suf matches
  local -x COMP_POINT COMP_CWORD
  local -a COMP_WORDS COMPREPLY BASH_VERSINFO
  local -x COMP_LINE="$words"
  local -A savejobstates savejobtexts

  (( COMP_POINT = 1 + ${#${(j. .)words[1,CURRENT]}} + $#QIPREFIX + $#IPREFIX + $#PREFIX ))
  (( COMP_CWORD = CURRENT - 1))
  COMP_WORDS=( $words )
  BASH_VERSINFO=( 2 05b 0 1 release )

  savejobstates=( ${(kv)jobstates} )
  savejobtexts=( ${(kv)jobtexts} )

  [[ ${argv[${argv[(I)nospace]:-0}-1]} = -o ]] && suf=( -S '' )

  matches=( ${(f)"$(compgen $@ -- ${words[CURRENT]})"} )

  if [[ -n $matches ]]; then
    if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then
      compset -P '*/' && matches=( ${matches##*/} )
      compset -S '/*' && matches=( ${matches%%/*} )
      compadd -Q -f "${suf[@]}" -a matches && ret=0
    else
      compadd -Q "${suf[@]}" -a matches && ret=0
    fi
  fi

  if (( ret )); then
    if [[ ${argv[${argv[(I)default]:-0}-1]} = -o ]]; then
      _default "${suf[@]}" && ret=0
    elif [[ ${argv[${argv[(I)dirnames]:-0}-1]} = -o ]]; then
      _directories "${suf[@]}" && ret=0
    fi
  fi

  return ret
}

complete -C aws_completer aws

Notify maintainers

@bhipple @davegallant @bryanasdev000 @devusb @anthonyroussel

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

aaron@nixos:~/ > nix-info -m
 - system: `"x86_64-linux"`
 - host os: `Linux 6.1.68, NixOS, 23.11 (Tapir), 23.11.2082.d02ffbbe834b`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.1`
 - channels(root): `"nixos-23.11"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Add a :+1: reaction to issues you find important.

seh commented 8 months ago

For now I add the following workaround to my ~/.zshrc file:

if command -v aws > /dev/null 2>&1; then
  for p in ${(ps. .)NIX_PROFILES}; do
    f="${p}/share/zsh/site-functions/_aws"
    if [ -r "${f}" ]; then
      source "${f}"
      break
    fi
  done
fi

I agree that this should not be necessary, though.

seh commented 8 months ago

I did notice that this _aws_zshcompleter.zsh file has been in use since at least #91655 almost four years ago. Whether the content of that file changed such that it is no longer amenable to autoloading is harder to say.

Assuming that the upstream file comes from aws/aws-cli, the file's content hasn't changed for almost two years.