-
Notifications
You must be signed in to change notification settings - Fork 124
Copied and reduced the tab_autocompletion example to specifically exe… #499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
#!/usr/bin/env python3 | ||
# coding=utf-8 | ||
""" | ||
A example usage of AutoCompleter with delayed initialization of the argparse object | ||
|
||
Copyright 2018 Eric Lin <anselor@gmail.com> | ||
Released under MIT license, see LICENSE file | ||
""" | ||
import argparse | ||
import itertools | ||
from typing import List | ||
|
||
import cmd2 | ||
from cmd2 import argparse_completer | ||
|
||
actors = ['Mark Hamill', 'Harrison Ford', 'Carrie Fisher', 'Alec Guinness', 'Peter Mayhew', | ||
'Anthony Daniels', 'Adam Driver', 'Daisy Ridley', 'John Boyega', 'Oscar Isaac', | ||
'Lupita Nyong\'o', 'Andy Serkis', 'Liam Neeson', 'Ewan McGregor', 'Natalie Portman', | ||
'Jake Lloyd', 'Hayden Christensen', 'Christopher Lee'] | ||
|
||
|
||
def query_actors() -> List[str]: | ||
"""Simulating a function that queries and returns a completion values""" | ||
return actors | ||
|
||
|
||
class TabCompleteExample(cmd2.Cmd): | ||
""" Example cmd2 application where we a base command which has a couple subcommands.""" | ||
|
||
CAT_AUTOCOMPLETE = 'AutoComplete Examples' | ||
|
||
def __init__(self): | ||
super().__init__() | ||
|
||
video_types_subparsers = TabCompleteExample.video_parser.add_subparsers(title='Media Types', dest='type') | ||
|
||
vid_movies_parser = argparse_completer.ACArgumentParser(prog='movies') | ||
vid_movies_parser.set_defaults(func=TabCompleteExample._do_vid_media_movies) | ||
|
||
vid_movies_commands_subparsers = vid_movies_parser.add_subparsers(title='Commands', dest='command') | ||
|
||
vid_movies_list_parser = vid_movies_commands_subparsers.add_parser('list') | ||
|
||
vid_movies_list_parser.add_argument('-t', '--title', help='Title Filter') | ||
vid_movies_list_parser.add_argument('-r', '--rating', help='Rating Filter', nargs='+', | ||
choices=TabCompleteExample.ratings_types) | ||
# save a reference to the action object | ||
director_action = vid_movies_list_parser.add_argument('-d', '--director', help='Director Filter') | ||
actor_action = vid_movies_list_parser.add_argument('-a', '--actor', help='Actor Filter', action='append') | ||
|
||
# tag the action objects with completion providers. This can be a collection or a callable | ||
setattr(director_action, argparse_completer.ACTION_ARG_CHOICES, TabCompleteExample.static_list_directors) | ||
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, query_actors) | ||
|
||
vid_movies_add_parser = vid_movies_commands_subparsers.add_parser('add') | ||
vid_movies_add_parser.add_argument('title', help='Movie Title') | ||
vid_movies_add_parser.add_argument('rating', help='Movie Rating', choices=TabCompleteExample.ratings_types) | ||
|
||
# save a reference to the action object | ||
director_action = vid_movies_add_parser.add_argument('-d', '--director', help='Director', nargs=(1, 2), | ||
required=True) | ||
actor_action = vid_movies_add_parser.add_argument('actor', help='Actors', nargs='*') | ||
|
||
vid_movies_load_parser = vid_movies_commands_subparsers.add_parser('load') | ||
vid_movie_file_action = vid_movies_load_parser.add_argument('movie_file', help='Movie database') | ||
|
||
vid_movies_read_parser = vid_movies_commands_subparsers.add_parser('read') | ||
vid_movie_fread_action = vid_movies_read_parser.add_argument('movie_file', help='Movie database') | ||
|
||
# tag the action objects with completion providers. This can be a collection or a callable | ||
setattr(director_action, argparse_completer.ACTION_ARG_CHOICES, TabCompleteExample.static_list_directors) | ||
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, 'instance_query_actors') | ||
|
||
# tag the file property with a custom completion function 'delimeter_complete' provided by cmd2. | ||
setattr(vid_movie_file_action, argparse_completer.ACTION_ARG_CHOICES, | ||
('delimiter_complete', | ||
{'delimiter': '/', | ||
'match_against': TabCompleteExample.file_list})) | ||
setattr(vid_movie_fread_action, argparse_completer.ACTION_ARG_CHOICES, | ||
('path_complete', [False, False])) | ||
|
||
vid_movies_delete_parser = vid_movies_commands_subparsers.add_parser('delete') | ||
vid_delete_movie_id = vid_movies_delete_parser.add_argument('movie_id', help='Movie ID') | ||
setattr(vid_delete_movie_id, argparse_completer.ACTION_ARG_CHOICES, TabCompleteExample.instance_query_movie_ids) | ||
setattr(vid_delete_movie_id, argparse_completer.ACTION_DESCRIPTIVE_COMPLETION_HEADER, 'Title') | ||
|
||
# Add the 'movies' parser as a parent of sub-parser | ||
video_types_subparsers.add_parser('movies', parents=[vid_movies_parser], add_help=False) | ||
|
||
|
||
|
||
vid_shows_parser = argparse_completer.ACArgumentParser(prog='shows') | ||
vid_shows_parser.set_defaults(func=TabCompleteExample._do_vid_media_shows) | ||
|
||
vid_shows_commands_subparsers = vid_shows_parser.add_subparsers(title='Commands', dest='command') | ||
|
||
vid_shows_list_parser = vid_shows_commands_subparsers.add_parser('list') | ||
|
||
video_types_subparsers.add_parser('shows', parents=[vid_shows_parser], add_help=False) | ||
|
||
|
||
# For mocking a data source for the example commands | ||
ratings_types = ['G', 'PG', 'PG-13', 'R', 'NC-17'] | ||
show_ratings = ['TV-Y', 'TV-Y7', 'TV-G', 'TV-PG', 'TV-14', 'TV-MA'] | ||
static_list_directors = ['J. J. Abrams', 'Irvin Kershner', 'George Lucas', 'Richard Marquand', | ||
'Rian Johnson', 'Gareth Edwards'] | ||
USER_MOVIE_LIBRARY = ['ROGUE1', 'SW_EP04', 'SW_EP05'] | ||
MOVIE_DATABASE_IDS = ['SW_EP1', 'SW_EP02', 'SW_EP03', 'ROGUE1', 'SW_EP04', | ||
'SW_EP05', 'SW_EP06', 'SW_EP07', 'SW_EP08', 'SW_EP09'] | ||
MOVIE_DATABASE = {'SW_EP04': {'title': 'Star Wars: Episode IV - A New Hope', | ||
'rating': 'PG', | ||
'director': ['George Lucas'], | ||
'actor': ['Mark Hamill', 'Harrison Ford', 'Carrie Fisher', | ||
'Alec Guinness', 'Peter Mayhew', 'Anthony Daniels'] | ||
}, | ||
'SW_EP05': {'title': 'Star Wars: Episode V - The Empire Strikes Back', | ||
'rating': 'PG', | ||
'director': ['Irvin Kershner'], | ||
'actor': ['Mark Hamill', 'Harrison Ford', 'Carrie Fisher', | ||
'Alec Guinness', 'Peter Mayhew', 'Anthony Daniels'] | ||
}, | ||
'SW_EP06': {'title': 'Star Wars: Episode VI - Return of the Jedi', | ||
'rating': 'PG', | ||
'director': ['Richard Marquand'], | ||
'actor': ['Mark Hamill', 'Harrison Ford', 'Carrie Fisher', | ||
'Alec Guinness', 'Peter Mayhew', 'Anthony Daniels'] | ||
}, | ||
'SW_EP1': {'title': 'Star Wars: Episode I - The Phantom Menace', | ||
'rating': 'PG', | ||
'director': ['George Lucas'], | ||
'actor': ['Liam Neeson', 'Ewan McGregor', 'Natalie Portman', 'Jake Lloyd'] | ||
}, | ||
'SW_EP02': {'title': 'Star Wars: Episode II - Attack of the Clones', | ||
'rating': 'PG', | ||
'director': ['George Lucas'], | ||
'actor': ['Liam Neeson', 'Ewan McGregor', 'Natalie Portman', | ||
'Hayden Christensen', 'Christopher Lee'] | ||
}, | ||
'SW_EP03': {'title': 'Star Wars: Episode III - Revenge of the Sith', | ||
'rating': 'PG-13', | ||
'director': ['George Lucas'], | ||
'actor': ['Liam Neeson', 'Ewan McGregor', 'Natalie Portman', | ||
'Hayden Christensen'] | ||
}, | ||
|
||
} | ||
USER_SHOW_LIBRARY = {'SW_REB': ['S01E01', 'S02E02']} | ||
SHOW_DATABASE_IDS = ['SW_CW', 'SW_TCW', 'SW_REB'] | ||
SHOW_DATABASE = {'SW_CW': {'title': 'Star Wars: Clone Wars', | ||
'rating': 'TV-Y7', | ||
'seasons': {1: ['S01E01', 'S01E02', 'S01E03'], | ||
2: ['S02E01', 'S02E02', 'S02E03']} | ||
}, | ||
'SW_TCW': {'title': 'Star Wars: The Clone Wars', | ||
'rating': 'TV-PG', | ||
'seasons': {1: ['S01E01', 'S01E02', 'S01E03'], | ||
2: ['S02E01', 'S02E02', 'S02E03']} | ||
}, | ||
'SW_REB': {'title': 'Star Wars: Rebels', | ||
'rating': 'TV-Y7', | ||
'seasons': {1: ['S01E01', 'S01E02', 'S01E03'], | ||
2: ['S02E01', 'S02E02', 'S02E03']} | ||
}, | ||
} | ||
|
||
file_list = \ | ||
[ | ||
'/home/user/file.db', | ||
'/home/user/file space.db', | ||
'/home/user/another.db', | ||
'/home/other user/maps.db', | ||
'/home/other user/tests.db' | ||
] | ||
|
||
def instance_query_actors(self) -> List[str]: | ||
"""Simulating a function that queries and returns a completion values""" | ||
return actors | ||
|
||
def instance_query_movie_ids(self) -> List[str]: | ||
"""Demonstrates showing tabular hinting of tab completion information""" | ||
completions_with_desc = [] | ||
|
||
for movie_id in self.MOVIE_DATABASE_IDS: | ||
if movie_id in self.MOVIE_DATABASE: | ||
movie_entry = self.MOVIE_DATABASE[movie_id] | ||
completions_with_desc.append(argparse_completer.CompletionItem(movie_id, movie_entry['title'])) | ||
|
||
return completions_with_desc | ||
|
||
|
||
################################################################################### | ||
# The media command demonstrates a completer with multiple layers of subcommands | ||
# - This example demonstrates how to tag a completion attribute on each action, enabling argument | ||
# completion without implementing a complete_COMMAND function | ||
|
||
def _do_vid_media_movies(self, args) -> None: | ||
if not args.command: | ||
self.do_help('video movies') | ||
elif args.command == 'list': | ||
for movie_id in TabCompleteExample.MOVIE_DATABASE: | ||
movie = TabCompleteExample.MOVIE_DATABASE[movie_id] | ||
print('{}\n-----------------------------\n{} ID: {}\nDirector: {}\nCast:\n {}\n\n' | ||
.format(movie['title'], movie['rating'], movie_id, | ||
', '.join(movie['director']), | ||
'\n '.join(movie['actor']))) | ||
|
||
def _do_vid_media_shows(self, args) -> None: | ||
if not args.command: | ||
self.do_help('video shows') | ||
|
||
elif args.command == 'list': | ||
for show_id in TabCompleteExample.SHOW_DATABASE: | ||
show = TabCompleteExample.SHOW_DATABASE[show_id] | ||
print('{}\n-----------------------------\n{} ID: {}' | ||
.format(show['title'], show['rating'], show_id)) | ||
for season in show['seasons']: | ||
ep_list = show['seasons'][season] | ||
print(' Season {}:\n {}' | ||
.format(season, | ||
'\n '.join(ep_list))) | ||
print() | ||
|
||
video_parser = argparse_completer.ACArgumentParser(prog='video') | ||
|
||
@cmd2.with_category(CAT_AUTOCOMPLETE) | ||
@cmd2.with_argparser(video_parser) | ||
def do_video(self, args): | ||
"""Video management command demonstrates multiple layers of subcommands being handled by AutoCompleter""" | ||
func = getattr(args, 'func', None) | ||
if func is not None: | ||
# Call whatever subcommand function was selected | ||
func(self, args) | ||
else: | ||
# No subcommand was provided, so call help | ||
self.do_help('video') | ||
|
||
|
||
if __name__ == '__main__': | ||
app = TabCompleteExample() | ||
app.cmdloop() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this relevant example