diff options
-rwxr-xr-x | cmd2.py | 43 | ||||
-rwxr-xr-x | examples/pirate.py | 16 | ||||
-rw-r--r-- | examples/transcripts/exampleSession.txt (renamed from examples/exampleSession.txt) | 0 | ||||
-rw-r--r-- | examples/transcripts/pirate.transcript | 10 | ||||
-rw-r--r-- | examples/transcripts/transcript_regex.txt (renamed from examples/transcript_regex.txt) | 0 | ||||
-rw-r--r-- | tests/conftest.py | 8 |
6 files changed, 60 insertions, 17 deletions
@@ -962,8 +962,7 @@ class Cmd(cmd.Cmd): (stop, statement) = self.postparsing_precmd(statement) if stop: return self.postparsing_postcmd(stop) - if statement.parsed.command not in self.excludeFromHistory: - self.history.append(statement.parsed.raw) + try: if self.allow_redirection: self._redirect_output(statement) @@ -1012,7 +1011,11 @@ class Cmd(cmd.Cmd): self.cmdqueue = list(cmds) + self.cmdqueue try: while self.cmdqueue and not stop: - stop = self.onecmd_plus_hooks(self.cmdqueue.pop(0)) + line = self.cmdqueue.pop(0) + if self.echo and line != 'eos': + self.poutput('{}{}'.format(self.prompt, line)) + + stop = self.onecmd_plus_hooks(line) finally: # Clear out the command queue and script directory stack, just in # case we hit an error and they were not completed. @@ -1154,6 +1157,10 @@ class Cmd(cmd.Cmd): if not funcname: return self.default(statement) + # Since we have a valid command store it in the history + if statement.parsed.command not in self.excludeFromHistory: + self.history.append(statement.parsed.raw) + try: func = getattr(self, funcname) except AttributeError: @@ -1808,8 +1815,9 @@ Paths or arguments that contain spaces must be enclosed in quotes history_parser_group.add_argument('-r', '--run', action='store_true', help='run selected history items') history_parser_group.add_argument('-e', '--edit', action='store_true', help='edit and then run selected history items') - history_parser_group.add_argument('-o', '--output-file', metavar='FILE', help='output to file') - history_parser.add_argument('-s', '--script', action='store_true', help='script format; no separation lines') + history_parser_group.add_argument('-s', '--script', action='store_true', help='script format; no separation lines') + history_parser_group.add_argument('-o', '--output-file', metavar='FILE', help='output commands to a script file') + history_parser_group.add_argument('-t', '--transcript', help='output commands and results to a transcript file') _history_arg_help = """empty all history items a one history item by number a..b, a:b, a:, ..b items by indices (inclusive) @@ -1838,7 +1846,8 @@ a..b, a:b, a:, ..b items by indices (inclusive) else: # If no arg given, then retrieve the entire history cowardly_refuse_to_run = True - history = self.history + # Get a copy of the history so it doesn't get mutated while we are using it + history = self.history[:] if args.run: if cowardly_refuse_to_run: @@ -1871,6 +1880,28 @@ a..b, a:b, a:, ..b items by indices (inclusive) self.pfeedback('{} command{} saved to {}'.format(len(history), plural, args.output_file)) except Exception as e: self.perror('Saving {!r} - {}'.format(args.output_file, e), traceback_war=False) + elif args.transcript: + # Make sure echo is on so commands print to standard out + saved_echo = self.echo + self.echo = True + + # Redirect stdout to the transcript file + saved_self_stdout = self.stdout + self.stdout = open(args.transcript, 'w') + + # Run all of the commands in the history with output redirected to transcript and echo on + self.runcmds_plus_hooks(history) + + # Restore stdout to its original state + self.stdout.close() + self.stdout = saved_self_stdout + + # Set echo back to its original state + self.echo = saved_echo + + plural = 's' if len(history) > 1 else '' + self.pfeedback('{} command{} and outputs saved to transcript file {!r}'.format(len(history), plural, + args.transcript)) else: # Display the history items retrieved for hi in history: diff --git a/examples/pirate.py b/examples/pirate.py index dd9fd98c..06fdb61b 100755 --- a/examples/pirate.py +++ b/examples/pirate.py @@ -25,13 +25,13 @@ class Pirate(Cmd): """Initialize the base class as well as this one""" Cmd.__init__(self) # prompts and defaults - self.gold = 3 + self.gold = 0 self.initial_gold = self.gold self.prompt = 'arrr> ' def default(self, line): """This handles unknown commands.""" - print('What mean ye by "{0}"?'.format(line)) + self.poutput('What mean ye by "{0}"?'.format(line)) def precmd(self, line): """Runs just before a command line is parsed, but after the prompt is presented.""" @@ -41,10 +41,10 @@ class Pirate(Cmd): def postcmd(self, stop, line): """Runs right before a command is about to return.""" if self.gold != self.initial_gold: - print('Now we gots {0} doubloons' + self.poutput('Now we gots {0} doubloons' .format(self.gold)) if self.gold < 0: - print("Off to debtorrr's prison.") + self.poutput("Off to debtorrr's prison.") stop = True return stop @@ -61,17 +61,17 @@ class Pirate(Cmd): self.gold -= int(arg) except ValueError: if arg: - print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.poutput('''What's "{0}"? I'll take rrrum.'''.format(arg)) self.gold -= 1 def do_quit(self, arg): """Quit the application gracefully.""" - print("Quiterrr!") + self.poutput("Quiterrr!") return True def do_sing(self, arg): """Sing a colorful song.""" - print(self.colorize(arg, self.songcolor)) + self.poutput(self.colorize(arg, self.songcolor)) yo_parser = argparse.ArgumentParser() yo_parser.add_argument('--ho', type=int, default=2, help="How often to chant 'ho'") @@ -84,7 +84,7 @@ class Pirate(Cmd): chant = ['yo'] + ['ho'] * args.ho separator = ', ' if args.commas else ' ' chant = separator.join(chant) - print('{0} and a bottle of {1}'.format(chant, args.beverage)) + self.poutput('{0} and a bottle of {1}'.format(chant, args.beverage)) if __name__ == '__main__': diff --git a/examples/exampleSession.txt b/examples/transcripts/exampleSession.txt index 840bee60..840bee60 100644 --- a/examples/exampleSession.txt +++ b/examples/transcripts/exampleSession.txt diff --git a/examples/transcripts/pirate.transcript b/examples/transcripts/pirate.transcript new file mode 100644 index 00000000..570f0cd7 --- /dev/null +++ b/examples/transcripts/pirate.transcript @@ -0,0 +1,10 @@ +arrr> loot +Now we gots 1 doubloons +arrr> loot +Now we gots 2 doubloons +arrr> loot +Now we gots 3 doubloons +arrr> drink 3 +Now we gots 0 doubloons +arrr> yo --ho 3 rum +yo ho ho ho and a bottle of rum diff --git a/examples/transcript_regex.txt b/examples/transcripts/transcript_regex.txt index 7d017dee..7d017dee 100644 --- a/examples/transcript_regex.txt +++ b/examples/transcripts/transcript_regex.txt diff --git a/tests/conftest.py b/tests/conftest.py index 030172a1..319e54fe 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -19,7 +19,7 @@ edit help history load py pyscript quit set shell shortcuts """ # Help text for the history command -HELP_HISTORY = """usage: history [-h] [-r | -e | -o FILE] [-s] [arg] +HELP_HISTORY = """usage: history [-h] [-r | -e | -s | -o FILE | -t TRANSCRIPT] [arg] View, run, edit, and save previously entered commands. @@ -34,9 +34,11 @@ optional arguments: -h, --help show this help message and exit -r, --run run selected history items -e, --edit edit and then run selected history items - -o FILE, --output-file FILE - output to file -s, --script script format; no separation lines + -o FILE, --output-file FILE + output commands to a script file + -t TRANSCRIPT, --transcript TRANSCRIPT + output commands and results to a transcript file """ # Output from the shortcuts command with default built-in shortcuts |