ZSH Autocomplete For Custom Script
Asked Answered
S

1

9

I've been searching online for a lot of hours, puling an all nighter because i got so lost down this rabbit hole :D but i'm having trouble finding examples with working code.

I have a bash script that is called upon like the following examples:

foo-tools.sh switch <version number>
foo-tools.sh start 
foo-tools.sh open-ports on 
foo-tools.sh kube get logs 
foo-tools.sh kube edit ing default-ingress -oyaml

I use zsh with oh-my-zsh as my shell.

I want to be able to type "foo-tools.sh " to list all availabe options and i want to be able to autocomplete an option with "foo-tools.sh k" meaning it should either list all availabe options starting with "foo-tools.sh k*" or if there is only one option autcomplete the command.

I found this code on some stackoverflow thread, it's the closes I've gotten to having it work fully:

#compdef foo-tools.sh

_foo_tools_sh() {
    typeset -A opt_args
    local alternatives

    alternatives=(
        'args:rv options:_foo_tools_sh_options'
    )

    _alternative $alternatives && return 0

    return 1
}

_foo_tools_sh_options() {
    local -a arguments=(
        'start:Start VP'
        'stop:Stop VP]'
        'kube:Kube CMD'
        'kube logs:Kube logs'
        'info:Display info'
        'get:Get CMD'
        )

    _sequence _describe 'cmds' arguments

    return 1
}

# invoke the completion command during autoload
_foo_tools_sh "$@"

This works some what. When i type "foo-tools.sh " it shows me the options i configured: all options displayed when TAB

But when i autocomplete one of the options with tab it adds a , after the command: , added when TAB cmd

And the option with a space between the words, "kube logs" gets the space escaped when tabbed out:space escpaded + added ,

I also found these two commands, they goes in my .zshrc. The expansion is wierd, it ignores the commands that has spaces in them and it doesnt understand that the commands are nested. I.e if typing foo-tools.sh open-ports it displays all the options, not just off/on.

local -a _foo_tools_sh=(
    "start"
    "stop"
    "switch"
    "install"
    "kube"
    "kube get"
    "kube edit"
    "open-ports on"
    "open-ports off"
)
complete -W "${_foo_tools_sh}" 'foo-tools.sh'

yet the Options not nestled: Options not nestled

I would very much appreciate any help or insights in how to improve the script i have (or throw it out and replace it with something proper).

Sequacious answered 23/4, 2022 at 8:12 Comment(0)
A
1

Better late then never.

Following a few of the examples found here: https://github.com/zsh-users/zsh-completions/blob/master/src/, I managed to cobble together a completion script that behaves as expected.

#compdef foo-tools
_foo_tools() {
  local curcontext="$curcontext" state line
  _arguments -C ":command:->command" "*::options:->options"
  case $state in
    (command)
      local -a subcommands=(
        "start:Start VP"
        "stop:Stop VP"
        "kube:Kube logs|CMD"
        "info:Display info"
        "open-port:dis-/enable open-port"
        "get:Get CMD"
       )
       _describe -t commands 'commands' subcommands
       ;;
    (options)
      [ $#line -gt 2 ] && return 0 # don't complete multiple options
      case $line[1] in
        (kube)
          local -a ku=(
            "logs:Show the logs"
            "CMD:whatever"
          )
          _describe -O 'kube options' ku
          ;;
        (open-port)
          local -a op=(
            "on:Turn open-ports on"
            "off:Turn open-ports off"
          )
          _describe -O 'open-port options' op
      esac
  esac
}
Affectional answered 31/1 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.