1

I have some custom completion I've been working on and am stuck. It extends existing completion scripts with some custom options. The full file can be found here https://github.com/rothgar/k/blob/zsh-completion/completions/zsh/k

I have a custom function called __k_handle_kspace which looks at the current word and does a basic case statement and calls another function. (pasting code without comments and extra options here)

__k_handle_kspace() {
    cur="${words[$CURRENT]}"

    case $cur in
    +* )
        __k_kspace_parse_config_contexts
        ;;
    @* )
        __k_kspace_parse_config_clusters
esac

When I set compdef __k_handle_kspace k this works great and all tab completion is exactly what I want. The full __k_kspace_parse_config_* function can be found here

The completion by default uses __start_k which calls __k_handle_word which then calls my __k_handle_kspace function.

When I set compdef __start_k k I can see my functions being called (using set -x for debugging) and compadd being the last thing called but no tab completion is shown.

When I use the default completion I also have to change the cur variable to cur="${words[$(($CURRENT -1))]}" in my __k_handle_kspace function.

I cant figure out if there's a variable I need to set/return from my function or rules around when compadd can be called to return completion values.


Justin Garrison
  • 338
  • 5
  • 13
  • Can you add the last lines of output from `set -x`, so we can see what's happening? That would help. – Marlon Richert Oct 21 '20 at 20:50
  • I found out from the zsh-workers mailing list that the reason it was happening was from a default completion that tries to complete files after my custom completion ran. I used https://github.com/zsh-users/zsh/blob/master/Completion/Base/Widget/_complete_debug and saw it would run _bash_complete which looked for files that started with `@` `:` or `+`. I haven't figure out how to stop _bash_complete from running yet (maybe zstyle) but hope to start looking at it again soon. – Justin Garrison Oct 23 '20 at 20:41
  • You wrote "no tab completion is shown". How can no tab completion be shown because a default completion is run? That doesn't make any sense. Can you share a bit more of the conversation on the mailing list? – Marlon Richert Oct 24 '20 at 17:20
  • Also, there is no completer called `_bash_complete`. I presume you mean [`_bash_completions`](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-_005fbash_005fcompletions)? That's actually a top-level widget function. You are reading the output of [`^Xh`](index-_005fcomplete_005fhelp-_0028_005eXh_0029) the wrong way around. `_bash_completions` is apparently the widget function you've bound to your tab key. – Marlon Richert Oct 24 '20 at 17:26
  • Anyway, again, it would be helpful if you could actually show the output of `set -x` or `^Xh`. It would make it a lot easier to help you if you did. – Marlon Richert Oct 24 '20 at 17:26
  • Thanks for offering to help. Using _complete_debug widget here's the full output of `k @` https://gist.github.com/rothgar/249cc731eafc3a58b6dd24eaeb517bf3 You'll see at line 355 `compadd` adds the clusters to completion I would expect but then line 384 the zstyle tries to complete files that start with `@` and line 2173 says no matches found. If I put a file called `@foo` in the directory it'll match that file – Justin Garrison Oct 26 '20 at 16:58
  • I think I need to modify the zstyle of the command to ignore files when using `:`, `+`, or `@` but I haven't figure out how to do that yet. Otherwise the completion looks like it works as intended. – Justin Garrison Oct 26 '20 at 16:59
  • Ah, now I found where `_bash_complete` comes from: You're using `bashcompinit`. But if you're writing completion function for Zsh natively, then why are you using `_bash_complete`? You write that you've used `compdef __k_handle_kspace k`, but it looks like you've actually used `bashcompinit`'s `complete` function instead. – Marlon Richert Oct 27 '20 at 09:02
  • The output from `kubctl autocomelpte zsh` enables bashcompinit because it is required for many of the functions. I've extended the default output to handle my specific arguments. I believe this behavior comes from cobra (the go cli framework). https://github.com/rothgar/k/blob/zsh-completion/completions/zsh/k#L212 I'm not sure if there's a way for me to disable bashcompinit for specific functions so they don't use `_bash_complete` or if I would have to change the behavior of kubectl's completion function. I thought `zstyle` might be able to do that but maybe I'm probably wrong – Justin Garrison Oct 27 '20 at 19:31

1 Answers1

0

The completion code you're extending is based on bashcompinit. As a result of this, you need to write your code as a Bash completion function. This means you should add your completion matches to the array COMPREPLY. Because that array is empty when your function returns, _bash_complete reports to Zsh's _main_complete that it has failed.

So, in short: Add your completion matches to COMPREPLY, instead of using compadd, and that should fix it.

Marlon Richert
  • 5,250
  • 1
  • 18
  • 27