Lets say this is related to #241 ...
Recently support was added to have argument autocompletion, custom completion functions/lists and a special case for click.Choice options too.
This is great ! I would like to see better support for filenames and directories, have been looking at the code and wanted to share my thoughts here... as far as I can see the problems with filename/directory are multiple but hopefully addressed with a couple of simple patches.
Undesirable Autocompletion of paths
In the case that the user is completing an option which takes one or more arguments, and those arguments cannot be completed (i.e. they are just a string or integer type), then the builtin completion mechanism correctly reports no results, however the bash completion glue (here) specifies "-o default"
This parameter to the bash complete function tells bash to default to completing paths when the resulting COMPREPLY array is empty, and the side effect is undesirable filenames being completed.
Filenames reported for directory arguments
Because click does not do anything for filenames or directories itself, it instead falls back on the undesirable complete -o default behavior mentioned above for filenames and all arguments which did not supply any custom autocompletion list or function.
This means that filenames are suggested when the argument is in fact a directory, and also directory names are suggested for filenames.
Filename and directory completion has different behavior
The default shell behavior is to take the reported list in COMPREPLY, and if there is only one element, it will append a space and the next TAB is ready to complete the next token, but this is not the desired behavior when completing paths, where you want to complete only one directory at a time.
This can be addressed however by using the "complete -o nospace ..." option, which will just cause the shell to not append any space for a single available completion, allowing the program to continue completing the last completion on the next iteration.
In this case, click can:
- Append a space to the reported completion in the case that only one completion was available
- Append a slash (if none is already there), in the case that the completion is a directory name
Proposed Approach
Instead of handling click.Choice explicitly in _bashcompletion.py, we should instead have the base ParamType cooperate in the process of completion, so that paths and filenames can have an opportunity to decide if the parameter is entirely complete or could be completed further (i.e. whether a space should be appended to the reported completion, or whether it should remain, as in the case for a filename which is a directory that could be completed further).
click.Choice would implement completions by overriding an abstract method of click.ParamType, click.BOOL could also implement this, because why not.
The new autocompletion attribute would be checked before ever consulting the click.ParamType abstract method, so the user can always override the default completions for any parameter.
Also, we should change the completion script to not use "-o default" and use "-o nospace" instead, ensuring that filenames dont show up by default.
Finally, the click.Path and click.File need to do the work we were previously offloading to the shell, this is the most tricky (or "meaty") part of the patch I guess, hopefully a python implementation using os.listdir() and file concatenation would not slow down the completion process too much.
Lets say this is related to #241 ...
Recently support was added to have argument autocompletion, custom completion functions/lists and a special case for click.Choice options too.
This is great ! I would like to see better support for filenames and directories, have been looking at the code and wanted to share my thoughts here... as far as I can see the problems with filename/directory are multiple but hopefully addressed with a couple of simple patches.
Undesirable Autocompletion of paths
In the case that the user is completing an option which takes one or more arguments, and those arguments cannot be completed (i.e. they are just a string or integer type), then the builtin completion mechanism correctly reports no results, however the bash completion glue (here) specifies "-o default"
This parameter to the bash complete function tells bash to default to completing paths when the resulting COMPREPLY array is empty, and the side effect is undesirable filenames being completed.
Filenames reported for directory arguments
Because click does not do anything for filenames or directories itself, it instead falls back on the undesirable complete -o default behavior mentioned above for filenames and all arguments which did not supply any custom autocompletion list or function.
This means that filenames are suggested when the argument is in fact a directory, and also directory names are suggested for filenames.
Filename and directory completion has different behavior
The default shell behavior is to take the reported list in COMPREPLY, and if there is only one element, it will append a space and the next TAB is ready to complete the next token, but this is not the desired behavior when completing paths, where you want to complete only one directory at a time.
This can be addressed however by using the "complete -o nospace ..." option, which will just cause the shell to not append any space for a single available completion, allowing the program to continue completing the last completion on the next iteration.
In this case, click can:
Proposed Approach
Instead of handling click.Choice explicitly in _bashcompletion.py, we should instead have the base ParamType cooperate in the process of completion, so that paths and filenames can have an opportunity to decide if the parameter is entirely complete or could be completed further (i.e. whether a space should be appended to the reported completion, or whether it should remain, as in the case for a filename which is a directory that could be completed further).
click.Choice would implement completions by overriding an abstract method of click.ParamType, click.BOOL could also implement this, because why not.
The new autocompletion attribute would be checked before ever consulting the click.ParamType abstract method, so the user can always override the default completions for any parameter.
Also, we should change the completion script to not use "-o default" and use "-o nospace" instead, ensuring that filenames dont show up by default.
Finally, the click.Path and click.File need to do the work we were previously offloading to the shell, this is the most tricky (or "meaty") part of the patch I guess, hopefully a python implementation using os.listdir() and file concatenation would not slow down the completion process too much.