click-contrib / click-completion

Add or enhance bash, fish, zsh and powershell completion in Click
MIT License
288 stars 33 forks source link

Single function/command with options: no completion #4

Closed kontrafiktion closed 6 years ago

kontrafiktion commented 6 years ago

Hi! I have the following reduced example:

# file: xdummy
import click
import click_completion

click_completion.init()

@click.command()
@click.option('--upper/--lower', default=None, help="Change text to upper or lower case")
def echo(upper):
    click.echo(' foo ')

if __name__ == "__main__":
    echo()

When I try to complete

"xdummy "

(a single space after the name) I do not get any completions.

I would have expected to get "--upper" "--lower", and perhaps "--help" but I do not get anything. What am I doing wrong?

glehmann commented 6 years ago

options are not completed unless you write a first dash. Just try xdummy - then hit tab.

kontrafiktion commented 6 years ago

Thx. Will try to find a workaround. As a user I wouldn’t expect that behavior

glehmann commented 6 years ago

It could be a customisable behavior.

This is the behavior of the bash completion natively present in click, and I think it is very nice to use with subcommands and arguments with a custom value completion.

I understand it may not be always the best behavior though, especially for the programs that rely heavily on options instead of subcommands, and probably other cases.

kontrafiktion commented 6 years ago

Just to understand, what would be necessary I patched the do_zsh_completefunction:

diff --git a/click_completion/__init__.py b/click_completion/__init__.py
index 26e2bb7..26a93cf 100644
--- a/click_completion/__init__.py
+++ b/click_completion/__init__.py
@@ -158,7 +158,10 @@ def do_zsh_complete(cli, prog_name):
     def escape(s):
         return s.replace('"', '""').replace("'", "''").replace('$', '\\$')
     res = []
-    for item, help in get_choices(cli, prog_name, args, incomplete):
+    choices = list(get_choices(cli, prog_name, args, incomplete))
+    if len(choices) == 0 and incomplete ==  '':
+        choices = get_choices(cli, prog_name, args, "-")
+    for item, help in choices:
         if help:
             res.append('"%s"\:"%s"' % (escape(item), escape(help)))
         else:

What I really do not know: How could I make this customizable. I haven't yet found anything in the code, where I could put some kind of configuration parameter. I hoped that I could use the init() function, but it is just replacing stuff in click.core.

Could you give me any hints?

And would do you think about the above patch?

kontrafiktion commented 6 years ago

Perhaps:

def init(assumeDash=False):
    ...
    click.core._bashcomplete = _wrapped_shell_complete(assumeDash)

def _wrapped_shell_complete(assumeDash):
    def _shellcomplete(cli, prog_name, complete_var=None):
        ...
        elif complete_instr == 'complete-zsh':
            do_zsh_complete(cli, prog_name, assumeDash)
        ...

    return _shellcomplete
kontrafiktion commented 6 years ago

Ping @glehmann

glehmann commented 6 years ago

Sorry for the too long time before reply.

This could be done in the init method — it only has to store the parameters somewhere they can be reused.

Another option is to predefine a variable that allow to customize that behavior, as we did with startswith, and that the user can replace by something else directly in the module. Something like click_completion.complete_options = True. I definitely prefer the init though.

BTW, the method that should be modified in get_choices. The option completion is done line 53, only when incomplete is not empty. This check should be changed, and the whole if elif else block should be reorganize to allow to visit several blocks at once (option and subcommands for example).

glehmann commented 6 years ago

I gave it a try in ff48df2645a87313e18190cef6be61462ce2b853. Could you test it?

kontrafiktion commented 6 years ago

Works fine for me.

Thx!

From: Gaëtan Lehmann notifications@github.com notifications@github.com Reply: click-contrib/click-completion reply@reply.github.com reply@reply.github.com Date: 5. April 2018 at 17:13:06 To: click-contrib/click-completion click-completion@noreply.github.com click-completion@noreply.github.com Cc: Victor Volle victor.volle@beta-thoughts.org victor.volle@beta-thoughts.org, Author author@noreply.github.com author@noreply.github.com Subject: Re: [click-contrib/click-completion] Single function/command with options: no completion (#4)

I gave it a try in ff48df2 https://github.com/click-contrib/click-completion/commit/ff48df2645a87313e18190cef6be61462ce2b853. Could you test it?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/click-contrib/click-completion/issues/4#issuecomment-378971098, or mute the thread https://github.com/notifications/unsubscribe-auth/AAMHZmOCYmnI1ofa24qlZTJ84t_y2Avzks5tljSCgaJpZM4Robsl .

glehmann commented 6 years ago

merged in master!