We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Autocomplete support for zsh
Bash autocompletion works well, but I would really like zsh to work as well


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `click/_bashcomplete.py`
Content:
```
1 import collections
2 import copy
3 import os
4 import re
5 
6 from .utils import echo
7 from .parser import split_arg_string
8 from .core import MultiCommand, Option, Argument
9 from .types import Choice
10 
11 WORDBREAK = '='
12 
13 COMPLETION_SCRIPT = '''
14 %(complete_func)s() {
15     local IFS=$'\n'
16     COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\
17                    COMP_CWORD=$COMP_CWORD \\
18                    %(autocomplete_var)s=complete $1 ) )
19     return 0
20 }
21 
22 complete -F %(complete_func)s -o default %(script_names)s
23 '''
24 
25 _invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]')
26 
27 
28 def get_completion_script(prog_name, complete_var):
29     cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_'))
30     return (COMPLETION_SCRIPT % {
31         'complete_func': '_%s_completion' % cf_name,
32         'script_names': prog_name,
33         'autocomplete_var': complete_var,
34     }).strip() + ';'
35 
36 
37 def resolve_ctx(cli, prog_name, args):
38     """
39     Parse into a hierarchy of contexts. Contexts are connected through the parent variable.
40     :param cli: command definition
41     :param prog_name: the program that is running
42     :param args: full list of args
43     :return: the final context/command parsed
44     """
45     ctx = cli.make_context(prog_name, args, resilient_parsing=True)
46     args_remaining = ctx.protected_args + ctx.args
47     while ctx is not None and args_remaining:
48         if isinstance(ctx.command, MultiCommand):
49             cmd = ctx.command.get_command(ctx, args_remaining[0])
50             if cmd is None:
51                 return None
52             ctx = cmd.make_context(
53                 args_remaining[0], args_remaining[1:], parent=ctx, resilient_parsing=True)
54             args_remaining = ctx.protected_args + ctx.args
55         else:
56             ctx = ctx.parent
57 
58     return ctx
59 
60 
61 def start_of_option(param_str):
62     """
63     :param param_str: param_str to check
64     :return: whether or not this is the start of an option declaration (i.e. starts "-" or "--")
65     """
66     return param_str and param_str[:1] == '-'
67 
68 
69 def is_incomplete_option(all_args, cmd_param):
70     """
71     :param all_args: the full original list of args supplied
72     :param cmd_param: the current command paramter
73     :return: whether or not the last option declaration (i.e. starts "-" or "--") is incomplete and
74     corresponds to this cmd_param. In other words whether this cmd_param option can still accept
75     values
76     """
77     if not isinstance(cmd_param, Option):
78         return False
79     if cmd_param.is_flag:
80         return False
81     last_option = None
82     for index, arg_str in enumerate(reversed([arg for arg in all_args if arg != WORDBREAK])):
83         if index + 1 > cmd_param.nargs:
84             break
85         if start_of_option(arg_str):
86             last_option = arg_str
87 
88     return True if last_option and last_option in cmd_param.opts else False
89 
90 
91 def is_incomplete_argument(current_params, cmd_param):
92     """
93     :param current_params: the current params and values for this argument as already entered
94     :param cmd_param: the current command parameter
95     :return: whether or not the last argument is incomplete and corresponds to this cmd_param. In
96     other words whether or not the this cmd_param argument can still accept values
97     """
98     if not isinstance(cmd_param, Argument):
99         return False
100     current_param_values = current_params[cmd_param.name]
101     if current_param_values is None:
102         return True
103     if cmd_param.nargs == -1:
104         return True
105     if isinstance(current_param_values, collections.Iterable) \
106             and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs:
107         return True
108     return False
109 
110 
111 def get_user_autocompletions(ctx, args, incomplete, cmd_param):
112     """
113     :param ctx: context associated with the parsed command
114     :param args: full list of args
115     :param incomplete: the incomplete text to autocomplete
116     :param cmd_param: command definition
117     :return: all the possible user-specified completions for the param
118     """
119     if isinstance(cmd_param.type, Choice):
120         return [c for c in cmd_param.type.choices if c.startswith(incomplete)]
121     elif cmd_param.autocompletion is not None:
122         return cmd_param.autocompletion(ctx=ctx,
123                                         args=args,
124                                         incomplete=incomplete)
125     else:
126         return []
127 
128 
129 def add_subcommand_completions(ctx, incomplete, completions_out):
130     # Add subcommand completions.
131     if isinstance(ctx.command, MultiCommand):
132         completions_out.extend(
133             [c for c in ctx.command.list_commands(ctx) if c.startswith(incomplete)])
134 
135     # Walk up the context list and add any other completion possibilities from chained commands
136     while ctx.parent is not None:
137         ctx = ctx.parent
138         if isinstance(ctx.command, MultiCommand) and ctx.command.chain:
139             remaining_commands = sorted(
140                 set(ctx.command.list_commands(ctx)) - set(ctx.protected_args))
141             completions_out.extend(
142                 [c for c in remaining_commands if c.startswith(incomplete)])
143 
144 
145 def get_choices(cli, prog_name, args, incomplete):
146     """
147     :param cli: command definition
148     :param prog_name: the program that is running
149     :param args: full list of args
150     :param incomplete: the incomplete text to autocomplete
151     :return: all the possible completions for the incomplete
152     """
153     all_args = copy.deepcopy(args)
154 
155     ctx = resolve_ctx(cli, prog_name, args)
156     if ctx is None:
157         return []
158 
159     # In newer versions of bash long opts with '='s are partitioned, but it's easier to parse
160     # without the '='
161     if start_of_option(incomplete) and WORDBREAK in incomplete:
162         partition_incomplete = incomplete.partition(WORDBREAK)
163         all_args.append(partition_incomplete[0])
164         incomplete = partition_incomplete[2]
165     elif incomplete == WORDBREAK:
166         incomplete = ''
167 
168     completions = []
169     if start_of_option(incomplete):
170         # completions for partial options
171         for param in ctx.command.params:
172             if isinstance(param, Option):
173                 param_opts = [param_opt for param_opt in param.opts +
174                               param.secondary_opts if param_opt not in all_args or param.multiple]
175                 completions.extend(
176                     [c for c in param_opts if c.startswith(incomplete)])
177         return completions
178     # completion for option values from user supplied values
179     for param in ctx.command.params:
180         if is_incomplete_option(all_args, param):
181             return get_user_autocompletions(ctx, all_args, incomplete, param)
182     # completion for argument values from user supplied values
183     for param in ctx.command.params:
184         if is_incomplete_argument(ctx.params, param):
185             completions.extend(get_user_autocompletions(
186                 ctx, all_args, incomplete, param))
187             # Stop looking for other completions only if this argument is required.
188             if param.required:
189                 return completions
190             break
191 
192     add_subcommand_completions(ctx, incomplete, completions)
193     return completions
194 
195 
196 def do_complete(cli, prog_name):
197     cwords = split_arg_string(os.environ['COMP_WORDS'])
198     cword = int(os.environ['COMP_CWORD'])
199     args = cwords[1:cword]
200     try:
201         incomplete = cwords[cword]
202     except IndexError:
203         incomplete = ''
204 
205     for item in get_choices(cli, prog_name, args, incomplete):
206         echo(item)
207 
208     return True
209 
210 
211 def bashcomplete(cli, prog_name, complete_var, complete_instr):
212     if complete_instr == 'source':
213         echo(get_completion_script(prog_name, complete_var))
214         return True
215     elif complete_instr == 'complete':
216         return do_complete(cli, prog_name)
217     return False
218
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/click/_bashcomplete.py b/click/_bashcomplete.py
--- a/click/_bashcomplete.py
+++ b/click/_bashcomplete.py
@@ -10,7 +10,7 @@
 
 WORDBREAK = '='
 
-COMPLETION_SCRIPT = '''
+COMPLETION_SCRIPT_BASH = '''
 %(complete_func)s() {
     local IFS=$'\n'
     COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\
@@ -19,15 +19,30 @@
     return 0
 }
 
-complete -F %(complete_func)s -o default %(script_names)s
+complete -F %(complete_func)s %(script_names)s
+'''
+
+COMPLETION_SCRIPT_ZSH = '''
+%(complete_func)s() {
+    emulate -L zsh
+    local IFS=$'\n'
+    local completions=( $( env COMP_WORDS="${words[*]}" \\
+                        COMP_CWORD=$((CURRENT-1)) \\
+                        %(autocomplete_var)s="complete" \\
+                        %(script_names)s ) )
+    compadd -M 'r:|=* l:|=* r:|=*' -a -- completions 
+}
+
+compdef %(complete_func)s %(script_names)s
 '''
 
 _invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]')
 
 
-def get_completion_script(prog_name, complete_var):
+def get_completion_script(prog_name, complete_var, shell):
     cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_'))
-    return (COMPLETION_SCRIPT % {
+    script = COMPLETION_SCRIPT_ZSH if shell == 'zsh' else COMPLETION_SCRIPT_BASH
+    return (script % {
         'complete_func': '_%s_completion' % cf_name,
         'script_names': prog_name,
         'autocomplete_var': complete_var,
@@ -209,8 +224,9 @@
 
 
 def bashcomplete(cli, prog_name, complete_var, complete_instr):
-    if complete_instr == 'source':
-        echo(get_completion_script(prog_name, complete_var))
+    if complete_instr.startswith('source'):
+        shell = 'zsh' if complete_instr == 'source_zsh' else 'bash'
+        echo(get_completion_script(prog_name, complete_var, shell))
         return True
     elif complete_instr == 'complete':
         return do_complete(cli, prog_name)

{"golden_diff": "diff --git a/click/_bashcomplete.py b/click/_bashcomplete.py\n--- a/click/_bashcomplete.py\n+++ b/click/_bashcomplete.py\n@@ -10,7 +10,7 @@\n \n WORDBREAK = '='\n \n-COMPLETION_SCRIPT = '''\n+COMPLETION_SCRIPT_BASH = '''\n %(complete_func)s() {\n     local IFS=$'\\n'\n     COMPREPLY=( $( env COMP_WORDS=\"${COMP_WORDS[*]}\" \\\\\n@@ -19,15 +19,30 @@\n     return 0\n }\n \n-complete -F %(complete_func)s -o default %(script_names)s\n+complete -F %(complete_func)s %(script_names)s\n+'''\n+\n+COMPLETION_SCRIPT_ZSH = '''\n+%(complete_func)s() {\n+    emulate -L zsh\n+    local IFS=$'\\n'\n+    local completions=( $( env COMP_WORDS=\"${words[*]}\" \\\\\n+                        COMP_CWORD=$((CURRENT-1)) \\\\\n+                        %(autocomplete_var)s=\"complete\" \\\\\n+                        %(script_names)s ) )\n+    compadd -M 'r:|=* l:|=* r:|=*' -a -- completions \n+}\n+\n+compdef %(complete_func)s %(script_names)s\n '''\n \n _invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]')\n \n \n-def get_completion_script(prog_name, complete_var):\n+def get_completion_script(prog_name, complete_var, shell):\n     cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_'))\n-    return (COMPLETION_SCRIPT % {\n+    script = COMPLETION_SCRIPT_ZSH if shell == 'zsh' else COMPLETION_SCRIPT_BASH\n+    return (script % {\n         'complete_func': '_%s_completion' % cf_name,\n         'script_names': prog_name,\n         'autocomplete_var': complete_var,\n@@ -209,8 +224,9 @@\n \n \n def bashcomplete(cli, prog_name, complete_var, complete_instr):\n-    if complete_instr == 'source':\n-        echo(get_completion_script(prog_name, complete_var))\n+    if complete_instr.startswith('source'):\n+        shell = 'zsh' if complete_instr == 'source_zsh' else 'bash'\n+        echo(get_completion_script(prog_name, complete_var, shell))\n         return True\n     elif complete_instr == 'complete':\n         return do_complete(cli, prog_name)\n", "issue": "Autocomplete support for zsh\nBash autocompletion works well, but I would really like zsh to work as well\n\n", "before_files": [{"content": "import collections\nimport copy\nimport os\nimport re\n\nfrom .utils import echo\nfrom .parser import split_arg_string\nfrom .core import MultiCommand, Option, Argument\nfrom .types import Choice\n\nWORDBREAK = '='\n\nCOMPLETION_SCRIPT = '''\n%(complete_func)s() {\n    local IFS=$'\\n'\n    COMPREPLY=( $( env COMP_WORDS=\"${COMP_WORDS[*]}\" \\\\\n                   COMP_CWORD=$COMP_CWORD \\\\\n                   %(autocomplete_var)s=complete $1 ) )\n    return 0\n}\n\ncomplete -F %(complete_func)s -o default %(script_names)s\n'''\n\n_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]')\n\n\ndef get_completion_script(prog_name, complete_var):\n    cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_'))\n    return (COMPLETION_SCRIPT % {\n        'complete_func': '_%s_completion' % cf_name,\n        'script_names': prog_name,\n        'autocomplete_var': complete_var,\n    }).strip() + ';'\n\n\ndef resolve_ctx(cli, prog_name, args):\n    \"\"\"\n    Parse into a hierarchy of contexts. Contexts are connected through the parent variable.\n    :param cli: command definition\n    :param prog_name: the program that is running\n    :param args: full list of args\n    :return: the final context/command parsed\n    \"\"\"\n    ctx = cli.make_context(prog_name, args, resilient_parsing=True)\n    args_remaining = ctx.protected_args + ctx.args\n    while ctx is not None and args_remaining:\n        if isinstance(ctx.command, MultiCommand):\n            cmd = ctx.command.get_command(ctx, args_remaining[0])\n            if cmd is None:\n                return None\n            ctx = cmd.make_context(\n                args_remaining[0], args_remaining[1:], parent=ctx, resilient_parsing=True)\n            args_remaining = ctx.protected_args + ctx.args\n        else:\n            ctx = ctx.parent\n\n    return ctx\n\n\ndef start_of_option(param_str):\n    \"\"\"\n    :param param_str: param_str to check\n    :return: whether or not this is the start of an option declaration (i.e. starts \"-\" or \"--\")\n    \"\"\"\n    return param_str and param_str[:1] == '-'\n\n\ndef is_incomplete_option(all_args, cmd_param):\n    \"\"\"\n    :param all_args: the full original list of args supplied\n    :param cmd_param: the current command paramter\n    :return: whether or not the last option declaration (i.e. starts \"-\" or \"--\") is incomplete and\n    corresponds to this cmd_param. In other words whether this cmd_param option can still accept\n    values\n    \"\"\"\n    if not isinstance(cmd_param, Option):\n        return False\n    if cmd_param.is_flag:\n        return False\n    last_option = None\n    for index, arg_str in enumerate(reversed([arg for arg in all_args if arg != WORDBREAK])):\n        if index + 1 > cmd_param.nargs:\n            break\n        if start_of_option(arg_str):\n            last_option = arg_str\n\n    return True if last_option and last_option in cmd_param.opts else False\n\n\ndef is_incomplete_argument(current_params, cmd_param):\n    \"\"\"\n    :param current_params: the current params and values for this argument as already entered\n    :param cmd_param: the current command parameter\n    :return: whether or not the last argument is incomplete and corresponds to this cmd_param. In\n    other words whether or not the this cmd_param argument can still accept values\n    \"\"\"\n    if not isinstance(cmd_param, Argument):\n        return False\n    current_param_values = current_params[cmd_param.name]\n    if current_param_values is None:\n        return True\n    if cmd_param.nargs == -1:\n        return True\n    if isinstance(current_param_values, collections.Iterable) \\\n            and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs:\n        return True\n    return False\n\n\ndef get_user_autocompletions(ctx, args, incomplete, cmd_param):\n    \"\"\"\n    :param ctx: context associated with the parsed command\n    :param args: full list of args\n    :param incomplete: the incomplete text to autocomplete\n    :param cmd_param: command definition\n    :return: all the possible user-specified completions for the param\n    \"\"\"\n    if isinstance(cmd_param.type, Choice):\n        return [c for c in cmd_param.type.choices if c.startswith(incomplete)]\n    elif cmd_param.autocompletion is not None:\n        return cmd_param.autocompletion(ctx=ctx,\n                                        args=args,\n                                        incomplete=incomplete)\n    else:\n        return []\n\n\ndef add_subcommand_completions(ctx, incomplete, completions_out):\n    # Add subcommand completions.\n    if isinstance(ctx.command, MultiCommand):\n        completions_out.extend(\n            [c for c in ctx.command.list_commands(ctx) if c.startswith(incomplete)])\n\n    # Walk up the context list and add any other completion possibilities from chained commands\n    while ctx.parent is not None:\n        ctx = ctx.parent\n        if isinstance(ctx.command, MultiCommand) and ctx.command.chain:\n            remaining_commands = sorted(\n                set(ctx.command.list_commands(ctx)) - set(ctx.protected_args))\n            completions_out.extend(\n                [c for c in remaining_commands if c.startswith(incomplete)])\n\n\ndef get_choices(cli, prog_name, args, incomplete):\n    \"\"\"\n    :param cli: command definition\n    :param prog_name: the program that is running\n    :param args: full list of args\n    :param incomplete: the incomplete text to autocomplete\n    :return: all the possible completions for the incomplete\n    \"\"\"\n    all_args = copy.deepcopy(args)\n\n    ctx = resolve_ctx(cli, prog_name, args)\n    if ctx is None:\n        return []\n\n    # In newer versions of bash long opts with '='s are partitioned, but it's easier to parse\n    # without the '='\n    if start_of_option(incomplete) and WORDBREAK in incomplete:\n        partition_incomplete = incomplete.partition(WORDBREAK)\n        all_args.append(partition_incomplete[0])\n        incomplete = partition_incomplete[2]\n    elif incomplete == WORDBREAK:\n        incomplete = ''\n\n    completions = []\n    if start_of_option(incomplete):\n        # completions for partial options\n        for param in ctx.command.params:\n            if isinstance(param, Option):\n                param_opts = [param_opt for param_opt in param.opts +\n                              param.secondary_opts if param_opt not in all_args or param.multiple]\n                completions.extend(\n                    [c for c in param_opts if c.startswith(incomplete)])\n        return completions\n    # completion for option values from user supplied values\n    for param in ctx.command.params:\n        if is_incomplete_option(all_args, param):\n            return get_user_autocompletions(ctx, all_args, incomplete, param)\n    # completion for argument values from user supplied values\n    for param in ctx.command.params:\n        if is_incomplete_argument(ctx.params, param):\n            completions.extend(get_user_autocompletions(\n                ctx, all_args, incomplete, param))\n            # Stop looking for other completions only if this argument is required.\n            if param.required:\n                return completions\n            break\n\n    add_subcommand_completions(ctx, incomplete, completions)\n    return completions\n\n\ndef do_complete(cli, prog_name):\n    cwords = split_arg_string(os.environ['COMP_WORDS'])\n    cword = int(os.environ['COMP_CWORD'])\n    args = cwords[1:cword]\n    try:\n        incomplete = cwords[cword]\n    except IndexError:\n        incomplete = ''\n\n    for item in get_choices(cli, prog_name, args, incomplete):\n        echo(item)\n\n    return True\n\n\ndef bashcomplete(cli, prog_name, complete_var, complete_instr):\n    if complete_instr == 'source':\n        echo(get_completion_script(prog_name, complete_var))\n        return True\n    elif complete_instr == 'complete':\n        return do_complete(cli, prog_name)\n    return False\n", "path": "click/_bashcomplete.py"}], "after_files": [{"content": "import collections\nimport copy\nimport os\nimport re\n\nfrom .utils import echo\nfrom .parser import split_arg_string\nfrom .core import MultiCommand, Option, Argument\nfrom .types import Choice\n\nWORDBREAK = '='\n\nCOMPLETION_SCRIPT_BASH = '''\n%(complete_func)s() {\n    local IFS=$'\\n'\n    COMPREPLY=( $( env COMP_WORDS=\"${COMP_WORDS[*]}\" \\\\\n                   COMP_CWORD=$COMP_CWORD \\\\\n                   %(autocomplete_var)s=complete $1 ) )\n    return 0\n}\n\ncomplete -F %(complete_func)s %(script_names)s\n'''\n\nCOMPLETION_SCRIPT_ZSH = '''\n%(complete_func)s() {\n    emulate -L zsh\n    local IFS=$'\\n'\n    local completions=( $( env COMP_WORDS=\"${words[*]}\" \\\\\n                        COMP_CWORD=$((CURRENT-1)) \\\\\n                        %(autocomplete_var)s=\"complete\" \\\\\n                        %(script_names)s ) )\n    compadd -M 'r:|=* l:|=* r:|=*' -a -- completions \n}\n\ncompdef %(complete_func)s %(script_names)s\n'''\n\n_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]')\n\n\ndef get_completion_script(prog_name, complete_var, shell):\n    cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_'))\n    script = COMPLETION_SCRIPT_ZSH if shell == 'zsh' else COMPLETION_SCRIPT_BASH\n    return (script % {\n        'complete_func': '_%s_completion' % cf_name,\n        'script_names': prog_name,\n        'autocomplete_var': complete_var,\n    }).strip() + ';'\n\n\ndef resolve_ctx(cli, prog_name, args):\n    \"\"\"\n    Parse into a hierarchy of contexts. Contexts are connected through the parent variable.\n    :param cli: command definition\n    :param prog_name: the program that is running\n    :param args: full list of args\n    :return: the final context/command parsed\n    \"\"\"\n    ctx = cli.make_context(prog_name, args, resilient_parsing=True)\n    args_remaining = ctx.protected_args + ctx.args\n    while ctx is not None and args_remaining:\n        if isinstance(ctx.command, MultiCommand):\n            cmd = ctx.command.get_command(ctx, args_remaining[0])\n            if cmd is None:\n                return None\n            ctx = cmd.make_context(\n                args_remaining[0], args_remaining[1:], parent=ctx, resilient_parsing=True)\n            args_remaining = ctx.protected_args + ctx.args\n        else:\n            ctx = ctx.parent\n\n    return ctx\n\n\ndef start_of_option(param_str):\n    \"\"\"\n    :param param_str: param_str to check\n    :return: whether or not this is the start of an option declaration (i.e. starts \"-\" or \"--\")\n    \"\"\"\n    return param_str and param_str[:1] == '-'\n\n\ndef is_incomplete_option(all_args, cmd_param):\n    \"\"\"\n    :param all_args: the full original list of args supplied\n    :param cmd_param: the current command paramter\n    :return: whether or not the last option declaration (i.e. starts \"-\" or \"--\") is incomplete and\n    corresponds to this cmd_param. In other words whether this cmd_param option can still accept\n    values\n    \"\"\"\n    if not isinstance(cmd_param, Option):\n        return False\n    if cmd_param.is_flag:\n        return False\n    last_option = None\n    for index, arg_str in enumerate(reversed([arg for arg in all_args if arg != WORDBREAK])):\n        if index + 1 > cmd_param.nargs:\n            break\n        if start_of_option(arg_str):\n            last_option = arg_str\n\n    return True if last_option and last_option in cmd_param.opts else False\n\n\ndef is_incomplete_argument(current_params, cmd_param):\n    \"\"\"\n    :param current_params: the current params and values for this argument as already entered\n    :param cmd_param: the current command parameter\n    :return: whether or not the last argument is incomplete and corresponds to this cmd_param. In\n    other words whether or not the this cmd_param argument can still accept values\n    \"\"\"\n    if not isinstance(cmd_param, Argument):\n        return False\n    current_param_values = current_params[cmd_param.name]\n    if current_param_values is None:\n        return True\n    if cmd_param.nargs == -1:\n        return True\n    if isinstance(current_param_values, collections.Iterable) \\\n            and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs:\n        return True\n    return False\n\n\ndef get_user_autocompletions(ctx, args, incomplete, cmd_param):\n    \"\"\"\n    :param ctx: context associated with the parsed command\n    :param args: full list of args\n    :param incomplete: the incomplete text to autocomplete\n    :param cmd_param: command definition\n    :return: all the possible user-specified completions for the param\n    \"\"\"\n    if isinstance(cmd_param.type, Choice):\n        return [c for c in cmd_param.type.choices if c.startswith(incomplete)]\n    elif cmd_param.autocompletion is not None:\n        return cmd_param.autocompletion(ctx=ctx,\n                                        args=args,\n                                        incomplete=incomplete)\n    else:\n        return []\n\n\ndef add_subcommand_completions(ctx, incomplete, completions_out):\n    # Add subcommand completions.\n    if isinstance(ctx.command, MultiCommand):\n        completions_out.extend(\n            [c for c in ctx.command.list_commands(ctx) if c.startswith(incomplete)])\n\n    # Walk up the context list and add any other completion possibilities from chained commands\n    while ctx.parent is not None:\n        ctx = ctx.parent\n        if isinstance(ctx.command, MultiCommand) and ctx.command.chain:\n            remaining_commands = sorted(\n                set(ctx.command.list_commands(ctx)) - set(ctx.protected_args))\n            completions_out.extend(\n                [c for c in remaining_commands if c.startswith(incomplete)])\n\n\ndef get_choices(cli, prog_name, args, incomplete):\n    \"\"\"\n    :param cli: command definition\n    :param prog_name: the program that is running\n    :param args: full list of args\n    :param incomplete: the incomplete text to autocomplete\n    :return: all the possible completions for the incomplete\n    \"\"\"\n    all_args = copy.deepcopy(args)\n\n    ctx = resolve_ctx(cli, prog_name, args)\n    if ctx is None:\n        return []\n\n    # In newer versions of bash long opts with '='s are partitioned, but it's easier to parse\n    # without the '='\n    if start_of_option(incomplete) and WORDBREAK in incomplete:\n        partition_incomplete = incomplete.partition(WORDBREAK)\n        all_args.append(partition_incomplete[0])\n        incomplete = partition_incomplete[2]\n    elif incomplete == WORDBREAK:\n        incomplete = ''\n\n    completions = []\n    if start_of_option(incomplete):\n        # completions for partial options\n        for param in ctx.command.params:\n            if isinstance(param, Option):\n                param_opts = [param_opt for param_opt in param.opts +\n                              param.secondary_opts if param_opt not in all_args or param.multiple]\n                completions.extend(\n                    [c for c in param_opts if c.startswith(incomplete)])\n        return completions\n    # completion for option values from user supplied values\n    for param in ctx.command.params:\n        if is_incomplete_option(all_args, param):\n            return get_user_autocompletions(ctx, all_args, incomplete, param)\n    # completion for argument values from user supplied values\n    for param in ctx.command.params:\n        if is_incomplete_argument(ctx.params, param):\n            completions.extend(get_user_autocompletions(\n                ctx, all_args, incomplete, param))\n            # Stop looking for other completions only if this argument is required.\n            if param.required:\n                return completions\n            break\n\n    add_subcommand_completions(ctx, incomplete, completions)\n    return completions\n\n\ndef do_complete(cli, prog_name):\n    cwords = split_arg_string(os.environ['COMP_WORDS'])\n    cword = int(os.environ['COMP_CWORD'])\n    args = cwords[1:cword]\n    try:\n        incomplete = cwords[cword]\n    except IndexError:\n        incomplete = ''\n\n    for item in get_choices(cli, prog_name, args, incomplete):\n        echo(item)\n\n    return True\n\n\ndef bashcomplete(cli, prog_name, complete_var, complete_instr):\n    if complete_instr.startswith('source'):\n        shell = 'zsh' if complete_instr == 'source_zsh' else 'bash'\n        echo(get_completion_script(prog_name, complete_var, shell))\n        return True\n    elif complete_instr == 'complete':\n        return do_complete(cli, prog_name)\n    return False\n", "path": "click/_bashcomplete.py"}]}