diff options
-rwxr-xr-x | cmd2/cmd2.py | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 60d1dbf8..3dc0cb5f 100755 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -52,6 +52,8 @@ import pyperclip # Set up readline from .rl_utils import rl_force_redisplay, readline, rl_type, RlType +from cmd2.parsing import CommandParser + if rl_type == RlType.PYREADLINE: # Save the original pyreadline display completion function since we need to override it and restore it @@ -703,11 +705,11 @@ class Cmd(cmd.Cmd): """ # Attributes used to configure the ParserManager (all are not dynamically settable at runtime) blankLinesAllowed = False - commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) - commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd ^ '*/') - legalChars = u'!#$%.:?@_-' + pyparsing.alphanums + pyparsing.alphas8bit + commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) # deleteme + commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd ^ '*/') # deleteme + legalChars = u'!#$%.:?@_-' + pyparsing.alphanums + pyparsing.alphas8bit # deleteme multilineCommands = [] - prefixParser = pyparsing.Empty() + prefixParser = pyparsing.Empty() #deleteme redirector = '>' # for sending output to file shortcuts = {'?': 'help', '!': 'shell', '@': 'load', '@@': '_relative_load'} aliases = dict() @@ -798,13 +800,20 @@ class Cmd(cmd.Cmd): self.history = History() self.pystate = {} self.keywords = self.reserved_words + [fname[3:] for fname in dir(self) if fname.startswith('do_')] - self.parser_manager = ParserManager(redirector=self.redirector, terminators=self.terminators, - multilineCommands=self.multilineCommands, - legalChars=self.legalChars, commentGrammars=self.commentGrammars, - commentInProgress=self.commentInProgress, - blankLinesAllowed=self.blankLinesAllowed, prefixParser=self.prefixParser, - preparse=self.preparse, postparse=self.postparse, aliases=self.aliases, - shortcuts=self.shortcuts) + self.command_parser = CommandParser( + quotes=QUOTES, + allow_redirection=self.allow_redirection, + redirection_chars=REDIRECTION_CHARS, + terminators=self.terminators, + multilineCommands=self.multilineCommands, + ) + # self.parser_manager = ParserManager(redirector=self.redirector, terminators=self.terminators, + # multilineCommands=self.multilineCommands, + # legalChars=self.legalChars, commentGrammars=self.commentGrammars, + # commentInProgress=self.commentInProgress, + # blankLinesAllowed=self.blankLinesAllowed, prefixParser=self.prefixParser, + # preparse=self.preparse, postparse=self.postparse, aliases=self.aliases, + # shortcuts=self.shortcuts) self._transcript_files = transcript_files # Used to enable the ability for a Python script to quit the application @@ -2205,14 +2214,15 @@ class Cmd(cmd.Cmd): def _complete_statement(self, line): """Keep accepting lines of input until the command is complete.""" - if not line or (not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line)): - raise EmptyStatement() - statement = self.parser_manager.parsed(line) - while statement.parsed.multilineCommand and (statement.parsed.terminator == ''): - statement = '%s\n%s' % (statement.parsed.raw, - self.pseudo_raw_input(self.continuation_prompt)) - statement = self.parser_manager.parsed(statement) - if not statement.parsed.command: + #if not line or (not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line)): + # raise EmptyStatement() + # statement = self.parser_manager.parsed(line) # deleteme + statement = self.command_parser.parseString(line) + #while statement.parsed.multilineCommand and (statement.parsed.terminator == ''): + # statement = '%s\n%s' % (statement.parsed.raw, + # self.pseudo_raw_input(self.continuation_prompt)) + # statement = self.parser_manager.parsed(statement) + if not statement.command: raise EmptyStatement() return statement @@ -2221,7 +2231,7 @@ class Cmd(cmd.Cmd): :param statement: ParsedString - subclass of str which also contains pyparsing ParseResults instance """ - if statement.parsed.pipeTo: + if statement.pipeTo: self.kept_state = Statekeeper(self, ('stdout',)) # Create a pipe with read and write sides @@ -2236,7 +2246,7 @@ class Cmd(cmd.Cmd): # We want Popen to raise an exception if it fails to open the process. Thus we don't set shell to True. try: - self.pipe_proc = subprocess.Popen(shlex.split(statement.parsed.pipeTo), stdin=subproc_stdin) + self.pipe_proc = subprocess.Popen(shlex.split(statement.pipeTo), stdin=subproc_stdin) except Exception as ex: # Restore stdout to what it was and close the pipe self.stdout.close() @@ -2248,20 +2258,20 @@ class Cmd(cmd.Cmd): # Re-raise the exception raise ex - elif statement.parsed.output: - if (not statement.parsed.outputTo) and (not can_clip): + elif statement.output: + if (not statement.outputTo) and (not can_clip): raise EnvironmentError('Cannot redirect to paste buffer; install ``xclip`` and re-run to enable') self.kept_state = Statekeeper(self, ('stdout',)) self.kept_sys = Statekeeper(sys, ('stdout',)) self.redirecting = True - if statement.parsed.outputTo: + if statement.outputTo: mode = 'w' - if statement.parsed.output == 2 * self.redirector: + if statement.output == 2 * self.redirector: mode = 'a' - sys.stdout = self.stdout = open(os.path.expanduser(statement.parsed.outputTo), mode) + sys.stdout = self.stdout = open(os.path.expanduser(statement.outputTo), mode) else: sys.stdout = self.stdout = tempfile.TemporaryFile(mode="w+") - if statement.parsed.output == '>>': + if statement.output == '>>': self.poutput(get_paste_buffer()) def _restore_output(self, statement): @@ -2272,7 +2282,7 @@ class Cmd(cmd.Cmd): # If we have redirected output to a file or the clipboard or piped it to a shell command, then restore state if self.kept_state is not None: # If we redirected output to the clipboard - if statement.parsed.output and not statement.parsed.outputTo: + if statement.output and not statement.outputTo: self.stdout.seek(0) write_to_paste_buffer(self.stdout.read()) @@ -2310,29 +2320,29 @@ class Cmd(cmd.Cmd): result = target return result - def onecmd(self, line): + def onecmd(self, statement): """ This executes the actual do_* method for a command. If the command provided doesn't exist, then it executes _default() instead. - :param line: ParsedString - subclass of string including the pyparsing ParseResults + :param line: Command - a parsed command from the input stream :return: bool - a flag indicating whether the interpretation of commands should stop """ - statement = self.parser_manager.parsed(line) - funcname = self._func_named(statement.parsed.command) + #statement = self.parser_manager.parsed(line) # deleteme + funcname = self._func_named(statement.command) 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.exclude_from_history: - self.history.append(statement.parsed.raw) + if statement.command not in self.exclude_from_history: + self.history.append(statement.raw) try: func = getattr(self, funcname) except AttributeError: return self.default(statement) - stop = func(statement) + stop = func("{} {}".format(statement.command, statement.args)) return stop def default(self, statement): |