|
| 1 | +"""Shell completion support for the OpenAI CLI.""" |
| 2 | + |
| 3 | +from __future__ import annotations |
| 4 | + |
| 5 | +import argparse |
| 6 | + |
| 7 | + |
| 8 | +BASH_COMPLETION = ''' |
| 9 | +_openai_completion() { |
| 10 | + local cur prev words cword |
| 11 | + _init_completion || return |
| 12 | +
|
| 13 | + local commands="api tools completion" |
| 14 | + local global_opts="-v --verbose -b --api-base -k --api-key -p --proxy -o --organization -t --api-type --api-version --azure-endpoint --azure-ad-token -V --version -h --help" |
| 15 | +
|
| 16 | + case "${prev}" in |
| 17 | + openai) |
| 18 | + COMPREPLY=($(compgen -W "${commands} ${global_opts}" -- "${cur}")) |
| 19 | + return |
| 20 | + ;; |
| 21 | + completion) |
| 22 | + COMPREPLY=($(compgen -W "bash zsh fish pwsh" -- "${cur}")) |
| 23 | + return |
| 24 | + ;; |
| 25 | + -t|--api-type) |
| 26 | + COMPREPLY=($(compgen -W "openai azure" -- "${cur}")) |
| 27 | + return |
| 28 | + ;; |
| 29 | + esac |
| 30 | +
|
| 31 | + if [[ "${cur}" == -* ]]; then |
| 32 | + COMPREPLY=($(compgen -W "${global_opts}" -- "${cur}")) |
| 33 | + else |
| 34 | + COMPREPLY=($(compgen -W "${commands}" -- "${cur}")) |
| 35 | + fi |
| 36 | +} |
| 37 | +
|
| 38 | +complete -F _openai_completion openai |
| 39 | +''' |
| 40 | + |
| 41 | +ZSH_COMPLETION = ''' |
| 42 | +#compdef openai |
| 43 | +
|
| 44 | +_openai() { |
| 45 | + local -a commands global_opts shells |
| 46 | +
|
| 47 | + commands=( |
| 48 | + 'api:Direct API calls' |
| 49 | + 'tools:Client side tools for convenience' |
| 50 | + 'completion:Generate shell completion scripts' |
| 51 | + ) |
| 52 | +
|
| 53 | + shells=( |
| 54 | + 'bash:Generate bash completion script' |
| 55 | + 'zsh:Generate zsh completion script' |
| 56 | + 'fish:Generate fish completion script' |
| 57 | + 'pwsh:Generate PowerShell completion script' |
| 58 | + ) |
| 59 | +
|
| 60 | + _arguments -C \ |
| 61 | + '-v[Set verbosity]' \ |
| 62 | + '--verbose[Set verbosity]' \ |
| 63 | + '-b[API base URL]:url:' \ |
| 64 | + '--api-base[API base URL]:url:' \ |
| 65 | + '-k[API key]:key:' \ |
| 66 | + '--api-key[API key]:key:' \ |
| 67 | + '-t[API type]:type:(openai azure)' \ |
| 68 | + '--api-type[API type]:type:(openai azure)' \ |
| 69 | + '-V[Show version]' \ |
| 70 | + '--version[Show version]' \ |
| 71 | + '1:command:->command' \ |
| 72 | + '*::arg:->args' |
| 73 | +
|
| 74 | + case "$state" in |
| 75 | + command) |
| 76 | + _describe -t commands 'openai commands' commands |
| 77 | + ;; |
| 78 | + args) |
| 79 | + case "$words[1]" in |
| 80 | + completion) |
| 81 | + _describe -t shells 'shells' shells |
| 82 | + ;; |
| 83 | + esac |
| 84 | + ;; |
| 85 | + esac |
| 86 | +} |
| 87 | +
|
| 88 | +_openai "$@" |
| 89 | +''' |
| 90 | + |
| 91 | +FISH_COMPLETION = ''' |
| 92 | +# Fish completion for openai CLI |
| 93 | +complete -c openai -f |
| 94 | +complete -c openai -s v -l verbose -d "Set verbosity" |
| 95 | +complete -c openai -s b -l api-base -d "API base URL" -r |
| 96 | +complete -c openai -s k -l api-key -d "API key" -r |
| 97 | +complete -c openai -s t -l api-type -d "API type" -r -a "openai azure" |
| 98 | +complete -c openai -s V -l version -d "Show version" |
| 99 | +complete -c openai -n "__fish_use_subcommand" -a api -d "Direct API calls" |
| 100 | +complete -c openai -n "__fish_use_subcommand" -a tools -d "Client side tools" |
| 101 | +complete -c openai -n "__fish_use_subcommand" -a completion -d "Generate shell completion" |
| 102 | +complete -c openai -n "__fish_seen_subcommand_from completion" -a "bash zsh fish pwsh" |
| 103 | +''' |
| 104 | + |
| 105 | +POWERSHELL_COMPLETION = ''' |
| 106 | +Register-ArgumentCompleter -Native -CommandName openai -ScriptBlock { |
| 107 | + param($wordToComplete, $commandAst, $cursorPosition) |
| 108 | + $commands = @('api', 'tools', 'completion') |
| 109 | + $shells = @('bash', 'zsh', 'fish', 'pwsh') |
| 110 | + $cmds = $commandAst.CommandElements |
| 111 | + if ($cmds.Count -eq 1) { |
| 112 | + $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { |
| 113 | + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) |
| 114 | + } |
| 115 | + } elseif ($cmds.Count -ge 2 -and $cmds[1].ToString() -eq 'completion') { |
| 116 | + $shells | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { |
| 117 | + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) |
| 118 | + } |
| 119 | + } |
| 120 | +} |
| 121 | +''' |
| 122 | + |
| 123 | + |
| 124 | +def _get_completion_script(shell: str) -> str: |
| 125 | + scripts = { |
| 126 | + "bash": BASH_COMPLETION, |
| 127 | + "zsh": ZSH_COMPLETION, |
| 128 | + "fish": FISH_COMPLETION, |
| 129 | + "pwsh": POWERSHELL_COMPLETION, |
| 130 | + "powershell": POWERSHELL_COMPLETION, |
| 131 | + } |
| 132 | + script = scripts.get(shell.lower()) |
| 133 | + if script is None: |
| 134 | + raise ValueError(f"Unsupported shell: {shell}. Supported: bash, zsh, fish, pwsh") |
| 135 | + return script.strip() |
| 136 | + |
| 137 | + |
| 138 | +def register_completion_commands(parser: argparse.ArgumentParser) -> None: |
| 139 | + subparsers = parser.add_subparsers() |
| 140 | + for shell in ["bash", "zsh", "fish", "pwsh"]: |
| 141 | + shell_parser = subparsers.add_parser(shell, help=f"Generate {shell} completion script") |
| 142 | + shell_parser.set_defaults(func=lambda s=shell: print(_get_completion_script(s))) |
0 commit comments