summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/.cmd2rc4
-rwxr-xr-xexamples/alias_startup.py4
-rwxr-xr-xexamples/arg_print.py7
-rwxr-xr-xexamples/async_printing.py203
-rwxr-xr-xexamples/colors.py142
-rwxr-xr-x[-rw-r--r--]examples/hooks.py10
-rwxr-xr-xexamples/pirate.py20
-rwxr-xr-xexamples/plumbum_colors.py144
-rwxr-xr-xexamples/python_scripting.py14
-rwxr-xr-xexamples/subcommands.py38
-rwxr-xr-xexamples/table_display.py4
-rw-r--r--examples/transcripts/exampleSession.txt4
-rw-r--r--examples/transcripts/transcript_regex.txt4
13 files changed, 572 insertions, 26 deletions
diff --git a/examples/.cmd2rc b/examples/.cmd2rc
index 4ffedab9..cedcbe20 100644
--- a/examples/.cmd2rc
+++ b/examples/.cmd2rc
@@ -1,2 +1,2 @@
-alias ls !ls -hal
-alias pwd !pwd
+alias create ls !ls -hal
+alias create pwd !pwd
diff --git a/examples/alias_startup.py b/examples/alias_startup.py
index 4ae91661..8a289e79 100755
--- a/examples/alias_startup.py
+++ b/examples/alias_startup.py
@@ -14,6 +14,10 @@ class AliasAndStartup(cmd2.Cmd):
alias_script = os.path.join(os.path.dirname(__file__), '.cmd2rc')
super().__init__(startup_script=alias_script)
+ def do_nothing(self, args):
+ """This command does nothing and produces no output."""
+ pass
+
if __name__ == '__main__':
app = AliasAndStartup()
diff --git a/examples/arg_print.py b/examples/arg_print.py
index 4f0ca709..f2168126 100755
--- a/examples/arg_print.py
+++ b/examples/arg_print.py
@@ -2,13 +2,12 @@
# coding=utf-8
"""A simple example demonstrating the following:
1) How arguments and options get parsed and passed to commands
- 2) How to change what syntax get parsed as a comment and stripped from
- the arguments
+ 2) How to change what syntax gets parsed as a comment and stripped from the arguments
This is intended to serve as a live demonstration so that developers can
experiment with and understand how command and argument parsing work.
-It also serves as an example of how to create command aliases (shortcuts).
+It also serves as an example of how to create shortcuts.
"""
import argparse
@@ -18,7 +17,7 @@ class ArgumentAndOptionPrinter(cmd2.Cmd):
""" Example cmd2 application where we create commands that just print the arguments they are called with."""
def __init__(self):
- # Create command aliases which are shorter
+ # Create command shortcuts which are typically 1 character abbreviations which can be used in place of a command
self.shortcuts.update({'$': 'aprint', '%': 'oprint'})
# Make sure to call this super class __init__ *after* setting and/or updating shortcuts
diff --git a/examples/async_printing.py b/examples/async_printing.py
new file mode 100755
index 00000000..a4165ae8
--- /dev/null
+++ b/examples/async_printing.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+A simple example demonstrating an application that asynchronously prints alerts, updates the prompt
+and changes the window title
+"""
+
+import random
+import threading
+import time
+from typing import List
+
+from colorama import Fore
+
+import cmd2
+
+ALERTS = ["Watch as this application prints alerts and updates the prompt",
+ "This will only happen when the prompt is present",
+ "Notice how it doesn't interfere with your typing or cursor location",
+ "Go ahead and type some stuff and move the cursor throughout the line",
+ "Keep typing...",
+ "Move that cursor...",
+ "Pretty seamless, eh?",
+ "Feedback can also be given in the window title. Notice the arg count up there?",
+ "You can stop and start the alerts by typing stop_alerts and start_alerts",
+ "This demo will now continue to print alerts at random intervals"
+ ]
+
+
+class AlerterApp(cmd2.Cmd):
+ """ An app that shows off async_alert() and async_update_prompt() """
+
+ def __init__(self, *args, **kwargs) -> None:
+ """ Initializer """
+
+ super().__init__(*args, **kwargs)
+
+ self.prompt = "(APR)> "
+
+ # The thread that will asynchronously alert the user of events
+ self._stop_thread = False
+ self._alerter_thread = threading.Thread()
+ self._alert_count = 0
+ self._next_alert_time = 0
+
+ # Create some hooks to handle the starting and stopping of our thread
+ self.register_preloop_hook(self._preloop_hook)
+ self.register_postloop_hook(self._postloop_hook)
+
+ def _preloop_hook(self) -> None:
+ """ Start the alerter thread """
+ # This runs after cmdloop() acquires self.terminal_lock, which will be locked until the prompt appears.
+ # Therefore this is the best place to start the alerter thread since there is no risk of it alerting
+ # before the prompt is displayed. You can also start it via a command if its not something that should
+ # be running during the entire application. See do_start_alerts().
+ self._stop_thread = False
+
+ self._alerter_thread = threading.Thread(name='alerter', target=self._alerter_thread_func)
+ self._alerter_thread.start()
+
+ def _postloop_hook(self) -> None:
+ """ Stops the alerter thread """
+
+ # After this function returns, cmdloop() releases self.terminal_lock which could make the alerter
+ # thread think the prompt is on screen. Therefore this is the best place to stop the alerter thread.
+ # You can also stop it via a command. See do_stop_alerts().
+ self._stop_thread = True
+ if self._alerter_thread.is_alive():
+ self._alerter_thread.join()
+
+ def do_start_alerts(self, _):
+ """ Starts the alerter thread """
+ if self._alerter_thread.is_alive():
+ print("The alert thread is already started")
+ else:
+ self._stop_thread = False
+ self._alerter_thread = threading.Thread(name='alerter', target=self._alerter_thread_func)
+ self._alerter_thread.start()
+
+ def do_stop_alerts(self, _):
+ """ Stops the alerter thread """
+ self._stop_thread = True
+ if self._alerter_thread.is_alive():
+ self._alerter_thread.join()
+ else:
+ print("The alert thread is already stopped")
+
+ def _get_alerts(self) -> List[str]:
+ """
+ Reports alerts
+ :return: the list of alerts
+ """
+ global ALERTS
+
+ cur_time = time.monotonic()
+ if cur_time < self._next_alert_time:
+ return []
+
+ alerts = []
+
+ if self._alert_count < len(ALERTS):
+ alerts.append(ALERTS[self._alert_count])
+ self._alert_count += 1
+ self._next_alert_time = cur_time + 4
+
+ else:
+ rand_num = random.randint(1, 20)
+ if rand_num > 2:
+ return []
+
+ for i in range(0, rand_num):
+ self._alert_count += 1
+ alerts.append("Alert {}".format(self._alert_count))
+
+ self._next_alert_time = 0
+
+ return alerts
+
+ def _generate_alert_str(self) -> str:
+ """
+ Combines alerts into one string that can be printed to the terminal
+ :return: the alert string
+ """
+ global ALERTS
+
+ alert_str = ''
+ alerts = self._get_alerts()
+
+ longest_alert = max(ALERTS, key=len)
+ num_astericks = len(longest_alert) + 8
+
+ for i, cur_alert in enumerate(alerts):
+ # Use padding to center the alert
+ padding = ' ' * int((num_astericks - len(cur_alert)) / 2)
+
+ if i > 0:
+ alert_str += '\n'
+ alert_str += '*' * num_astericks + '\n'
+ alert_str += padding + cur_alert + padding + '\n'
+ alert_str += '*' * num_astericks + '\n'
+
+ return alert_str
+
+ def _generate_colored_prompt(self) -> str:
+ """
+ Randomly generates a colored the prompt
+ :return: the new prompt
+ """
+ rand_num = random.randint(1, 20)
+
+ status_color = Fore.RESET
+
+ if rand_num == 1:
+ status_color = Fore.LIGHTRED_EX
+ elif rand_num == 2:
+ status_color = Fore.LIGHTYELLOW_EX
+ elif rand_num == 3:
+ status_color = Fore.CYAN
+ elif rand_num == 4:
+ status_color = Fore.LIGHTGREEN_EX
+ elif rand_num == 5:
+ status_color = Fore.LIGHTBLUE_EX
+
+ return status_color + self.visible_prompt + Fore.RESET
+
+ def _alerter_thread_func(self) -> None:
+ """ Prints alerts and updates the prompt any time the prompt is showing """
+
+ self._alert_count = 0
+ self._next_alert_time = 0
+
+ while not self._stop_thread:
+ # Always acquire terminal_lock before printing alerts or updating the prompt
+ # To keep the app responsive, do not block on this call
+ if self.terminal_lock.acquire(blocking=False):
+
+ # Get any alerts that need to be printed
+ alert_str = self._generate_alert_str()
+
+ # Generate a new prompt
+ new_prompt = self._generate_colored_prompt()
+
+ # Check if we have alerts to print
+ if alert_str:
+ # new_prompt is an optional parameter to async_alert()
+ self.async_alert(alert_str, new_prompt)
+ new_title = "Alerts Printed: {}".format(self._alert_count)
+ self.set_window_title(new_title)
+
+ # No alerts needed to be printed, check if the prompt changed
+ elif new_prompt != self.prompt:
+ self.async_update_prompt(new_prompt)
+
+ # Don't forget to release the lock
+ self.terminal_lock.release()
+
+ time.sleep(0.5)
+
+
+if __name__ == '__main__':
+ app = AlerterApp()
+ app.set_window_title("Asynchronous Printer Test")
+ app.cmdloop()
diff --git a/examples/colors.py b/examples/colors.py
new file mode 100755
index 00000000..8765aee0
--- /dev/null
+++ b/examples/colors.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+A sample application for cmd2. Demonstrating colorized output.
+
+Experiment with the command line options on the `speak` command to see how
+different output colors ca
+
+The colors setting has three possible values:
+
+Never
+ poutput() and pfeedback() strip all ANSI escape sequences
+ which instruct the terminal to colorize output
+
+Terminal
+ (the default value) poutput() and pfeedback() do not strip any ANSI escape
+ sequences when the output is a terminal, but if the output is a pipe or a
+ file the escape sequences are stripped. If you want colorized output you
+ must add ANSI escape sequences, preferably using some python color library
+ like `plumbum.colors`, `colorama`, `blessings`, or `termcolor`.
+
+Always
+ poutput() and pfeedback() never strip ANSI escape sequences, regardless of
+ the output destination
+"""
+
+import random
+import argparse
+
+import cmd2
+from colorama import Fore, Back
+
+FG_COLORS = {
+ 'black': Fore.BLACK,
+ 'red': Fore.RED,
+ 'green': Fore.GREEN,
+ 'yellow': Fore.YELLOW,
+ 'blue': Fore.BLUE,
+ 'magenta': Fore.MAGENTA,
+ 'cyan': Fore.CYAN,
+ 'white': Fore.WHITE,
+}
+BG_COLORS = {
+ 'black': Back.BLACK,
+ 'red': Back.RED,
+ 'green': Back.GREEN,
+ 'yellow': Back.YELLOW,
+ 'blue': Back.BLUE,
+ 'magenta': Back.MAGENTA,
+ 'cyan': Back.CYAN,
+ 'white': Back.WHITE,
+}
+
+
+class CmdLineApp(cmd2.Cmd):
+ """Example cmd2 application demonstrating colorized output."""
+
+ # Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist
+ # default_to_shell = True
+ MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh']
+ MUMBLE_FIRST = ['so', 'like', 'well']
+ MUMBLE_LAST = ['right?']
+
+ def __init__(self):
+ self.multiline_commands = ['orate']
+ self.maxrepeats = 3
+
+ # Add stuff to settable and shortcuts before calling base class initializer
+ self.settable['maxrepeats'] = 'max repetitions for speak command'
+ self.shortcuts.update({'&': 'speak'})
+
+ # Set use_ipython to True to enable the "ipy" command which embeds and interactive IPython shell
+ super().__init__(use_ipython=True)
+
+ speak_parser = argparse.ArgumentParser()
+ speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ speak_parser.add_argument('-f', '--fg', choices=FG_COLORS, help='foreground color to apply to output')
+ speak_parser.add_argument('-b', '--bg', choices=BG_COLORS, help='background color to apply to output')
+ speak_parser.add_argument('words', nargs='+', help='words to say')
+
+ @cmd2.with_argparser(speak_parser)
+ def do_speak(self, args):
+ """Repeats what you tell me to."""
+ words = []
+ for word in args.words:
+ if args.piglatin:
+ word = '%s%say' % (word[1:], word[0])
+ if args.shout:
+ word = word.upper()
+ words.append(word)
+
+ repetitions = args.repeat or 1
+
+ color_on = ''
+ if args.fg:
+ color_on += FG_COLORS[args.fg]
+ if args.bg:
+ color_on += BG_COLORS[args.bg]
+ color_off = Fore.RESET + Back.RESET
+
+ for i in range(min(repetitions, self.maxrepeats)):
+ # .poutput handles newlines, and accommodates output redirection too
+ self.poutput(color_on + ' '.join(words) + color_off)
+
+ do_say = do_speak # now "say" is a synonym for "speak"
+ do_orate = do_speak # another synonym, but this one takes multi-line input
+
+ mumble_parser = argparse.ArgumentParser()
+ mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
+ mumble_parser.add_argument('-f', '--fg', help='foreground color to apply to output')
+ mumble_parser.add_argument('-b', '--bg', help='background color to apply to output')
+ mumble_parser.add_argument('words', nargs='+', help='words to say')
+
+ @cmd2.with_argparser(mumble_parser)
+ def do_mumble(self, args):
+ """Mumbles what you tell me to."""
+ color_on = ''
+ if args.fg and args.fg in FG_COLORS:
+ color_on += FG_COLORS[args.fg]
+ if args.bg and args.bg in BG_COLORS:
+ color_on += BG_COLORS[args.bg]
+ color_off = Fore.RESET + Back.RESET
+
+ repetitions = args.repeat or 1
+ for i in range(min(repetitions, self.maxrepeats)):
+ output = []
+ if random.random() < .33:
+ output.append(random.choice(self.MUMBLE_FIRST))
+ for word in args.words:
+ if random.random() < .40:
+ output.append(random.choice(self.MUMBLES))
+ output.append(word)
+ if random.random() < .25:
+ output.append(random.choice(self.MUMBLE_LAST))
+ self.poutput(color_on + ' '.join(output) + color_off)
+
+
+if __name__ == '__main__':
+ c = CmdLineApp()
+ c.cmdloop()
diff --git a/examples/hooks.py b/examples/hooks.py
index 3d11457a..b6f6263e 100644..100755
--- a/examples/hooks.py
+++ b/examples/hooks.py
@@ -84,12 +84,12 @@ class CmdLineApp(cmd2.Cmd):
def abbrev_hook(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
"""Accept unique abbreviated commands"""
- target = 'do_' + data.statement.command
- if target not in dir(self):
+ func = self.cmd_func(data.statement.command)
+ if func is None:
# check if the entered command might be an abbreviation
- funcs = [func for func in self.keywords if func.startswith(data.statement.command)]
- if len(funcs) == 1:
- raw = data.statement.raw.replace(data.statement.command, funcs[0], 1)
+ possible_cmds = [cmd for cmd in self.keywords if cmd.startswith(data.statement.command)]
+ if len(possible_cmds) == 1:
+ raw = data.statement.raw.replace(data.statement.command, possible_cmds[0], 1)
data.statement = self.statement_parser.parse(raw)
return data
diff --git a/examples/pirate.py b/examples/pirate.py
index 34906a9f..22274dbf 100755
--- a/examples/pirate.py
+++ b/examples/pirate.py
@@ -8,8 +8,21 @@ It demonstrates many features of cmd2.
"""
import argparse
+from colorama import Fore
+
import cmd2
+COLORS = {
+ 'black': Fore.BLACK,
+ 'red': Fore.RED,
+ 'green': Fore.GREEN,
+ 'yellow': Fore.YELLOW,
+ 'blue': Fore.BLUE,
+ 'magenta': Fore.MAGENTA,
+ 'cyan': Fore.CYAN,
+ 'white': Fore.WHITE,
+}
+
class Pirate(cmd2.Cmd):
"""A piratical example cmd2 application involving looting and drinking."""
@@ -17,10 +30,10 @@ class Pirate(cmd2.Cmd):
self.default_to_shell = True
self.multiline_commands = ['sing']
self.terminators = self.terminators + ['...']
- self.songcolor = 'blue'
+ self.songcolor = Fore.BLUE
# Add stuff to settable and/or shortcuts before calling base class initializer
- self.settable['songcolor'] = 'Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)'
+ self.settable['songcolor'] = 'Color to ``sing`` in (black/red/green/yellow/blue/magenta/cyan/white)'
self.shortcuts.update({'~': 'sing'})
"""Initialize the base class as well as this one"""
@@ -68,7 +81,8 @@ class Pirate(cmd2.Cmd):
def do_sing(self, arg):
"""Sing a colorful song."""
- self.poutput(self.colorize(arg, self.songcolor))
+ color_escape = COLORS.get(self.songcolor, default=Fore.RESET)
+ self.poutput(arg, color=color_escape)
yo_parser = argparse.ArgumentParser()
yo_parser.add_argument('--ho', type=int, default=2, help="How often to chant 'ho'")
diff --git a/examples/plumbum_colors.py b/examples/plumbum_colors.py
new file mode 100755
index 00000000..942eaf80
--- /dev/null
+++ b/examples/plumbum_colors.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+A sample application for cmd2. Demonstrating colorized output using the plumbum package.
+
+Experiment with the command line options on the `speak` command to see how
+different output colors ca
+
+The colors setting has three possible values:
+
+Never
+ poutput() and pfeedback() strip all ANSI escape sequences
+ which instruct the terminal to colorize output
+
+Terminal
+ (the default value) poutput() and pfeedback() do not strip any ANSI escape
+ sequences when the output is a terminal, but if the output is a pipe or a
+ file the escape sequences are stripped. If you want colorized output you
+ must add ANSI escape sequences, preferably using some python color library
+ like `plumbum.colors`, `colorama`, `blessings`, or `termcolor`.
+
+Always
+ poutput() and pfeedback() never strip ANSI escape sequences, regardless of
+ the output destination
+
+WARNING: This example requires the plumbum package, which isn't normally required by cmd2.
+"""
+
+import random
+import argparse
+
+import cmd2
+from plumbum.colors import fg, bg, reset
+
+FG_COLORS = {
+ 'black': fg.Black,
+ 'red': fg.DarkRedA,
+ 'green': fg.MediumSpringGreen,
+ 'yellow': fg.LightYellow,
+ 'blue': fg.RoyalBlue1,
+ 'magenta': fg.Purple,
+ 'cyan': fg.SkyBlue1,
+ 'white': fg.White,
+}
+BG_COLORS = {
+ 'black': bg.BLACK,
+ 'red': bg.DarkRedA,
+ 'green': bg.MediumSpringGreen,
+ 'yellow': bg.LightYellow,
+ 'blue': bg.RoyalBlue1,
+ 'magenta': bg.Purple,
+ 'cyan': bg.SkyBlue1,
+ 'white': bg.White,
+}
+
+
+class CmdLineApp(cmd2.Cmd):
+ """Example cmd2 application demonstrating colorized output."""
+
+ # Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist
+ # default_to_shell = True
+ MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh']
+ MUMBLE_FIRST = ['so', 'like', 'well']
+ MUMBLE_LAST = ['right?']
+
+ def __init__(self):
+ self.multiline_commands = ['orate']
+ self.maxrepeats = 3
+
+ # Add stuff to settable and shortcuts before calling base class initializer
+ self.settable['maxrepeats'] = 'max repetitions for speak command'
+ self.shortcuts.update({'&': 'speak'})
+
+ # Set use_ipython to True to enable the "ipy" command which embeds and interactive IPython shell
+ super().__init__(use_ipython=True)
+
+ speak_parser = argparse.ArgumentParser()
+ speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ speak_parser.add_argument('-f', '--fg', choices=FG_COLORS, help='foreground color to apply to output')
+ speak_parser.add_argument('-b', '--bg', choices=BG_COLORS, help='background color to apply to output')
+ speak_parser.add_argument('words', nargs='+', help='words to say')
+
+ @cmd2.with_argparser(speak_parser)
+ def do_speak(self, args):
+ """Repeats what you tell me to."""
+ words = []
+ for word in args.words:
+ if args.piglatin:
+ word = '%s%say' % (word[1:], word[0])
+ if args.shout:
+ word = word.upper()
+ words.append(word)
+
+ repetitions = args.repeat or 1
+
+ color_on = ''
+ if args.fg:
+ color_on += FG_COLORS[args.fg]
+ if args.bg:
+ color_on += BG_COLORS[args.bg]
+ color_off = reset
+
+ for i in range(min(repetitions, self.maxrepeats)):
+ # .poutput handles newlines, and accommodates output redirection too
+ self.poutput(color_on + ' '.join(words) + color_off)
+
+ do_say = do_speak # now "say" is a synonym for "speak"
+ do_orate = do_speak # another synonym, but this one takes multi-line input
+
+ mumble_parser = argparse.ArgumentParser()
+ mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
+ mumble_parser.add_argument('-f', '--fg', help='foreground color to apply to output')
+ mumble_parser.add_argument('-b', '--bg', help='background color to apply to output')
+ mumble_parser.add_argument('words', nargs='+', help='words to say')
+
+ @cmd2.with_argparser(mumble_parser)
+ def do_mumble(self, args):
+ """Mumbles what you tell me to."""
+ color_on = ''
+ if args.fg and args.fg in FG_COLORS:
+ color_on += FG_COLORS[args.fg]
+ if args.bg and args.bg in BG_COLORS:
+ color_on += BG_COLORS[args.bg]
+ color_off = Fore.RESET + Back.RESET
+
+ repetitions = args.repeat or 1
+ for i in range(min(repetitions, self.maxrepeats)):
+ output = []
+ if random.random() < .33:
+ output.append(random.choice(self.MUMBLE_FIRST))
+ for word in args.words:
+ if random.random() < .40:
+ output.append(random.choice(self.MUMBLES))
+ output.append(word)
+ if random.random() < .25:
+ output.append(random.choice(self.MUMBLE_LAST))
+ self.poutput(color_on + ' '.join(output) + color_off)
+
+
+if __name__ == '__main__':
+ c = CmdLineApp()
+ c.cmdloop()
diff --git a/examples/python_scripting.py b/examples/python_scripting.py
index 069bcff5..0b0030a5 100755
--- a/examples/python_scripting.py
+++ b/examples/python_scripting.py
@@ -17,6 +17,8 @@ This application and the "scripts/conditional.py" script serve as an example for
import argparse
import os
+from colorama import Fore
+
import cmd2
@@ -27,20 +29,20 @@ class CmdLineApp(cmd2.Cmd):
# Enable the optional ipy command if IPython is installed by setting use_ipython=True
super().__init__(use_ipython=True)
self._set_prompt()
- self.intro = 'Happy 𝛑 Day. Note the full Unicode support: 😇 (Python 3 only) 💩'
+ self.intro = 'Happy 𝛑 Day. Note the full Unicode support: 😇 💩'
self.locals_in_py = True
def _set_prompt(self):
"""Set prompt so it displays the current working directory."""
self.cwd = os.getcwd()
- self.prompt = self.colorize('{!r} $ '.format(self.cwd), 'cyan')
+ self.prompt = Fore.CYAN + '{!r} $ '.format(self.cwd) + Fore.RESET
- def postcmd(self, stop, line):
+ def postcmd(self, stop: bool, line: str) -> bool:
"""Hook method executed just after a command dispatch is finished.
- :param stop: bool - if True, the command has indicated the application should exit
- :param line: str - the command line text for this command
- :return: bool - if this is True, the application will exit after this command and the postloop() will run
+ :param stop: if True, the command has indicated the application should exit
+ :param line: the command line text for this command
+ :return: if this is True, the application will exit after this command and the postloop() will run
"""
"""Override this so prompt always displays cwd."""
self._set_prompt()
diff --git a/examples/subcommands.py b/examples/subcommands.py
index 9d51fbee..02b06412 100755
--- a/examples/subcommands.py
+++ b/examples/subcommands.py
@@ -37,6 +37,33 @@ sport_arg = parser_sport.add_argument('sport', help='Enter name of a sport')
setattr(sport_arg, 'arg_choices', sport_item_strs)
+# create the top-level parser for the alternate command
+# The alternate command doesn't provide its own help flag
+base2_parser = argparse.ArgumentParser(prog='alternate', add_help=False)
+base2_subparsers = base2_parser.add_subparsers(title='subcommands', help='subcommand help')
+
+# create the parser for the "foo" subcommand
+parser_foo2 = base2_subparsers.add_parser('foo', help='foo help')
+parser_foo2.add_argument('-x', type=int, default=1, help='integer')
+parser_foo2.add_argument('y', type=float, help='float')
+parser_foo2.add_argument('input_file', type=str, help='Input File')
+
+# create the parser for the "bar" subcommand
+parser_bar2 = base2_subparsers.add_parser('bar', help='bar help')
+
+bar2_subparsers = parser_bar2.add_subparsers(title='layer3', help='help for 3rd layer of commands')
+parser_bar2.add_argument('z', help='string')
+
+bar2_subparsers.add_parser('apple', help='apple help')
+bar2_subparsers.add_parser('artichoke', help='artichoke help')
+bar2_subparsers.add_parser('cranberries', help='cranberries help')
+
+# create the parser for the "sport" subcommand
+parser_sport2 = base2_subparsers.add_parser('sport', help='sport help')
+sport2_arg = parser_sport2.add_argument('sport', help='Enter name of a sport')
+setattr(sport2_arg, 'arg_choices', sport_item_strs)
+
+
class SubcommandsExample(cmd2.Cmd):
"""
Example cmd2 application where we a base command which has a couple subcommands
@@ -74,6 +101,17 @@ class SubcommandsExample(cmd2.Cmd):
# No subcommand was provided, so call help
self.do_help('base')
+ @cmd2.with_argparser(base2_parser)
+ def do_alternate(self, args):
+ """Alternate command help"""
+ 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('alternate')
+
if __name__ == '__main__':
app = SubcommandsExample()
diff --git a/examples/table_display.py b/examples/table_display.py
index 75eada85..63447377 100755
--- a/examples/table_display.py
+++ b/examples/table_display.py
@@ -151,8 +151,8 @@ class TableDisplay(cmd2.Cmd):
def ptable(self, rows, columns, grid_args, row_stylist):
"""Format tabular data for pretty-printing as a fixed-width table and then display it using a pager.
- :param rows: required argument - can be a list-of-lists (or another iterable of iterables), a two-dimensional
- NumPy array, or an Iterable of non-iterable objects
+ :param rows: can be a list-of-lists (or another iterable of iterables), a two-dimensional
+ NumPy array, or an Iterable of non-iterable objects
:param columns: column headers and formatting options per column
:param grid_args: argparse arguments for formatting the grid
:param row_stylist: function to determine how each row gets styled
diff --git a/examples/transcripts/exampleSession.txt b/examples/transcripts/exampleSession.txt
index 1d1b3b79..38fb0659 100644
--- a/examples/transcripts/exampleSession.txt
+++ b/examples/transcripts/exampleSession.txt
@@ -3,13 +3,13 @@
# The regex for editor will match whatever program you use.
# regexes on prompts just make the trailing space obvious
(Cmd) set
-colors: /(True|False)/
+colors: /(Terminal|Always|Never)/
continuation_prompt: >/ /
debug: False
echo: False
editor: /.*?/
feedback_to_output: False
-locals_in_py: True
+locals_in_py: False
maxrepeats: 3
prompt: (Cmd)/ /
quiet: False
diff --git a/examples/transcripts/transcript_regex.txt b/examples/transcripts/transcript_regex.txt
index adf4d77e..6980fac6 100644
--- a/examples/transcripts/transcript_regex.txt
+++ b/examples/transcripts/transcript_regex.txt
@@ -3,13 +3,13 @@
# The regex for editor will match whatever program you use.
# regexes on prompts just make the trailing space obvious
(Cmd) set
-colors: /(True|False)/
+colors: /(Terminal|Always|Never)/
continuation_prompt: >/ /
debug: False
echo: False
editor: /.*?/
feedback_to_output: False
-locals_in_py: True
+locals_in_py: False
maxrepeats: 3
prompt: (Cmd)/ /
quiet: False