Show More
@@ -78,5 +78,105 b' def main():' | |||||
78 | #print "al",cmd |
|
78 | #print "al",cmd | |
79 | noext, ext = os.path.splitext(cmd) |
|
79 | noext, ext = os.path.splitext(cmd) | |
80 | ip.IP.alias_table[noext] = (0,cmd) |
|
80 | ip.IP.alias_table[noext] = (0,cmd) | |
|
81 | extend_shell_behavior(ip) | |||
|
82 | ||||
|
83 | def extend_shell_behavior(ip): | |||
|
84 | ||||
|
85 | # Instead of making signature a global variable tie it to IPSHELL. | |||
|
86 | # In future if it is required to distinguish between different | |||
|
87 | # shells we can assign a signature per shell basis | |||
|
88 | ip.IP.__sig__ = 0xa005 | |||
|
89 | # mark the IPSHELL with this signature | |||
|
90 | ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__ | |||
|
91 | ||||
|
92 | from IPython.Itpl import ItplNS | |||
|
93 | from IPython.genutils import shell | |||
|
94 | # utility to expand user variables via Itpl | |||
|
95 | ip.IP.var_expand = lambda cmd, lvars=None: \ | |||
|
96 | str(ItplNS(cmd.replace('#','\#'), ip.IP.user_ns, get_locals())) | |||
|
97 | ||||
|
98 | def get_locals(): | |||
|
99 | """ Substituting a variable through Itpl deep inside the IPSHELL stack | |||
|
100 | requires the knowledge of all the variables in scope upto the last | |||
|
101 | IPSHELL frame. This routine simply merges all the local variables | |||
|
102 | on the IPSHELL stack without worrying about their scope rules | |||
|
103 | """ | |||
|
104 | import sys | |||
|
105 | # note lambda expression constitues a function call | |||
|
106 | # hence fno should be incremented by one | |||
|
107 | getsig = lambda fno: sys._getframe(fno+1).f_globals \ | |||
|
108 | ['__builtins__'].__dict__['__sig__'] | |||
|
109 | getlvars = lambda fno: sys._getframe(fno+1).f_locals | |||
|
110 | # trackback until we enter the IPSHELL | |||
|
111 | frame_no = 1 | |||
|
112 | sig = ip.IP.__sig__ | |||
|
113 | fsig = ~sig | |||
|
114 | while fsig != sig : | |||
|
115 | try: | |||
|
116 | fsig = getsig(frame_no) | |||
|
117 | except (AttributeError, KeyError): | |||
|
118 | frame_no += 1 | |||
|
119 | except ValueError: | |||
|
120 | # stack is depleted | |||
|
121 | # call did not originate from IPSHELL | |||
|
122 | return {} | |||
|
123 | first_frame = frame_no | |||
|
124 | # walk further back until we exit from IPSHELL or deplete stack | |||
|
125 | try: | |||
|
126 | while(sig == getsig(frame_no+1)): | |||
|
127 | frame_no += 1 | |||
|
128 | except (AttributeError, KeyError, ValueError): | |||
|
129 | pass | |||
|
130 | # merge the locals from top down hence overriding | |||
|
131 | # any re-definitions of variables, functions etc. | |||
|
132 | lvars = {} | |||
|
133 | for fno in range(frame_no, first_frame-1, -1): | |||
|
134 | lvars.update(getlvars(fno)) | |||
|
135 | #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg | |||
|
136 | return lvars | |||
|
137 | ||||
|
138 | def _runlines(lines): | |||
|
139 | """Run a string of one or more lines of source. | |||
|
140 | ||||
|
141 | This method is capable of running a string containing multiple source | |||
|
142 | lines, as if they had been entered at the IPython prompt. Since it | |||
|
143 | exposes IPython's processing machinery, the given strings can contain | |||
|
144 | magic calls (%magic), special shell access (!cmd), etc.""" | |||
|
145 | ||||
|
146 | # We must start with a clean buffer, in case this is run from an | |||
|
147 | # interactive IPython session (via a magic, for example). | |||
|
148 | ip.IP.resetbuffer() | |||
|
149 | lines = lines.split('\n') | |||
|
150 | more = 0 | |||
|
151 | command = '' | |||
|
152 | for line in lines: | |||
|
153 | # skip blank lines so we don't mess up the prompt counter, but do | |||
|
154 | # NOT skip even a blank line if we are in a code block (more is | |||
|
155 | # true) | |||
|
156 | # if command is not empty trim the line | |||
|
157 | if command != '' : | |||
|
158 | line = line.strip() | |||
|
159 | # add the broken line to the command | |||
|
160 | if line and line[-1] == '\\' : | |||
|
161 | command += line[0:-1] + ' ' | |||
|
162 | more = True | |||
|
163 | continue | |||
|
164 | else : | |||
|
165 | # add the last (current) line to the command | |||
|
166 | command += line | |||
|
167 | if command or more: | |||
|
168 | more = ip.IP.push(ip.IP.prefilter(command,more)) | |||
|
169 | command = '' | |||
|
170 | # IPython's runsource returns None if there was an error | |||
|
171 | # compiling the code. This allows us to stop processing right | |||
|
172 | # away, so the user gets the error message at the right place. | |||
|
173 | if more is None: | |||
|
174 | break | |||
|
175 | # final newline in case the input didn't have it, so that the code | |||
|
176 | # actually does get executed | |||
|
177 | if more: | |||
|
178 | ip.IP.push('\n') | |||
|
179 | ||||
|
180 | ip.IP.runlines = _runlines | |||
81 |
|
181 | |||
82 | main() |
|
182 | main() |
@@ -1,3 +1,11 b'' | |||||
|
1 | 2006-06-12 Ville Vainio <vivainio@gmail.com> | |||
|
2 | ||||
|
3 | * ipy_profile_sh.py: applied Krisha Mohan Gundu's patch for | |||
|
4 | allowing $variable interpolation within multiline statements, | |||
|
5 | though so far only with "sh" profile for a testing period. | |||
|
6 | The patch also enables splitting long commands with \ but it | |||
|
7 | doesn't work properly yet. | |||
|
8 | ||||
1 | 2006-06-12 Walter Doerwald <walter@livinglogic.de> |
|
9 | 2006-06-12 Walter Doerwald <walter@livinglogic.de> | |
2 |
|
10 | |||
3 | * IPython/Extensions/ibrowse.py (_dodisplay): Display the length of the |
|
11 | * IPython/Extensions/ibrowse.py (_dodisplay): Display the length of the |
General Comments 0
You need to be logged in to leave comments.
Login now