ahmetb / kubectx

Faster way to switch between clusters and namespaces in kubectl
https://kubectx.dev
Apache License 2.0
17.71k stars 1.26k forks source link

_arguments:comparguments:325: can only be called from completion function #285

Open martinmaehlmann opened 3 years ago

martinmaehlmann commented 3 years ago

The zsh completion scripts make zsh throw an error.

_arguments:comparguments:325: can only be called from completion function

This is due to the fact, that both zsh completion scripts call _arguments outside a function.

Fix

Put the completion scripts into a function, as shown below:

kubectx.zsh

 #compdef kubectx kctx=kubectx

__kubectx() {
  local KUBECTX="${HOME}/.kube/kubectx"
  PREV=""

  local all_contexts="$(kubectl config get-contexts --output='name')"
  if [ -f "$KUBECTX" ]; then
      # show '-' only if there's a saved previous context
      local PREV=$(cat "${KUBECTX}")

      _arguments \
        "-d:*: :(${all_contexts})" \
        "(- *): :(- ${all_contexts})"
  else
      _arguments \
        "-d:*: :(${all_contexts})" \
        "(- *): :(${all_contexts})"
  fi
}

kubens.zsh

#compdef kubens kns=kubens

__kubens() {
  _arguments "1: :(- $(kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}'))"
}
ahmetb commented 3 years ago

It doesn't a throw an error for me on my oh-my-zsh setup with zsh 5.8 (x86_64-apple-darwin20.0). Can we first try to figure out what causes the error?

martinmaehlmann commented 3 years ago

The error is thrown, when the autocompletions are loaded, e.g. when I start a new instance of my zsh (zsh 5.7.1 (x86_64-apple-darwin19.0)). Despite the error thrown, the completion itself does work.

The error thrown due to the fact that the _arguments are called outside a function. This is why I wrapped the completion scripts with an the functions __kubens() and __kubectx() silencing the error.

thatmarkenglishguy commented 2 years ago

I was seeing this issue until I realised that rather than sourcing the completions they needed to be put into a directory on zsh's fpath E.g. something like (untested)

# Create a folder ~/.zsh to put files zsh will load
mkdir "${HOME}/.zsh"
flamegraph --completions zsh > "${HOME}/.zsh/.flamegraph-completion.zsh"

# Add .zsh to your fpath when the zsh shell starts
echo 'fpath+=~/.zsh' >>"${HOME}/.zshrc"
AlmogBaku commented 1 year ago

hey @martinmaehlmann @ahmetb @thatmarkenglishguy did you find a solution?

--

About my environment

MacOS Ventura 13.0.1 zsh 5.8.1 (x86_64-apple-darwin22.0) Antibody version dev (built from master)

In the antibody-plugins I loaded kubectx before I loaded ohmyzsh using ahmetb/kubectx path:completion kind:fpath

AlmogBaku commented 1 year ago

ok, I found a solution!

  1. Load the kubectx completion before ohmyzsh (as stated in the docs) (or put autoload -U compinit && compinit after loading these completions)
  2. ignore the error log by changing the _arguments \ statement to _arguments >/dev/null 2>&1 \

sending a pr

Dadaji18 commented 1 year ago

I found this script somwhere and it helped, just copy and paste it into the zsh terminal and the commands will run just fine.

cd ~
mkdir ~/.zsh
swift package completion-tool generate-zsh-script > ~/.zsh/_swift
echo -e "fpath=(~/.zsh \$fpath)\n" >> ~/.zshrc
echo -e "autoload -Uz compinit && compinit" >> ~/.zshrc