iterative / shtab

↔️ Automagic shell tab completion for Python CLI applications
https://docs.iterative.ai/shtab
Other
375 stars 34 forks source link

Reading completion options from config file fails #75

Closed janedenone closed 2 years ago

janedenone commented 2 years ago

Hi, my script relies on a config for its profile options:

def main():
    config_file = '/home/snafu/rbackup.ini'
    config = configparser.ConfigParser()
    config.read(config_file)

    parser = argparse.ArgumentParser(description='Backup with rsync')
    parser.add_argument('profile', type=str, choices=config.sections(), help='the profile to use')
    parser.add_argument("-u", "--unsafe", help="turn off ransomware checks",
                    action="store_true")
    parser.add_argument("-d", "--dry", help="dry run (do not back up)",
                    action="store_true")
    args = parser.parse_args()

When executing shtab --shell=zsh --verbose rbackup.main, shtab first returns the script's help message:

usage: shtab [-h] [-u] [-d]
             {profile1, profile2, ...}

and then prints the script's error message for not providing a profile argument:

shtab: error: argument profile: invalid choice: 'rbackup.main' (choose from  'profile1', 'profile2', ...

Why is that?

Thanks, Jan

casperdcl commented 2 years ago
  1. shtab doesn't have a --verbose option... maybe you meant shtab --shell=zsh rbackup.main?
  2. usage: shtab [-h] [-u] [-d] {profile1, profile2, ...} is definitely not this shtab program. try doing which shtab to find out the location, and also use python -m shtab to force use Python's version

TL;DR:

python3 -m pip install -U shtab
python3 -m shtab --shell=zsh rbackup.main
janedenone commented 2 years ago

Thanks, but there is only one version of shtab on my system (the one I installed using pip). It does have a verbose option:

% shtab --help
usage: shtab [-h] [--version] [-s {bash,zsh,tcsh}] [--prefix PREFIX] [--preamble PREAMBLE] [--prog PROG] [-u] [--verbose] parser

As I wrote above, shtab shows the usage info for my own script, followed by my script's error message. I cannot explain this behavior.

casperdcl commented 2 years ago

Ah yes --verbose was recently added. Anyway:

def main():
    ...
    args = parser.parse_args()

should be:

def get_parser():
    ...
    return parser

def main():
    parser = get_parser()
    args = parser.parse_args()

then you can do: shtab --shell=zsh rbackup.get_parser

janedenone commented 2 years ago

Getting there!

shtab --shell=zsh --prog rb rbackup.get_parser | sudo tee /usr/local/share/zsh/site-functions/_rb

creates _rb with the proper commands (and modifies ~/.zcompdump), but auto-complete still does not work for rb(my alias for the script rbackup.py).

If I remove the prog parameter, the file is created for shtab itself – and auto-complete with my script's arguments works for shtab! Manually changing that file's initial line from #compdef shtab to #compdef rb does not help, because then neither shtab nor rb will auto-complete.

casperdcl commented 2 years ago

missing either

  1. parser = argparse.ArgumentParser(description='Backup with rsync', prog='rb')
  2. or shtab --prog=rb

I think, see the FAQs

janedenone commented 2 years ago

I finally got it to work. Turns out an alias in .zshrc will not work, but a symlink to rbackup will. Thanks for all your help!