diff --git a/IPython/prefilter.py b/IPython/prefilter.py index d317884..ad84deb 100644 --- a/IPython/prefilter.py +++ b/IPython/prefilter.py @@ -105,7 +105,7 @@ def splitUserInput(line, pattern=None): #print 'line:<%s>' % line # dbg #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg - return pre,iFun.strip(),theRest + return pre,iFun.strip(),theRest.lstrip() # RegExp for splitting line contents into pre-char//first word-method//rest. @@ -122,10 +122,10 @@ def splitUserInput(line, pattern=None): # The three parts of the regex are: # 1) pre: pre_char *or* initial whitespace # 2) iFun: first word/method (mix of \w and '.') -# 3) theRest: rest of line +# 3) theRest: rest of line (separated from iFun by space if non-empty) line_split = re.compile(r'^([,;/%?]|!!?|\s*)' - r'\s*([\w\.]+)\s*' - r'(.*)$') + r'\s*([\w\.]+)' + r'(\s+.*$|$)') shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)') diff --git a/test/test_handlers.py b/test/test_handlers.py index 9f15656..495239b 100644 --- a/test/test_handlers.py +++ b/test/test_handlers.py @@ -17,7 +17,8 @@ def run(tests): ip.runlines(pre) ip.runlines('_i') # Not sure why I need this... actual = ip.user_ns['_i'] - if actual != None: actual = actual.rstrip('\n') + if actual != None: + actual = actual.rstrip('\n') if actual != post: failures.append('Expected %r to become %r, found %r' % ( pre, post, actual)) @@ -53,8 +54,8 @@ try: # write anything to stdout. # Turn off actual execution of aliases, because it's noisy - old_system_cmd = ip.IP.system - ip.IP.system = lambda cmd: None + old_system_cmd = ip.system + ip.system = lambda cmd: None ip.IP.alias_table['an_alias'] = (0, 'true') @@ -66,7 +67,7 @@ try: # chars, *not* initial chars which happen to be aliases: ("top", '_ip.system("d:/cygwin/top ")'), ]) - ip.IP.system = old_system_cmd + ip.system = old_system_cmd call_idx = CallableIndexable() diff --git a/test/test_prefilter.py b/test/test_prefilter.py index f240303..4d7aa62 100644 --- a/test/test_prefilter.py +++ b/test/test_prefilter.py @@ -154,12 +154,24 @@ esc_handler_tests = [ # XXX Possibly, add test for /,; once those are unhooked from %autocall ( 'emacs_mode # PYTHON-MODE', handle_emacs ), ( ' ', handle_normal), + # Trailing qmark combos. Odd special cases abound - ( '!thing?', handle_shell_escape), # trailing '?' loses to shell esc - ( '!thing ?', handle_shell_escape), - ( '!!thing?', handle_shell_escape), + + # The key is: we don't want the trailing ? to trigger help if it's a + # part of a shell glob (like, e.g. '!ls file.?'). Instead, we want the + # shell handler to be called. Due to subtleties of the input string + # parsing, however, we only call the shell handler if the trailing ? is + # part of something whitespace-separated from the !cmd. See examples. + ( '!thing?', handle_help), + ( '!thing arg?', handle_shell_escape), + ( '!!thing?', handle_help), + ( '!!thing arg?', handle_shell_escape), + + # For all other leading esc chars, we always trigger help ( '%cmd?', handle_help), + ( '%cmd ?', handle_help), ( '/cmd?', handle_help), + ( '/cmd ?', handle_help), ( ';cmd?', handle_help), ( ',cmd?', handle_help), ] @@ -216,6 +228,9 @@ run_handler_tests([ ( '%does_not_exist', handle_magic), ( 'cd /', handle_magic), ( 'cd = 2', handle_normal), + ( 'r', handle_magic), + ( 'r thing', handle_magic), + ( 'r"str"', handle_normal), ]) # If next elt starts with anything that could be an assignment, func call,