Mercurial > python-cmd2
comparison cmd2.py @ 170:310ebf4baa7a
\n endings still squirrely; watch blank spaces in saved files
author | catherine@dellzilla |
---|---|
date | Wed, 10 Dec 2008 16:33:05 -0500 |
parents | 429c8e984df4 |
children | 0b93f1a4076c |
comparison
equal
deleted
inserted
replaced
169:429c8e984df4 | 170:310ebf4baa7a |
---|---|
180 shortcuts = {'?': 'help', '!': 'shell', '@': 'load' } | 180 shortcuts = {'?': 'help', '!': 'shell', '@': 'load' } |
181 excludeFromHistory = '''run r list l history hi ed edit li eof'''.split() | 181 excludeFromHistory = '''run r list l history hi ed edit li eof'''.split() |
182 noSpecialParse = 'set ed edit exit'.split() | 182 noSpecialParse = 'set ed edit exit'.split() |
183 defaultExtension = 'txt' | 183 defaultExtension = 'txt' |
184 defaultFileName = 'command.txt' | 184 defaultFileName = 'command.txt' |
185 singleQuotedStrings = True | 185 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive', 'echo'] |
186 doubleQuotedStrings = True | |
187 | 186 |
188 editor = os.environ.get('EDITOR') | 187 editor = os.environ.get('EDITOR') |
189 _STOP_AND_EXIT = 2 | 188 _STOP_AND_EXIT = 2 |
190 if not editor: | 189 if not editor: |
191 if sys.platform[:3] == 'win': | 190 if sys.platform[:3] == 'win': |
193 else: | 192 else: |
194 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']: | 193 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']: |
195 if not os.system('which %s' % (editor)): | 194 if not os.system('which %s' % (editor)): |
196 break | 195 break |
197 | 196 |
198 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive', 'echo'] | |
199 def do_cmdenvironment(self, args): | 197 def do_cmdenvironment(self, args): |
200 self.stdout.write(""" | 198 self.stdout.write(""" |
201 Commands are %(casesensitive)scase-sensitive. | 199 Commands are %(casesensitive)scase-sensitive. |
202 Commands may be terminated with: %(terminators)s | 200 Commands may be terminated with: %(terminators)s |
203 Settable parameters: %(settable)s | 201 Settable parameters: %(settable)s |
227 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) | 225 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) |
228 | 226 |
229 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) | 227 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) |
230 commentGrammars.addParseAction(lambda x: '') | 228 commentGrammars.addParseAction(lambda x: '') |
231 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd) | 229 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd) |
232 #quotedStringInProgress = pyparsing.Literal('"') ^ pyparsing.Literal("'") + pyparsing.SkipTo(pyparsing.lineEnd) | |
233 terminators = [';', '\n\n'] | 230 terminators = [';', '\n\n'] |
234 multilineCommands = [] | 231 multilineCommands = [] |
235 | 232 |
236 def _init_parser(self): | 233 def _init_parser(self): |
237 ''' | 234 ''' |
381 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand') | 378 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand') |
382 oneLineCommand = pyparsing.Word(self.legalChars)('command') | 379 oneLineCommand = pyparsing.Word(self.legalChars)('command') |
383 pipe = pyparsing.Keyword('|', identChars='|') | 380 pipe = pyparsing.Keyword('|', identChars='|') |
384 self.commentGrammars.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).setParseAction(lambda x: '') | 381 self.commentGrammars.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).setParseAction(lambda x: '') |
385 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment) | 382 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment) |
386 #self.quotedStringInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString) | |
387 afterElements = \ | 383 afterElements = \ |
388 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \ | 384 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \ |
389 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) | 385 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) |
390 if self.caseInsensitive: | 386 if self.caseInsensitive: |
391 multilineCommand.setParseAction(lambda x: x[0].lower()) | 387 multilineCommand.setParseAction(lambda x: x[0].lower()) |
392 oneLineCommand.setParseAction(lambda x: x[0].lower()) | 388 oneLineCommand.setParseAction(lambda x: x[0].lower()) |
389 subparser1 = (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + | |
390 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) | |
391 subparser2 = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + | |
392 pyparsing.Optional(terminatorParser) + afterElements) | |
393 self.parser = ( | 393 self.parser = ( |
394 pyparsing.stringEnd | 394 pyparsing.stringEnd |
395 ^ | 395 | |
396 (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + | 396 subparser1 |
397 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) | 397 | |
398 ^ | |
399 multilineCommand + pyparsing.SkipTo(pyparsing.stringEnd) | 398 multilineCommand + pyparsing.SkipTo(pyparsing.stringEnd) |
400 ^ | 399 | |
401 ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + | 400 subparser2 |
402 pyparsing.Optional(terminatorParser) + afterElements) | |
403 ) | 401 ) |
404 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) | 402 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) |
405 | 403 |
406 inputMark = pyparsing.Literal('<') | 404 inputMark = pyparsing.Literal('<') |
407 inputMark.setParseAction(lambda x: '') | 405 inputMark.setParseAction(lambda x: '') |
412 | 410 |
413 def parsed(self, raw, **kwargs): | 411 def parsed(self, raw, **kwargs): |
414 if isinstance(raw, ParsedString): | 412 if isinstance(raw, ParsedString): |
415 p = raw | 413 p = raw |
416 else: | 414 else: |
417 s = self.inputParser.transformString(raw.strip()) # used to be raw.strip() | 415 s = self.inputParser.transformString(raw) # used to be raw.strip() |
418 for (shortcut, expansion) in self.shortcuts.items(): | 416 for (shortcut, expansion) in self.shortcuts.items(): |
419 if s.startswith(shortcut): | 417 if s.startswith(shortcut): |
420 s = s.replace(shortcut, expansion + ' ', 1) | 418 s = s.replace(shortcut, expansion + ' ', 1) |
421 break | 419 break |
422 result = self.parser.parseString(s) | 420 result = self.parser.parseString(s) |
441 commands by the interpreter should stop. | 439 commands by the interpreter should stop. |
442 | 440 |
443 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`. | 441 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`. |
444 | 442 |
445 """ | 443 """ |
446 line = line.strip() | 444 #line = line.strip() # trying to allow proper \n\n endings |
447 if not line: | 445 if not line: |
448 return self.emptyline() | 446 return self.emptyline() |
449 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line): | 447 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line): |
450 return 0 | 448 return 0 |
451 try: | 449 try: |
452 statement = self.parsed(line) | 450 statement = self.parsed(line) |
453 while statement.parsed.multilineCommand and not statement.parsed.terminator: | 451 while statement.parsed.multilineCommand and (statement.parsed.terminator == ''): |
454 statement = self.parsed('%s\n%s' % (statement.parsed.raw, | 452 statement = self.parsed('%s\n%s' % (statement.parsed.raw, |
455 self.pseudo_raw_input(self.continuationPrompt))) | 453 self.pseudo_raw_input(self.continuationPrompt))) |
456 except Exception, e: | 454 except Exception, e: |
457 print e | 455 print e |
458 return 0 | 456 return 0 |
916 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName) | 914 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName) |
917 def testall(self): | 915 def testall(self): |
918 if self.CmdApp: | 916 if self.CmdApp: |
919 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator(): | 917 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator(): |
920 parsed = self.cmdapp.parsed(cmdInput) | 918 parsed = self.cmdapp.parsed(cmdInput) |
921 if parsed.parsed.multilineCommand and not parsed.parsed.terminator: | 919 if parsed.parsed.multilineCommand and (parsed.parsed.terminator != ''): |
922 cmdInput = cmdInput + self.cmdapp.terminators[0] | 920 cmdInput = cmdInput + self.cmdapp.terminators[0] |
923 self.cmdapp.onecmd(cmdInput) | 921 self.cmdapp.onecmd(cmdInput) |
924 result = self.outputTrap.read() | 922 result = self.outputTrap.read() |
925 expected = self.transcriptReader.nextExpected() | 923 expected = self.transcriptReader.nextExpected() |
926 self.assertEqual(self.stripByLine(result), self.stripByLine(expected), | 924 self.assertEqual(self.stripByLine(result), self.stripByLine(expected), |