|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# coding=utf-8 |
| 3 | +# PYTHON_ARGCOMPLETE_OK - This is required at the beginning of the file to enable argcomplete support |
| 4 | +"""A simple example demonstrating integration with argcomplete. |
| 5 | +
|
| 6 | +This example demonstrates how to achieve automatic auto-completion of argparse arguments for a command-line utility |
| 7 | +(CLU) in the Bash shell. |
| 8 | +
|
| 9 | +Realistically it will probably only work on Linux and then only in a Bash shell. With some effort you can probably get |
| 10 | +it to work on macOS or Windows Subsystem for Linux (WSL); but then again, specifically within a Bash shell. This |
| 11 | +automatic Bash completion integration with the argcomplete module is included within cmd2 in order to assist developers |
| 12 | +with providing a the best possible out-of-the-box experience with their cmd2 applications, which in many cases will |
| 13 | +accept argparse arguments on the command-line when executed. But from an architectural point of view, the |
| 14 | +"argcomplete_bridge" functionality within cmd2 doesn't really depend on the rest of cmd2 and could be used in your own |
| 15 | +CLU which doesn't use cmd2. |
| 16 | +
|
| 17 | +WARNING: For this example to work correctly you need the argcomplete module installed and activated: |
| 18 | + pip install argcomplete |
| 19 | + activate-global-python-argcomplete |
| 20 | +Please see https://github.com/kislyuk/argcomplete for more information on argcomplete. |
| 21 | +""" |
| 22 | +import argparse |
| 23 | + |
| 24 | +optional_strs = ['Apple', 'Banana', 'Cranberry', 'Durian', 'Elderberry'] |
| 25 | + |
| 26 | +bash_parser = argparse.ArgumentParser(prog='base') |
| 27 | + |
| 28 | +bash_parser.add_argument('option', choices=['load', 'export', 'reload']) |
| 29 | + |
| 30 | +bash_parser.add_argument('-u', '--user', help='User name') |
| 31 | +bash_parser.add_argument('-p', '--passwd', help='Password') |
| 32 | + |
| 33 | +input_file = bash_parser.add_argument('-f', '--file', type=str, help='Input File') |
| 34 | + |
| 35 | +if __name__ == '__main__': |
| 36 | + from cmd2.argcomplete_bridge import bash_complete |
| 37 | + # bash_complete flags this argument telling AutoCompleter to yield to bash to perform |
| 38 | + # tab completion of a file path |
| 39 | + bash_complete(input_file) |
| 40 | + |
| 41 | +flag_opt = bash_parser.add_argument('-o', '--optional', help='Optional flag with choices') |
| 42 | +setattr(flag_opt, 'arg_choices', optional_strs) |
| 43 | + |
| 44 | +# Handle bash completion if it's installed |
| 45 | +# This early check allows the script to bail out early to provide tab-completion results |
| 46 | +# to the argcomplete library. Putting this at the end of the file would cause the full application |
| 47 | +# to load fulfill every tab-completion request coming from bash. This can cause a notable delay |
| 48 | +# on the bash prompt. |
| 49 | +try: |
| 50 | + # only move forward if we can import CompletionFinder and AutoCompleter |
| 51 | + from cmd2.argcomplete_bridge import CompletionFinder |
| 52 | + from cmd2.argparse_completer import AutoCompleter |
| 53 | + import sys |
| 54 | + if __name__ == '__main__': |
| 55 | + completer = CompletionFinder() |
| 56 | + |
| 57 | + # completer will return results to argcomplete and exit the script |
| 58 | + completer(bash_parser, AutoCompleter(bash_parser)) |
| 59 | +except ImportError: |
| 60 | + pass |
| 61 | + |
| 62 | +# Intentionally below the bash completion code to reduce tab completion lag |
| 63 | +import cmd2 |
| 64 | + |
| 65 | + |
| 66 | +class DummyApp(cmd2.Cmd): |
| 67 | + """ |
| 68 | + Dummy cmd2 app |
| 69 | + """ |
| 70 | + |
| 71 | + def __init__(self): |
| 72 | + super().__init__() |
| 73 | + |
| 74 | + |
| 75 | +if __name__ == '__main__': |
| 76 | + args = bash_parser.parse_args() |
| 77 | + |
| 78 | + # demonstrates some handling of the command line parameters |
| 79 | + |
| 80 | + if args.user is None: |
| 81 | + user = input('Username: ') |
| 82 | + else: |
| 83 | + user = args.user |
| 84 | + |
| 85 | + if args.passwd is None: |
| 86 | + import getpass |
| 87 | + password = getpass.getpass() |
| 88 | + else: |
| 89 | + password = args.passwd |
| 90 | + |
| 91 | + if args.file is not None: |
| 92 | + print('Loading file: {}'.format(args.file)) |
| 93 | + |
| 94 | + # Clear the argumentns so cmd2 doesn't try to parse them |
| 95 | + sys.argv = sys.argv[:1] |
| 96 | + |
| 97 | + app = DummyApp() |
| 98 | + app.cmdloop() |
0 commit comments