kislyuk / argcomplete

Python and tab completion, better together.
https://kislyuk.github.io/argcomplete/
Apache License 2.0
1.41k stars 133 forks source link

Wrong doc for activate-global-python-argcomplete #329

Open maxrossello opened 3 years ago

maxrossello commented 3 years ago

Documentation says that the command for global autocomplete with dest folder specification should be

_activate-global-python-argcomplete --dest=/path/to/bashcompletion.d

but actually the syntax with --dest= is rejected:

$ activate-global-python-argcomplete --dest=~/.local/share/bash-completion/completions
usage: activate-global-python-argcomplete [-h] [--dest DEST] [--user]
[--no-defaults]
[--complete-arguments ...]

As the help reports, a space must be used instead:

$ activate-global-python-argcomplete --dest ~/.local/share/bash-completion/completions
Installing bash completion script /home/rossellom/.local/share/bash-completion/completions/python-argcomplete

maxrossello commented 3 years ago

Furthermore, I found out that (at least on Ubuntu 18.04) the working installation as a user is to run:

_activate-global-python-argcomplete --dest=- >> .bashcompletion

First, the _~/.bashcompletion.d/ folder is not considered at all, and the working local folder for autocompletion scripts is ~/.local/share/bash-completion/completions instead. But, secondly, this folder is used for dynamic autocompletion, so the script name should have exactly the name of the autocompleted command, which is not the case for generic autocompletion. Hence my suggestion above.

evanunderscore commented 3 years ago

I can't reproduce this; the command line works the same for me both ways. The parser is built using argparse, which has supported both forms by default for as long as I've used it. Are you certain that syntax doesn't work? Which version of Python are you using?

evanunderscore commented 3 years ago

Never mind, I think I've worked out the problem. The important part is the error message after the usage:

usage: activate-global-python-argcomplete [-h] [--dest DEST] [--user]
                                          [--no-defaults]
                                          [--complete-arguments ...]
activate-global-python-argcomplete: error: Path ~/.local/share/bash-completion/completions does not exist

Bash doesn't appear to perform ~ expansion with the dest=~/... form.

Strictly speaking there's nothing wrong with the syntax in the documentation since the example does not include ~, however I agree it would probably be nice to change it to the form that won't break for paths that do.

maxrossello commented 3 years ago

Thanks @evanunderscore for your response! Maybe it's argparse's problem, but note that the misinterpretation arose from the fact that using ~ with a space does work:

$ activate-global-python-argcomplete --dest ~/.local/share/bash-completion/completions Installing bash completion script /home/rossellom/.local/share/bash-completion/completions/python-argcomplete

(EDIT: probably because in this case it's expanded by bash itself. Then maybe giving the example with space covers all the cases)

What about the fact that _~/.bashcompletion.d is not considered in Ubuntu and that for a default complete rule to be loaded for user ~/.bash_completion is the working choice?

Thanks a lot for the awesome project!

kislyuk commented 3 years ago

@evanunderscore thanks for tracking that down, we should just use https://docs.python.org/3.8/library/os.path.html#os.path.expanduser - we could even use this shorthand: parser.add_argument(..., type=os.path.expanduser)

kislyuk commented 3 years ago

@maxrossello

What about the fact that ~/.bash_completion.d is not considered in Ubuntu and that for a default complete rule to be loaded for user ~/.bash_completion is the working choice?

The following link provides a comprehensive review of your options: https://serverfault.com/a/831184

It looks like you need bash-completion >= version 2.9 for ~/.bash_completion.d to work.

maxrossello commented 3 years ago

@evanunderscore thanks for tracking that down, we should just use https://docs.python.org/3.8/library/os.path.html#os.path.expanduser - we could even use this shorthand: parser.add_argument(..., type=os.path.expanduser)

great!

maxrossello commented 3 years ago

The following link provides a comprehensive review of your options: https://serverfault.com/a/831184

It looks like you need bash-completion >= version 2.9 for ~/.bash_completion.d to work.

Well, no. The link you provide depicts a manual workaround for version <= 2.8 involving ~/.bash_completion.d as an arbitrarily chosen folder where to store scripts eagerly loaded from ~/.bash_completion through a customly written for loop. Looks like ~/.bash_completion.d has never been considered as a relevant folder by bash-completion.

In fact, even in 2.9 (cfr https://github.com/scop/bash-completion/tree/2.9) no ~/.bash_completion.d folder is mentioned, and the default user folder is the one already working for on demand loading in my 2.8 installation, i.e. ~/.local/share/bash-completion/completions (or _$XDG_DATAHOME/bash-completion/completions if $XDG_DATA_HOME exists).

But as I said before, that target folder works only for on demand completion, which means that a script named python-argcomplete would be loaded on the fly only for a python-argcomplete command. Agreed, once sourced somehow, it would work globally because of the shape of the complete command inside, but that is not the point. Only _~/.bashcompletion is loaded eagerly, as explained in the bash-completion FAQ:

Q. Where should I install my own local completions?

_A. Put them in the completions subdir of $BASH_COMPLETION_USER_DIR (defaults to $XDG_DATA_HOME/bash-completion or ~/.local/share/bash-completion if $XDG_DATA_HOME is not set) to have them loaded on demand. See also the next question's answer for considerations for these files' names, they apply here as well. Alternatively, you can write them directly in ~/.bashcompletion which is loaded eagerly by our main script.

kislyuk commented 3 years ago

Looks like you're right. We should probably change this script to append directly to ~/.bash_completion or ~/.local/share/bash-completion or whatever that discovery protocol yields.

maxrossello commented 3 years ago

So far my solution has been to append to ~/.bash_completion, not to delete any existing content

activate-global-python-argcomplete --dest=- >> ~/.bash_completion

I believe that this could first be used in docs, and then maybe the --user option would do the same (including some grep to check if already there not to duplicate?)

jsabater commented 2 years ago

Just wanted to provide some feedback on this thread regarding the package python3-argcomplete on Debian Bullseye 11, which fails when executing activate-global-python-argcomplete3:

~# activate-global-python-argcomplete3
usage: activate-global-python-argcomplete3 [-h] [--dest DEST] [--user] [--no-defaults]
                                           [--complete-arguments ...]
activate-global-python-argcomplete3: error: Path /etc/bash_completion.d does not exist

As stated above in this thread, the following command, run as root, works well as equivalent to what --user should do:

activate-global-python-argcomplete3 --dest=- >> ~/.bash_completion

This provided autocompletion to my ansible-playbook command, run as root, which was the desired outcome.

Moreover, when trying to install it system-wide:

~# activate-global-python-argcomplete3 --dest=/usr/share/bash-completion/completions/
Installing bash completion script /usr/share/bash-completion/completions/python-argcomplete.sh

The file was deployed correctly but no autocompletion was happening (as devops user created afterwards). This is strange as the bash-completion Debian package installs the script /etc/profile.d/bash_completion.sh, which sources the file /usr/share/bash-completion/bash_completion and is loaded automatically by the file /etc/profile installed in all users and sourced in their ~/.bashrc files.

Incidentally, using a space character after the dest option instead of an equal sign deployed the file at the correct destination as well. But autocompletion was not working either.

The documentation in /usr/share/doc/python3-argcomplete/ does not instruct the user properly on how to install it. Perhaps the installation script of the package should install and configure it system wide, making use of dh_bash-completion as stated in /usr/share/doc/bash-completion/README.Debian?