@@ -3002,45 +3002,65 @@ def do_history(self, args):
30023002 except Exception as e :
30033003 self .perror ('Saving {!r} - {}' .format (args .output_file , e ), traceback_war = False )
30043004 elif args .transcript :
3005- membuf = io .StringIO ()
3006-
3007- # Make sure echo is on so commands print to standard out
3005+ # Save the current echo state, and turn it off. We inject commands into the
3006+ # output using a different mechanism
30083007 saved_echo = self .echo
30093008 self .echo = False
30103009
30113010 # Redirect stdout to the transcript file
30123011 saved_self_stdout = self .stdout
3013- self .stdout = membuf
30143012
3015- # Run all of the commands in the history with output redirected to transcript and echo on
3013+ # The problem with supporting regular expressions in transcripts
3014+ # is that they shouldn't be processed in the command, just the output.
3015+ # In addition, when we generate a transcript, any slashes in the output
3016+ # are not really intended to indicate regular expressions, so they should
3017+ # be escaped.
3018+ #
3019+ # We have to jump through some hoops here in order to catch the commands
3020+ # separately from the output and escape the slashes in the output.
3021+ transcript = ''
30163022 for history_item in history :
3017- # write the command to the output stream
3023+ # build the command, complete with prompts. When we replay
3024+ # the transcript, it looks for the prompts to separate
3025+ # the command from the output
30183026 first = True
3027+ command = ''
30193028 for line in history_item .splitlines ():
30203029 if first :
3021- self . stdout . write ( '{}{}\n ' .format (self .prompt , line ) )
3030+ command += '{}{}\n ' .format (self .prompt , line )
30223031 first = False
30233032 else :
3024- self .stdout .write ('{}{}\n ' .format (self .continuation_prompt , line ))
3033+ command += '{}{}\n ' .format (self .continuation_prompt , line )
3034+ transcript += command
3035+ # create a new string buffer and set it to stdout to catch the output
3036+ # of the command
3037+ membuf = io .StringIO ()
3038+ self .stdout = membuf
3039+ # then run the command and let the output go into our buffer
30253040 self .onecmd_plus_hooks (history_item )
3041+ # rewind the buffer to the beginning
3042+ membuf .seek (0 )
3043+ # get the output out of the buffer
3044+ output = membuf .read ()
3045+ # and add the regex-escaped output to the transcript
3046+ transcript += output .replace ('/' , '\/' )
30263047
30273048 # Restore stdout to its original state
3028- #self.stdout.close()
30293049 self .stdout = saved_self_stdout
3030-
30313050 # Set echo back to its original state
30323051 self .echo = saved_echo
30333052
3034- # Post-process the file to escape un-escaped "/" regex escapes
3035- membuf .seek (0 )
3036- data = membuf .read ()
3037- post_processed_data = data .replace ('/' , '\/' )
3053+ # finally, we can write the transcript out to the file
30383054 with open (args .transcript , 'w' ) as fout :
3039- fout .write (post_processed_data )
3055+ fout .write (transcript )
30403056
3041- plural = 's' if len (history ) > 1 else ''
3042- self .pfeedback ('{} command{} and outputs saved to transcript file {!r}' .format (len (history ), plural ,
3043- args .transcript ))
3057+ # and let the user know what we did
3058+ if len (history ) > 1 :
3059+ plural = 'commands and their outputs'
3060+ else :
3061+ plural = 'command and its output'
3062+ msg = '{} {} saved to transcript file {!r}'
3063+ self .pfeedback (msg .format (len (history ), plural , args .transcript ))
30443064 else :
30453065 # Display the history items retrieved
30463066 for hi in history :
0 commit comments