Mercurial > python-cmd2
comparison cmd2.py @ 348:09145e5d7c26
beginning to change output redirection
author | catherine@Drou |
---|---|
date | Tue, 16 Feb 2010 17:33:11 -0500 |
parents | 432ccab7c6c8 |
children | 6116360f6e03 |
comparison
equal
deleted
inserted
replaced
347:432ccab7c6c8 | 348:09145e5d7c26 |
---|---|
347 else: | 347 else: |
348 result = get_paste_buffer() | 348 result = get_paste_buffer() |
349 return result | 349 return result |
350 | 350 |
351 class EmbeddedConsoleExit(Exception): | 351 class EmbeddedConsoleExit(Exception): |
352 pass | |
353 | |
354 class EmptyStatement(Exception): | |
352 pass | 355 pass |
353 | 356 |
354 def ljust(x, width, fillchar=' '): | 357 def ljust(x, width, fillchar=' '): |
355 'analogous to str.ljust, but works for lists' | 358 'analogous to str.ljust, but works for lists' |
356 if hasattr(x, 'ljust'): | 359 if hasattr(x, 'ljust'): |
726 return p | 729 return p |
727 | 730 |
728 def postparsing_precmd(self, statement): | 731 def postparsing_precmd(self, statement): |
729 stop = 0 | 732 stop = 0 |
730 return stop, statement | 733 return stop, statement |
731 | |
732 def postparsing_postcmd(self, stop): | 734 def postparsing_postcmd(self, stop): |
733 return stop | 735 return stop |
736 | |
734 def func_named(self, arg): | 737 def func_named(self, arg): |
735 result = None | 738 result = None |
736 target = 'do_' + arg | 739 target = 'do_' + arg |
737 if target in dir(self): | 740 if target in dir(self): |
738 result = target | 741 result = target |
745 def onecmd_plus_hooks(self, line): | 748 def onecmd_plus_hooks(self, line): |
746 line = self.precmd(line) | 749 line = self.precmd(line) |
747 stop = self.onecmd(line) | 750 stop = self.onecmd(line) |
748 stop = self.postcmd(stop, line) | 751 stop = self.postcmd(stop, line) |
749 return stop | 752 return stop |
750 def onecmd(self, line): | 753 def complete_statement(self, line): |
751 """Interpret the argument as though it had been typed in response | 754 if (not line) or ( |
752 to the prompt. | 755 not pyparsing.Or(self.commentGrammars). |
753 | 756 setParseAction(lambda x: '').transformString(line)): |
754 This may be overridden, but should not normally need to be; | 757 raise EmptyStatement |
755 see the precmd() and postcmd() methods for useful execution hooks. | 758 statement = self.parsed(line) |
756 The return value is a flag indicating whether interpretation of | 759 while statement.parsed.multilineCommand and (statement.parsed.terminator == ''): |
757 commands by the interpreter should stop. | 760 statement = '%s\n%s' % (statement.parsed.raw, |
758 | 761 self.pseudo_raw_input(self.continuation_prompt)) |
759 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`. | 762 statement = self.parsed(statement) |
760 | |
761 """ | |
762 # TODO: output from precmd and postcmd goes untrapped... and I don't | |
763 # know how to fix it... | |
764 if not line: | |
765 return self.emptyline() | |
766 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line): | |
767 return 0 # command was empty except for comments | |
768 try: | |
769 statement = self.parsed(line) | |
770 while statement.parsed.multilineCommand and (statement.parsed.terminator == ''): | |
771 statement = '%s\n%s' % (statement.parsed.raw, | |
772 self.pseudo_raw_input(self.continuation_prompt)) | |
773 statement = self.parsed(statement) | |
774 except Exception, e: | |
775 self.perror(e) | |
776 return 0 | |
777 if statement.parsed.command not in self.excludeFromHistory: | |
778 self.history.append(statement.parsed.raw) | |
779 try: | |
780 (stop, statement) = self.postparsing_precmd(statement) | |
781 except Exception, e: | |
782 self.perror(e) | |
783 return 0 | |
784 if stop: | |
785 return self.postparsing_postcmd(stop) | |
786 | |
787 if not statement.parsed.command: | 763 if not statement.parsed.command: |
788 return self.postparsing_postcmd(stop=0) | 764 raise EmptyStatement |
789 | 765 return statement |
766 | |
767 def output_state(self, statement): | |
790 statekeeper = None | 768 statekeeper = None |
791 | |
792 if statement.parsed.pipeTo: | 769 if statement.parsed.pipeTo: |
793 redirect = subprocess.Popen(statement.parsed.pipeTo, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE) | 770 redirect = subprocess.Popen(statement.parsed.pipeTo, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE) |
794 statekeeper = Statekeeper(self, ('stdout',)) | 771 statekeeper = Statekeeper(self, ('stdout',)) |
795 self.stdout = redirect.stdin | 772 self.stdout = redirect.stdin |
796 elif statement.parsed.output: | 773 elif statement.parsed.output: |
797 statekeeper = Statekeeper(self, ('stdout',)) | 774 statekeeper = Statekeeper(self, ('stdout',)) |
798 if statement.parsed.outputTo: | 775 if statement.parsed.outputTo: |
799 mode = 'w' | 776 mode = 'w' |
800 if statement.parsed.output == '>>': | 777 if statement.parsed.output == '>>': |
801 mode = 'a' | 778 mode = 'a' |
802 try: | 779 self.stdout = open(os.path.expanduser(statement.parsed.outputTo), mode) |
803 self.stdout = open(os.path.expanduser(statement.parsed.outputTo), mode) | |
804 except Exception, e: | |
805 self.perror(e) | |
806 return self.postparsing_postcmd(stop=0) | |
807 else: | 780 else: |
808 statekeeper = Statekeeper(self, ('stdout',)) | 781 statekeeper = Statekeeper(self, ('stdout',)) |
809 self.stdout = tempfile.TemporaryFile() | 782 self.stdout = tempfile.TemporaryFile() |
810 if statement.parsed.output == '>>': | 783 if statement.parsed.output == '>>': |
811 self.stdout.write(get_paste_buffer()) | 784 self.stdout.write(get_paste_buffer()) |
812 try: | 785 return statekeeper |
786 | |
787 def onecmd(self, line): | |
788 """Interpret the argument as though it had been typed in response | |
789 to the prompt. | |
790 | |
791 This may be overridden, but should not normally need to be; | |
792 see the precmd() and postcmd() methods for useful execution hooks. | |
793 The return value is a flag indicating whether interpretation of | |
794 commands by the interpreter should stop. | |
795 | |
796 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`. | |
797 | |
798 """ | |
799 # TODO: output from precmd and postcmd goes untrapped... and I don't | |
800 # know how to fix it... | |
801 | |
802 try: | |
803 statement = self.complete_statement(line) | |
804 except EmptyStatement: | |
805 return 0 | |
806 | |
807 (stop, statement) = self.postparsing_precmd(statement) | |
808 if stop: | |
809 return self.postparsing_postcmd(stop) | |
810 | |
811 try: | |
812 if statement.parsed.command not in self.excludeFromHistory: | |
813 self.history.append(statement.parsed.raw) | |
814 statekeeper = self.output_state(statement) | |
813 try: | 815 try: |
814 # "heart" of the command, replaces cmd's onecmd() | 816 # "heart" of the command, replaces cmd's onecmd() |
815 self.lastcmd = statement.parsed.raw | 817 self.lastcmd = statement.parsed.raw |
816 funcname = self.func_named(statement.parsed.command) | 818 funcname = self.func_named(statement.parsed.command) |
817 if not funcname: | 819 if not funcname: |
836 self.perror(e) | 838 self.perror(e) |
837 elif statement.parsed.pipeTo: | 839 elif statement.parsed.pipeTo: |
838 for result in redirect.communicate(): | 840 for result in redirect.communicate(): |
839 statekeeper.stdout.write(result or '') | 841 statekeeper.stdout.write(result or '') |
840 self.stdout.close() | 842 self.stdout.close() |
841 statekeeper.restore() | 843 statekeeper.restore() |
842 | |
843 return self.postparsing_postcmd(stop) | 844 return self.postparsing_postcmd(stop) |
844 | 845 |
845 def _default(self, statement): | 846 def _default(self, statement): |
846 arg = statement.full_parsed_statement() | 847 arg = statement.full_parsed_statement() |
847 if self.default_to_shell: | 848 if self.default_to_shell: |