1# encoding: utf-8
2"""
3Simple utility for splitting user input. This is used by both inputsplitter and
4prefilter.
5
6Authors:
7
8* Brian Granger
9* Fernando Perez
10"""
11
12#-----------------------------------------------------------------------------
13#  Copyright (C) 2008-2011  The IPython Development Team
14#
15#  Distributed under the terms of the BSD License.  The full license is in
16#  the file COPYING, distributed as part of this software.
17#-----------------------------------------------------------------------------
18
19#-----------------------------------------------------------------------------
20# Imports
21#-----------------------------------------------------------------------------
22
23import re
24import sys
25
26from IPython.utils import py3compat
27from IPython.utils.encoding import get_stream_enc
28
29#-----------------------------------------------------------------------------
30# Main function
31#-----------------------------------------------------------------------------
32
33# RegExp for splitting line contents into pre-char//first word-method//rest.
34# For clarity, each group in on one line.
35
36# WARNING: update the regexp if the escapes in interactiveshell are changed, as
37# they are hardwired in.
38
39# Although it's not solely driven by the regex, note that:
40# ,;/% only trigger if they are the first character on the line
41# ! and !! trigger if they are first char(s) *or* follow an indent
42# ? triggers as first or last char.
43
44line_split = re.compile("""
45             ^(\s*)               # any leading space
46             ([,;/%]|!!?|\?\??)?  # escape character or characters
47             \s*(%{0,2}[\w\.\*]*)     # function/method, possibly with leading %
48                                  # to correctly treat things like '?%magic'
49             (.*?$|$)             # rest of line
50             """, re.VERBOSE)
51
52
53def split_user_input(line, pattern=None):
54    """Split user input into initial whitespace, escape character, function part
55    and the rest.
56    """
57    # We need to ensure that the rest of this routine deals only with unicode
58    encoding = get_stream_enc(sys.stdin, 'utf-8')
59    line = py3compat.cast_unicode(line, encoding)
60
61    if pattern is None:
62        pattern = line_split
63    match = pattern.match(line)
64    if not match:
65        # print "match failed for line '%s'" % line
66        try:
67            ifun, the_rest = line.split(None,1)
68        except ValueError:
69            # print "split failed for line '%s'" % line
70            ifun, the_rest = line, u''
71        pre = re.match('^(\s*)(.*)',line).groups()[0]
72        esc = ""
73    else:
74        pre, esc, ifun, the_rest = match.groups()
75
76    #print 'line:<%s>' % line # dbg
77    #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
78    return pre, esc or '', ifun.strip(), the_rest.lstrip()
79
80
81class LineInfo(object):
82    """A single line of input and associated info.
83
84    Includes the following as properties:
85
86    line
87      The original, raw line
88
89    continue_prompt
90      Is this line a continuation in a sequence of multiline input?
91
92    pre
93      Any leading whitespace.
94
95    esc
96      The escape character(s) in pre or the empty string if there isn't one.
97      Note that '!!' and '??' are possible values for esc. Otherwise it will
98      always be a single character.
99
100    ifun
101      The 'function part', which is basically the maximal initial sequence
102      of valid python identifiers and the '.' character. This is what is
103      checked for alias and magic transformations, used for auto-calling,
104      etc. In contrast to Python identifiers, it may start with "%" and contain
105      "*".
106
107    the_rest
108      Everything else on the line.
109    """
110    def __init__(self, line, continue_prompt=False):
111        self.line            = line
112        self.continue_prompt = continue_prompt
113        self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
114
115        self.pre_char       = self.pre.strip()
116        if self.pre_char:
117            self.pre_whitespace = '' # No whitespace allowd before esc chars
118        else:
119            self.pre_whitespace = self.pre
120
121    def ofind(self, ip):
122        """Do a full, attribute-walking lookup of the ifun in the various
123        namespaces for the given IPython InteractiveShell instance.
124
125        Return a dict with keys: {found, obj, ospace, ismagic}
126
127        Note: can cause state changes because of calling getattr, but should
128        only be run if autocall is on and if the line hasn't matched any
129        other, less dangerous handlers.
130
131        Does cache the results of the call, so can be called multiple times
132        without worrying about *further* damaging state.
133        """
134        return ip._ofind(self.ifun)
135
136    def __str__(self):
137        return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
138