##// END OF EJS Templates
ipapi, ileo: fix _ip.runlines() cleanup routine for better handling of secondary blocks (else etc)
Ville M. Vainio -
Show More
@@ -1,586 +1,585 b''
1 """ ILeo - Leo plugin for IPython
1 """ ILeo - Leo plugin for IPython
2
2
3
3
4 """
4 """
5 import IPython.ipapi
5 import IPython.ipapi
6 import IPython.genutils
6 import IPython.genutils
7 import IPython.generics
7 import IPython.generics
8 from IPython.hooks import CommandChainDispatcher
8 from IPython.hooks import CommandChainDispatcher
9 import re
9 import re
10 import UserDict
10 import UserDict
11 from IPython.ipapi import TryNext
11 from IPython.ipapi import TryNext
12 import IPython.macro
12 import IPython.macro
13 import IPython.Shell
13 import IPython.Shell
14
14
15 def init_ipython(ipy):
15 def init_ipython(ipy):
16 """ This will be run by _ip.load('ipy_leo')
16 """ This will be run by _ip.load('ipy_leo')
17
17
18 Leo still needs to run update_commander() after this.
18 Leo still needs to run update_commander() after this.
19
19
20 """
20 """
21 global ip
21 global ip
22 ip = ipy
22 ip = ipy
23 IPython.Shell.hijack_tk()
23 IPython.Shell.hijack_tk()
24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
25 ip.expose_magic('mb',mb_f)
25 ip.expose_magic('mb',mb_f)
26 ip.expose_magic('lee',lee_f)
26 ip.expose_magic('lee',lee_f)
27 ip.expose_magic('leoref',leoref_f)
27 ip.expose_magic('leoref',leoref_f)
28 expose_ileo_push(push_cl_node,100)
28 expose_ileo_push(push_cl_node,100)
29 # this should be the LAST one that will be executed, and it will never raise TryNext
29 # this should be the LAST one that will be executed, and it will never raise TryNext
30 expose_ileo_push(push_ipython_script, 1000)
30 expose_ileo_push(push_ipython_script, 1000)
31 expose_ileo_push(push_plain_python, 100)
31 expose_ileo_push(push_plain_python, 100)
32 expose_ileo_push(push_ev_node, 100)
32 expose_ileo_push(push_ev_node, 100)
33 global wb
33 global wb
34 wb = LeoWorkbook()
34 wb = LeoWorkbook()
35 ip.user_ns['wb'] = wb
35 ip.user_ns['wb'] = wb
36
36
37 show_welcome()
37 show_welcome()
38
38
39
39
40 def update_commander(new_leox):
40 def update_commander(new_leox):
41 """ Set the Leo commander to use
41 """ Set the Leo commander to use
42
42
43 This will be run every time Leo does ipython-launch; basically,
43 This will be run every time Leo does ipython-launch; basically,
44 when the user switches the document he is focusing on, he should do
44 when the user switches the document he is focusing on, he should do
45 ipython-launch to tell ILeo what document the commands apply to.
45 ipython-launch to tell ILeo what document the commands apply to.
46
46
47 """
47 """
48
48
49 global c,g
49 global c,g
50 c,g = new_leox.c, new_leox.g
50 c,g = new_leox.c, new_leox.g
51 print "Set Leo Commander:",c.frame.getTitle()
51 print "Set Leo Commander:",c.frame.getTitle()
52
52
53 # will probably be overwritten by user, but handy for experimentation early on
53 # will probably be overwritten by user, but handy for experimentation early on
54 ip.user_ns['c'] = c
54 ip.user_ns['c'] = c
55 ip.user_ns['g'] = g
55 ip.user_ns['g'] = g
56 ip.user_ns['_leo'] = new_leox
56 ip.user_ns['_leo'] = new_leox
57
57
58 new_leox.push = push_position_from_leo
58 new_leox.push = push_position_from_leo
59 run_leo_startup_node()
59 run_leo_startup_node()
60
60
61 from IPython.external.simplegeneric import generic
61 from IPython.external.simplegeneric import generic
62 import pprint
62 import pprint
63
63
64 def es(s):
64 def es(s):
65 g.es(s, tabName = 'IPython')
65 g.es(s, tabName = 'IPython')
66 pass
66 pass
67
67
68 @generic
68 @generic
69 def format_for_leo(obj):
69 def format_for_leo(obj):
70 """ Convert obj to string representiation (for editing in Leo)"""
70 """ Convert obj to string representiation (for editing in Leo)"""
71 return pprint.pformat(obj)
71 return pprint.pformat(obj)
72
72
73 @format_for_leo.when_type(list)
73 @format_for_leo.when_type(list)
74 def format_list(obj):
74 def format_list(obj):
75 return "\n".join(str(s) for s in obj)
75 return "\n".join(str(s) for s in obj)
76
76
77
77
78 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
78 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
79 def valid_attribute(s):
79 def valid_attribute(s):
80 return attribute_re.match(s)
80 return attribute_re.match(s)
81
81
82 _rootnode = None
82 _rootnode = None
83 def rootnode():
83 def rootnode():
84 """ Get ileo root node (@ipy-root)
84 """ Get ileo root node (@ipy-root)
85
85
86 if node has become invalid or has not been set, return None
86 if node has become invalid or has not been set, return None
87
87
88 Note that the root is the *first* @ipy-root item found
88 Note that the root is the *first* @ipy-root item found
89 """
89 """
90 global _rootnode
90 global _rootnode
91 if _rootnode is None:
91 if _rootnode is None:
92 return None
92 return None
93 if c.positionExists(_rootnode.p):
93 if c.positionExists(_rootnode.p):
94 return _rootnode
94 return _rootnode
95 _rootnode = None
95 _rootnode = None
96 return None
96 return None
97
97
98 def all_cells():
98 def all_cells():
99 global _rootnode
99 global _rootnode
100 d = {}
100 d = {}
101 r = rootnode()
101 r = rootnode()
102 if r is not None:
102 if r is not None:
103 nodes = r.p.children_iter()
103 nodes = r.p.children_iter()
104 else:
104 else:
105 nodes = c.allNodes_iter()
105 nodes = c.allNodes_iter()
106
106
107 for p in nodes:
107 for p in nodes:
108 h = p.headString()
108 h = p.headString()
109 if h.strip() == '@ipy-root':
109 if h.strip() == '@ipy-root':
110 # update root node (found it for the first time)
110 # update root node (found it for the first time)
111 _rootnode = LeoNode(p)
111 _rootnode = LeoNode(p)
112 # the next recursive call will use the children of new root
112 # the next recursive call will use the children of new root
113 return all_cells()
113 return all_cells()
114
114
115 if h.startswith('@a '):
115 if h.startswith('@a '):
116 d[h.lstrip('@a ').strip()] = p.parent().copy()
116 d[h.lstrip('@a ').strip()] = p.parent().copy()
117 elif not valid_attribute(h):
117 elif not valid_attribute(h):
118 continue
118 continue
119 d[h] = p.copy()
119 d[h] = p.copy()
120 return d
120 return d
121
121
122 def eval_node(n):
122 def eval_node(n):
123 body = n.b
123 body = n.b
124 if not body.startswith('@cl'):
124 if not body.startswith('@cl'):
125 # plain python repr node, just eval it
125 # plain python repr node, just eval it
126 return ip.ev(n.b)
126 return ip.ev(n.b)
127 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
127 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
128 first, rest = body.split('\n',1)
128 first, rest = body.split('\n',1)
129 tup = first.split(None, 1)
129 tup = first.split(None, 1)
130 # @cl alone SPECIAL USE-> dump var to user_ns
130 # @cl alone SPECIAL USE-> dump var to user_ns
131 if len(tup) == 1:
131 if len(tup) == 1:
132 val = ip.ev(rest)
132 val = ip.ev(rest)
133 ip.user_ns[n.h] = val
133 ip.user_ns[n.h] = val
134 es("%s = %s" % (n.h, repr(val)[:20] ))
134 es("%s = %s" % (n.h, repr(val)[:20] ))
135 return val
135 return val
136
136
137 cl, hd = tup
137 cl, hd = tup
138
138
139 xformer = ip.ev(hd.strip())
139 xformer = ip.ev(hd.strip())
140 es('Transform w/ %s' % repr(xformer))
140 es('Transform w/ %s' % repr(xformer))
141 return xformer(rest, n)
141 return xformer(rest, n)
142
142
143 class LeoNode(object, UserDict.DictMixin):
143 class LeoNode(object, UserDict.DictMixin):
144 """ Node in Leo outline
144 """ Node in Leo outline
145
145
146 Most important attributes (getters/setters available:
146 Most important attributes (getters/setters available:
147 .v - evaluate node, can also be alligned
147 .v - evaluate node, can also be alligned
148 .b, .h - body string, headline string
148 .b, .h - body string, headline string
149 .l - value as string list
149 .l - value as string list
150
150
151 Also supports iteration,
151 Also supports iteration,
152
152
153 setitem / getitem (indexing):
153 setitem / getitem (indexing):
154 wb.foo['key'] = 12
154 wb.foo['key'] = 12
155 assert wb.foo['key'].v == 12
155 assert wb.foo['key'].v == 12
156
156
157 Note the asymmetry on setitem and getitem! Also other
157 Note the asymmetry on setitem and getitem! Also other
158 dict methods are available.
158 dict methods are available.
159
159
160 .ipush() - run push-to-ipython
160 .ipush() - run push-to-ipython
161
161
162 Minibuffer command access (tab completion works):
162 Minibuffer command access (tab completion works):
163
163
164 mb save-to-file
164 mb save-to-file
165
165
166 """
166 """
167 def __init__(self,p):
167 def __init__(self,p):
168 self.p = p.copy()
168 self.p = p.copy()
169
169
170 def __str__(self):
170 def __str__(self):
171 return "<LeoNode %s>" % str(self.p)
171 return "<LeoNode %s>" % str(self.p)
172
172
173 __repr__ = __str__
173 __repr__ = __str__
174
174
175 def __get_h(self): return self.p.headString()
175 def __get_h(self): return self.p.headString()
176 def __set_h(self,val):
176 def __set_h(self,val):
177 print "set head",val
177 print "set head",val
178 c.beginUpdate()
178 c.beginUpdate()
179 try:
179 try:
180 c.setHeadString(self.p,val)
180 c.setHeadString(self.p,val)
181 finally:
181 finally:
182 c.endUpdate()
182 c.endUpdate()
183
183
184 h = property( __get_h, __set_h, doc = "Node headline string")
184 h = property( __get_h, __set_h, doc = "Node headline string")
185
185
186 def __get_b(self): return self.p.bodyString()
186 def __get_b(self): return self.p.bodyString()
187 def __set_b(self,val):
187 def __set_b(self,val):
188 print "set body",val
188 print "set body",val
189 c.beginUpdate()
189 c.beginUpdate()
190 try:
190 try:
191 c.setBodyString(self.p, val)
191 c.setBodyString(self.p, val)
192 finally:
192 finally:
193 c.endUpdate()
193 c.endUpdate()
194
194
195 b = property(__get_b, __set_b, doc = "Nody body string")
195 b = property(__get_b, __set_b, doc = "Nody body string")
196
196
197 def __set_val(self, val):
197 def __set_val(self, val):
198 self.b = format_for_leo(val)
198 self.b = format_for_leo(val)
199
199
200 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
200 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
201
201
202 def __set_l(self,val):
202 def __set_l(self,val):
203 self.b = '\n'.join(val )
203 self.b = '\n'.join(val )
204 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
204 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
205 __set_l, doc = "Node value as string list")
205 __set_l, doc = "Node value as string list")
206
206
207 def __iter__(self):
207 def __iter__(self):
208 """ Iterate through nodes direct children """
208 """ Iterate through nodes direct children """
209
209
210 return (LeoNode(p) for p in self.p.children_iter())
210 return (LeoNode(p) for p in self.p.children_iter())
211
211
212 def __children(self):
212 def __children(self):
213 d = {}
213 d = {}
214 for child in self:
214 for child in self:
215 head = child.h
215 head = child.h
216 tup = head.split(None,1)
216 tup = head.split(None,1)
217 if len(tup) > 1 and tup[0] == '@k':
217 if len(tup) > 1 and tup[0] == '@k':
218 d[tup[1]] = child
218 d[tup[1]] = child
219 continue
219 continue
220
220
221 if not valid_attribute(head):
221 if not valid_attribute(head):
222 d[head] = child
222 d[head] = child
223 continue
223 continue
224 return d
224 return d
225 def keys(self):
225 def keys(self):
226 d = self.__children()
226 d = self.__children()
227 return d.keys()
227 return d.keys()
228 def __getitem__(self, key):
228 def __getitem__(self, key):
229 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
229 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
230
230
231 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
231 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
232 """
232 """
233 key = str(key)
233 key = str(key)
234 d = self.__children()
234 d = self.__children()
235 return d[key]
235 return d[key]
236 def __setitem__(self, key, val):
236 def __setitem__(self, key, val):
237 """ You can do wb.foo['My Stuff'] = 12 to create children
237 """ You can do wb.foo['My Stuff'] = 12 to create children
238
238
239 This will create 'My Stuff' as a child of foo (if it does not exist), and
239 This will create 'My Stuff' as a child of foo (if it does not exist), and
240 do .v = 12 assignment.
240 do .v = 12 assignment.
241
241
242 Exception:
242 Exception:
243
243
244 wb.foo['bar'] = 12
244 wb.foo['bar'] = 12
245
245
246 will create a child with headline '@k bar', because bar is a valid python name
246 will create a child with headline '@k bar', because bar is a valid python name
247 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
247 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
248 """
248 """
249 key = str(key)
249 key = str(key)
250 d = self.__children()
250 d = self.__children()
251 if key in d:
251 if key in d:
252 d[key].v = val
252 d[key].v = val
253 return
253 return
254
254
255 if not valid_attribute(key):
255 if not valid_attribute(key):
256 head = key
256 head = key
257 else:
257 else:
258 head = '@k ' + key
258 head = '@k ' + key
259 p = c.createLastChildNode(self.p, head, '')
259 p = c.createLastChildNode(self.p, head, '')
260 LeoNode(p).v = val
260 LeoNode(p).v = val
261
261
262 def ipush(self):
262 def ipush(self):
263 """ Does push-to-ipython on the node """
263 """ Does push-to-ipython on the node """
264 push_from_leo(self)
264 push_from_leo(self)
265
265
266 def go(self):
266 def go(self):
267 """ Set node as current node (to quickly see it in Outline) """
267 """ Set node as current node (to quickly see it in Outline) """
268 c.beginUpdate()
268 c.beginUpdate()
269 try:
269 try:
270 c.setCurrentPosition(self.p)
270 c.setCurrentPosition(self.p)
271 finally:
271 finally:
272 c.endUpdate()
272 c.endUpdate()
273
273
274 def script(self):
274 def script(self):
275 """ Method to get the 'tangled' contents of the node
275 """ Method to get the 'tangled' contents of the node
276
276
277 (parse @others, << section >> references etc.)
277 (parse @others, << section >> references etc.)
278 """
278 """
279 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
279 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
280
280
281 def __get_uA(self):
281 def __get_uA(self):
282 p = self.p
282 p = self.p
283 # Create the uA if necessary.
283 # Create the uA if necessary.
284 if not hasattr(p.v.t,'unknownAttributes'):
284 if not hasattr(p.v.t,'unknownAttributes'):
285 p.v.t.unknownAttributes = {}
285 p.v.t.unknownAttributes = {}
286
286
287 d = p.v.t.unknownAttributes.setdefault('ipython', {})
287 d = p.v.t.unknownAttributes.setdefault('ipython', {})
288 return d
288 return d
289
289
290 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
290 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
291
291
292
292
293 class LeoWorkbook:
293 class LeoWorkbook:
294 """ class for 'advanced' node access
294 """ class for 'advanced' node access
295
295
296 Has attributes for all "discoverable" nodes. Node is discoverable if it
296 Has attributes for all "discoverable" nodes. Node is discoverable if it
297 either
297 either
298
298
299 - has a valid python name (Foo, bar_12)
299 - has a valid python name (Foo, bar_12)
300 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
300 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
301
301
302 """
302 """
303 def __getattr__(self, key):
303 def __getattr__(self, key):
304 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
304 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
305 raise AttributeError
305 raise AttributeError
306 cells = all_cells()
306 cells = all_cells()
307 p = cells.get(key, None)
307 p = cells.get(key, None)
308 if p is None:
308 if p is None:
309 return add_var(key)
309 return add_var(key)
310
310
311 return LeoNode(p)
311 return LeoNode(p)
312
312
313 def __str__(self):
313 def __str__(self):
314 return "<LeoWorkbook>"
314 return "<LeoWorkbook>"
315 def __setattr__(self,key, val):
315 def __setattr__(self,key, val):
316 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
316 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
317
317
318 __repr__ = __str__
318 __repr__ = __str__
319
319
320 def __iter__(self):
320 def __iter__(self):
321 """ Iterate all (even non-exposed) nodes """
321 """ Iterate all (even non-exposed) nodes """
322 cells = all_cells()
322 cells = all_cells()
323 return (LeoNode(p) for p in c.allNodes_iter())
323 return (LeoNode(p) for p in c.allNodes_iter())
324
324
325 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
325 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
326
326
327 def match_h(self, regex):
327 def match_h(self, regex):
328 cmp = re.compile(regex)
328 cmp = re.compile(regex)
329 for node in self:
329 for node in self:
330 if re.match(cmp, node.h, re.IGNORECASE):
330 if re.match(cmp, node.h, re.IGNORECASE):
331 yield node
331 yield node
332 return
332 return
333
333
334 @IPython.generics.complete_object.when_type(LeoWorkbook)
334 @IPython.generics.complete_object.when_type(LeoWorkbook)
335 def workbook_complete(obj, prev):
335 def workbook_complete(obj, prev):
336 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
336 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
337
337
338
338
339 def add_var(varname):
339 def add_var(varname):
340 c.beginUpdate()
340 c.beginUpdate()
341 r = rootnode()
341 r = rootnode()
342 try:
342 try:
343 if r is None:
343 if r is None:
344 p2 = g.findNodeAnywhere(c,varname)
344 p2 = g.findNodeAnywhere(c,varname)
345 else:
345 else:
346 p2 = g.findNodeInChildren(c, r.p, varname)
346 p2 = g.findNodeInChildren(c, r.p, varname)
347 if p2:
347 if p2:
348 return LeoNode(p2)
348 return LeoNode(p2)
349
349
350 if r is not None:
350 if r is not None:
351 p2 = r.p.insertAsLastChild()
351 p2 = r.p.insertAsLastChild()
352
352
353 else:
353 else:
354 p2 = c.currentPosition().insertAfter()
354 p2 = c.currentPosition().insertAfter()
355
355
356 c.setHeadString(p2,varname)
356 c.setHeadString(p2,varname)
357 return LeoNode(p2)
357 return LeoNode(p2)
358 finally:
358 finally:
359 c.endUpdate()
359 c.endUpdate()
360
360
361 def add_file(self,fname):
361 def add_file(self,fname):
362 p2 = c.currentPosition().insertAfter()
362 p2 = c.currentPosition().insertAfter()
363
363
364 push_from_leo = CommandChainDispatcher()
364 push_from_leo = CommandChainDispatcher()
365
365
366 def expose_ileo_push(f, prio = 0):
366 def expose_ileo_push(f, prio = 0):
367 push_from_leo.add(f, prio)
367 push_from_leo.add(f, prio)
368
368
369 def push_ipython_script(node):
369 def push_ipython_script(node):
370 """ Execute the node body in IPython, as if it was entered in interactive prompt """
370 """ Execute the node body in IPython, as if it was entered in interactive prompt """
371 c.beginUpdate()
371 c.beginUpdate()
372 try:
372 try:
373 ohist = ip.IP.output_hist
373 ohist = ip.IP.output_hist
374 hstart = len(ip.IP.input_hist)
374 hstart = len(ip.IP.input_hist)
375 script = node.script()
375 script = node.script()
376
376
377 script = g.splitLines(script + '\n')
378 ip.user_ns['_p'] = node
377 ip.user_ns['_p'] = node
379 ip.runlines(script)
378 ip.runlines(script)
380 ip.user_ns.pop('_p',None)
379 ip.user_ns.pop('_p',None)
381
380
382 has_output = False
381 has_output = False
383 for idx in range(hstart,len(ip.IP.input_hist)):
382 for idx in range(hstart,len(ip.IP.input_hist)):
384 val = ohist.get(idx,None)
383 val = ohist.get(idx,None)
385 if val is None:
384 if val is None:
386 continue
385 continue
387 has_output = True
386 has_output = True
388 inp = ip.IP.input_hist[idx]
387 inp = ip.IP.input_hist[idx]
389 if inp.strip():
388 if inp.strip():
390 es('In: %s' % (inp[:40], ))
389 es('In: %s' % (inp[:40], ))
391
390
392 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
391 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
393
392
394 if not has_output:
393 if not has_output:
395 es('ipy run: %s (%d LL)' %( node.h,len(script)))
394 es('ipy run: %s (%d LL)' %( node.h,len(script)))
396 finally:
395 finally:
397 c.endUpdate()
396 c.endUpdate()
398
397
399
398
400 def eval_body(body):
399 def eval_body(body):
401 try:
400 try:
402 val = ip.ev(body)
401 val = ip.ev(body)
403 except:
402 except:
404 # just use stringlist if it's not completely legal python expression
403 # just use stringlist if it's not completely legal python expression
405 val = IPython.genutils.SList(body.splitlines())
404 val = IPython.genutils.SList(body.splitlines())
406 return val
405 return val
407
406
408 def push_plain_python(node):
407 def push_plain_python(node):
409 if not node.h.endswith('P'):
408 if not node.h.endswith('P'):
410 raise TryNext
409 raise TryNext
411 script = node.script()
410 script = node.script()
412 lines = script.count('\n')
411 lines = script.count('\n')
413 try:
412 try:
414 exec script in ip.user_ns
413 exec script in ip.user_ns
415 except:
414 except:
416 print " -- Exception in script:\n"+script + "\n --"
415 print " -- Exception in script:\n"+script + "\n --"
417 raise
416 raise
418 es('ipy plain: %s (%d LL)' % (node.h,lines))
417 es('ipy plain: %s (%d LL)' % (node.h,lines))
419
418
420
419
421 def push_cl_node(node):
420 def push_cl_node(node):
422 """ If node starts with @cl, eval it
421 """ If node starts with @cl, eval it
423
422
424 The result is put as last child of @ipy-results node, if it exists
423 The result is put as last child of @ipy-results node, if it exists
425 """
424 """
426 if not node.b.startswith('@cl'):
425 if not node.b.startswith('@cl'):
427 raise TryNext
426 raise TryNext
428
427
429 p2 = g.findNodeAnywhere(c,'@ipy-results')
428 p2 = g.findNodeAnywhere(c,'@ipy-results')
430 val = node.v
429 val = node.v
431 if p2:
430 if p2:
432 es("=> @ipy-results")
431 es("=> @ipy-results")
433 LeoNode(p2).v = val
432 LeoNode(p2).v = val
434 es(val)
433 es(val)
435
434
436 def push_ev_node(node):
435 def push_ev_node(node):
437 """ If headline starts with @ev, eval it and put result in body """
436 """ If headline starts with @ev, eval it and put result in body """
438 if not node.h.startswith('@ev '):
437 if not node.h.startswith('@ev '):
439 raise TryNext
438 raise TryNext
440 expr = node.h.lstrip('@ev ')
439 expr = node.h.lstrip('@ev ')
441 es('ipy eval ' + expr)
440 es('ipy eval ' + expr)
442 res = ip.ev(expr)
441 res = ip.ev(expr)
443 node.v = res
442 node.v = res
444
443
445
444
446 def push_position_from_leo(p):
445 def push_position_from_leo(p):
447 push_from_leo(LeoNode(p))
446 push_from_leo(LeoNode(p))
448
447
449 @generic
448 @generic
450 def edit_object_in_leo(obj, varname):
449 def edit_object_in_leo(obj, varname):
451 """ Make it @cl node so it can be pushed back directly by alt+I """
450 """ Make it @cl node so it can be pushed back directly by alt+I """
452 node = add_var(varname)
451 node = add_var(varname)
453 formatted = format_for_leo(obj)
452 formatted = format_for_leo(obj)
454 if not formatted.startswith('@cl'):
453 if not formatted.startswith('@cl'):
455 formatted = '@cl\n' + formatted
454 formatted = '@cl\n' + formatted
456 node.b = formatted
455 node.b = formatted
457 node.go()
456 node.go()
458
457
459 @edit_object_in_leo.when_type(IPython.macro.Macro)
458 @edit_object_in_leo.when_type(IPython.macro.Macro)
460 def edit_macro(obj,varname):
459 def edit_macro(obj,varname):
461 bod = '_ip.defmacro("""\\\n' + obj.value + '""")'
460 bod = '_ip.defmacro("""\\\n' + obj.value + '""")'
462 node = add_var('Macro_' + varname)
461 node = add_var('Macro_' + varname)
463 node.b = bod
462 node.b = bod
464 node.go()
463 node.go()
465
464
466 def get_history(hstart = 0):
465 def get_history(hstart = 0):
467 res = []
466 res = []
468 ohist = ip.IP.output_hist
467 ohist = ip.IP.output_hist
469
468
470 for idx in range(hstart, len(ip.IP.input_hist)):
469 for idx in range(hstart, len(ip.IP.input_hist)):
471 val = ohist.get(idx,None)
470 val = ohist.get(idx,None)
472 has_output = True
471 has_output = True
473 inp = ip.IP.input_hist_raw[idx]
472 inp = ip.IP.input_hist_raw[idx]
474 if inp.strip():
473 if inp.strip():
475 res.append('In [%d]: %s' % (idx, inp))
474 res.append('In [%d]: %s' % (idx, inp))
476 if val:
475 if val:
477 res.append(pprint.pformat(val))
476 res.append(pprint.pformat(val))
478 res.append('\n')
477 res.append('\n')
479 return ''.join(res)
478 return ''.join(res)
480
479
481
480
482 def lee_f(self,s):
481 def lee_f(self,s):
483 """ Open file(s)/objects in Leo
482 """ Open file(s)/objects in Leo
484
483
485 - %lee hist -> open full session history in leo
484 - %lee hist -> open full session history in leo
486 - Takes an object. l = [1,2,"hello"]; %lee l. Alt+I in leo pushes the object back
485 - Takes an object. l = [1,2,"hello"]; %lee l. Alt+I in leo pushes the object back
487 - Takes an mglob pattern, e.g. '%lee *.cpp' or %lee 'rec:*.cpp'
486 - Takes an mglob pattern, e.g. '%lee *.cpp' or %lee 'rec:*.cpp'
488 - Takes input history indices: %lee 4 6-8 10 12-47
487 - Takes input history indices: %lee 4 6-8 10 12-47
489 """
488 """
490 import os
489 import os
491
490
492 c.beginUpdate()
491 c.beginUpdate()
493 try:
492 try:
494 if s == 'hist':
493 if s == 'hist':
495 wb.ipython_history.b = get_history()
494 wb.ipython_history.b = get_history()
496 wb.ipython_history.go()
495 wb.ipython_history.go()
497 return
496 return
498
497
499
498
500 if s and s[0].isdigit():
499 if s and s[0].isdigit():
501 # numbers; push input slices to leo
500 # numbers; push input slices to leo
502 lines = self.extract_input_slices(s.strip().split(), True)
501 lines = self.extract_input_slices(s.strip().split(), True)
503 v = add_var('stored_ipython_input')
502 v = add_var('stored_ipython_input')
504 v.b = '\n'.join(lines)
503 v.b = '\n'.join(lines)
505 return
504 return
506
505
507
506
508 # try editing the object directly
507 # try editing the object directly
509 obj = ip.user_ns.get(s, None)
508 obj = ip.user_ns.get(s, None)
510 if obj is not None:
509 if obj is not None:
511 edit_object_in_leo(obj,s)
510 edit_object_in_leo(obj,s)
512 return
511 return
513
512
514
513
515 # if it's not object, it's a file name / mglob pattern
514 # if it's not object, it's a file name / mglob pattern
516 from IPython.external import mglob
515 from IPython.external import mglob
517
516
518 files = (os.path.abspath(f) for f in mglob.expand(s))
517 files = (os.path.abspath(f) for f in mglob.expand(s))
519 for fname in files:
518 for fname in files:
520 p = g.findNodeAnywhere(c,'@auto ' + fname)
519 p = g.findNodeAnywhere(c,'@auto ' + fname)
521 if not p:
520 if not p:
522 p = c.currentPosition().insertAfter()
521 p = c.currentPosition().insertAfter()
523
522
524 p.setHeadString('@auto ' + fname)
523 p.setHeadString('@auto ' + fname)
525 if os.path.isfile(fname):
524 if os.path.isfile(fname):
526 c.setBodyString(p,open(fname).read())
525 c.setBodyString(p,open(fname).read())
527 c.selectPosition(p)
526 c.selectPosition(p)
528 print "Editing file(s), press ctrl+shift+w in Leo to write @auto nodes"
527 print "Editing file(s), press ctrl+shift+w in Leo to write @auto nodes"
529 finally:
528 finally:
530 c.endUpdate()
529 c.endUpdate()
531
530
532
531
533
532
534 def leoref_f(self,s):
533 def leoref_f(self,s):
535 """ Quick reference for ILeo """
534 """ Quick reference for ILeo """
536 import textwrap
535 import textwrap
537 print textwrap.dedent("""\
536 print textwrap.dedent("""\
538 %leoe file/object - open file / object in leo
537 %leoe file/object - open file / object in leo
539 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
538 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
540 wb.foo.v = 12 - assign to body of node foo
539 wb.foo.v = 12 - assign to body of node foo
541 wb.foo.b - read or write the body of node foo
540 wb.foo.b - read or write the body of node foo
542 wb.foo.l - body of node foo as string list
541 wb.foo.l - body of node foo as string list
543
542
544 for el in wb.foo:
543 for el in wb.foo:
545 print el.v
544 print el.v
546
545
547 """
546 """
548 )
547 )
549
548
550
549
551
550
552 def mb_f(self, arg):
551 def mb_f(self, arg):
553 """ Execute leo minibuffer commands
552 """ Execute leo minibuffer commands
554
553
555 Example:
554 Example:
556 mb save-to-file
555 mb save-to-file
557 """
556 """
558 c.executeMinibufferCommand(arg)
557 c.executeMinibufferCommand(arg)
559
558
560 def mb_completer(self,event):
559 def mb_completer(self,event):
561 """ Custom completer for minibuffer """
560 """ Custom completer for minibuffer """
562 cmd_param = event.line.split()
561 cmd_param = event.line.split()
563 if event.line.endswith(' '):
562 if event.line.endswith(' '):
564 cmd_param.append('')
563 cmd_param.append('')
565 if len(cmd_param) > 2:
564 if len(cmd_param) > 2:
566 return ip.IP.Completer.file_matches(event.symbol)
565 return ip.IP.Completer.file_matches(event.symbol)
567 cmds = c.commandsDict.keys()
566 cmds = c.commandsDict.keys()
568 cmds.sort()
567 cmds.sort()
569 return cmds
568 return cmds
570
569
571 def show_welcome():
570 def show_welcome():
572 print "------------------"
571 print "------------------"
573 print "Welcome to Leo-enabled IPython session!"
572 print "Welcome to Leo-enabled IPython session!"
574 print "Try %leoref for quick reference."
573 print "Try %leoref for quick reference."
575 import IPython.platutils
574 import IPython.platutils
576 IPython.platutils.set_term_title('ILeo')
575 IPython.platutils.set_term_title('ILeo')
577 IPython.platutils.freeze_term_title()
576 IPython.platutils.freeze_term_title()
578
577
579 def run_leo_startup_node():
578 def run_leo_startup_node():
580 p = g.findNodeAnywhere(c,'@ipy-startup')
579 p = g.findNodeAnywhere(c,'@ipy-startup')
581 if p:
580 if p:
582 print "Running @ipy-startup nodes"
581 print "Running @ipy-startup nodes"
583 for n in LeoNode(p):
582 for n in LeoNode(p):
584 push_from_leo(n)
583 push_from_leo(n)
585
584
586
585
@@ -1,597 +1,608 b''
1 ''' IPython customization API
1 ''' IPython customization API
2
2
3 Your one-stop module for configuring & extending ipython
3 Your one-stop module for configuring & extending ipython
4
4
5 The API will probably break when ipython 1.0 is released, but so
5 The API will probably break when ipython 1.0 is released, but so
6 will the other configuration method (rc files).
6 will the other configuration method (rc files).
7
7
8 All names prefixed by underscores are for internal use, not part
8 All names prefixed by underscores are for internal use, not part
9 of the public api.
9 of the public api.
10
10
11 Below is an example that you can just put to a module and import from ipython.
11 Below is an example that you can just put to a module and import from ipython.
12
12
13 A good practice is to install the config script below as e.g.
13 A good practice is to install the config script below as e.g.
14
14
15 ~/.ipython/my_private_conf.py
15 ~/.ipython/my_private_conf.py
16
16
17 And do
17 And do
18
18
19 import_mod my_private_conf
19 import_mod my_private_conf
20
20
21 in ~/.ipython/ipythonrc
21 in ~/.ipython/ipythonrc
22
22
23 That way the module is imported at startup and you can have all your
23 That way the module is imported at startup and you can have all your
24 personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME
24 personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME
25 stuff) in there.
25 stuff) in there.
26
26
27 -----------------------------------------------
27 -----------------------------------------------
28 import IPython.ipapi
28 import IPython.ipapi
29 ip = IPython.ipapi.get()
29 ip = IPython.ipapi.get()
30
30
31 def ankka_f(self, arg):
31 def ankka_f(self, arg):
32 print "Ankka",self,"says uppercase:",arg.upper()
32 print "Ankka",self,"says uppercase:",arg.upper()
33
33
34 ip.expose_magic("ankka",ankka_f)
34 ip.expose_magic("ankka",ankka_f)
35
35
36 ip.magic('alias sayhi echo "Testing, hi ok"')
36 ip.magic('alias sayhi echo "Testing, hi ok"')
37 ip.magic('alias helloworld echo "Hello world"')
37 ip.magic('alias helloworld echo "Hello world"')
38 ip.system('pwd')
38 ip.system('pwd')
39
39
40 ip.ex('import re')
40 ip.ex('import re')
41 ip.ex("""
41 ip.ex("""
42 def funcci(a,b):
42 def funcci(a,b):
43 print a+b
43 print a+b
44 print funcci(3,4)
44 print funcci(3,4)
45 """)
45 """)
46 ip.ex("funcci(348,9)")
46 ip.ex("funcci(348,9)")
47
47
48 def jed_editor(self,filename, linenum=None):
48 def jed_editor(self,filename, linenum=None):
49 print "Calling my own editor, jed ... via hook!"
49 print "Calling my own editor, jed ... via hook!"
50 import os
50 import os
51 if linenum is None: linenum = 0
51 if linenum is None: linenum = 0
52 os.system('jed +%d %s' % (linenum, filename))
52 os.system('jed +%d %s' % (linenum, filename))
53 print "exiting jed"
53 print "exiting jed"
54
54
55 ip.set_hook('editor',jed_editor)
55 ip.set_hook('editor',jed_editor)
56
56
57 o = ip.options
57 o = ip.options
58 o.autocall = 2 # FULL autocall mode
58 o.autocall = 2 # FULL autocall mode
59
59
60 print "done!"
60 print "done!"
61 '''
61 '''
62
62
63 # stdlib imports
63 # stdlib imports
64 import __builtin__
64 import __builtin__
65 import sys
65 import sys
66
66
67 try: # Python 2.3 compatibility
67 try: # Python 2.3 compatibility
68 set
68 set
69 except NameError:
69 except NameError:
70 import sets
70 import sets
71 set = sets.Set
71 set = sets.Set
72
72
73 # our own
73 # our own
74 #from IPython.genutils import warn,error
74 #from IPython.genutils import warn,error
75
75
76 class TryNext(Exception):
76 class TryNext(Exception):
77 """Try next hook exception.
77 """Try next hook exception.
78
78
79 Raise this in your hook function to indicate that the next hook handler
79 Raise this in your hook function to indicate that the next hook handler
80 should be used to handle the operation. If you pass arguments to the
80 should be used to handle the operation. If you pass arguments to the
81 constructor those arguments will be used by the next hook instead of the
81 constructor those arguments will be used by the next hook instead of the
82 original ones.
82 original ones.
83 """
83 """
84
84
85 def __init__(self, *args, **kwargs):
85 def __init__(self, *args, **kwargs):
86 self.args = args
86 self.args = args
87 self.kwargs = kwargs
87 self.kwargs = kwargs
88
88
89 class UsageError(Exception):
89 class UsageError(Exception):
90 """ Error in magic function arguments, etc.
90 """ Error in magic function arguments, etc.
91
91
92 Something that probably won't warrant a full traceback, but should
92 Something that probably won't warrant a full traceback, but should
93 nevertheless interrupt a macro / batch file.
93 nevertheless interrupt a macro / batch file.
94 """
94 """
95
95
96 class IPyAutocall:
96 class IPyAutocall:
97 """ Instances of this class are always autocalled
97 """ Instances of this class are always autocalled
98
98
99 This happens regardless of 'autocall' variable state. Use this to
99 This happens regardless of 'autocall' variable state. Use this to
100 develop macro-like mechanisms.
100 develop macro-like mechanisms.
101 """
101 """
102
102
103 def set_ip(self,ip):
103 def set_ip(self,ip):
104 """ Will be used to set _ip point to current ipython instance b/f call
104 """ Will be used to set _ip point to current ipython instance b/f call
105
105
106 Override this method if you don't want this to happen.
106 Override this method if you don't want this to happen.
107
107
108 """
108 """
109 self._ip = ip
109 self._ip = ip
110
110
111
111
112 # contains the most recently instantiated IPApi
112 # contains the most recently instantiated IPApi
113
113
114 class IPythonNotRunning:
114 class IPythonNotRunning:
115 """Dummy do-nothing class.
115 """Dummy do-nothing class.
116
116
117 Instances of this class return a dummy attribute on all accesses, which
117 Instances of this class return a dummy attribute on all accesses, which
118 can be called and warns. This makes it easier to write scripts which use
118 can be called and warns. This makes it easier to write scripts which use
119 the ipapi.get() object for informational purposes to operate both with and
119 the ipapi.get() object for informational purposes to operate both with and
120 without ipython. Obviously code which uses the ipython object for
120 without ipython. Obviously code which uses the ipython object for
121 computations will not work, but this allows a wider range of code to
121 computations will not work, but this allows a wider range of code to
122 transparently work whether ipython is being used or not."""
122 transparently work whether ipython is being used or not."""
123
123
124 def __init__(self,warn=True):
124 def __init__(self,warn=True):
125 if warn:
125 if warn:
126 self.dummy = self._dummy_warn
126 self.dummy = self._dummy_warn
127 else:
127 else:
128 self.dummy = self._dummy_silent
128 self.dummy = self._dummy_silent
129
129
130 def __str__(self):
130 def __str__(self):
131 return "<IPythonNotRunning>"
131 return "<IPythonNotRunning>"
132
132
133 __repr__ = __str__
133 __repr__ = __str__
134
134
135 def __getattr__(self,name):
135 def __getattr__(self,name):
136 return self.dummy
136 return self.dummy
137
137
138 def _dummy_warn(self,*args,**kw):
138 def _dummy_warn(self,*args,**kw):
139 """Dummy function, which doesn't do anything but warn."""
139 """Dummy function, which doesn't do anything but warn."""
140
140
141 print ("IPython is not running, this is a dummy no-op function")
141 print ("IPython is not running, this is a dummy no-op function")
142
142
143 def _dummy_silent(self,*args,**kw):
143 def _dummy_silent(self,*args,**kw):
144 """Dummy function, which doesn't do anything and emits no warnings."""
144 """Dummy function, which doesn't do anything and emits no warnings."""
145 pass
145 pass
146
146
147 _recent = None
147 _recent = None
148
148
149
149
150 def get(allow_dummy=False,dummy_warn=True):
150 def get(allow_dummy=False,dummy_warn=True):
151 """Get an IPApi object.
151 """Get an IPApi object.
152
152
153 If allow_dummy is true, returns an instance of IPythonNotRunning
153 If allow_dummy is true, returns an instance of IPythonNotRunning
154 instead of None if not running under IPython.
154 instead of None if not running under IPython.
155
155
156 If dummy_warn is false, the dummy instance will be completely silent.
156 If dummy_warn is false, the dummy instance will be completely silent.
157
157
158 Running this should be the first thing you do when writing extensions that
158 Running this should be the first thing you do when writing extensions that
159 can be imported as normal modules. You can then direct all the
159 can be imported as normal modules. You can then direct all the
160 configuration operations against the returned object.
160 configuration operations against the returned object.
161 """
161 """
162 global _recent
162 global _recent
163 if allow_dummy and not _recent:
163 if allow_dummy and not _recent:
164 _recent = IPythonNotRunning(dummy_warn)
164 _recent = IPythonNotRunning(dummy_warn)
165 return _recent
165 return _recent
166
166
167 class IPApi:
167 class IPApi:
168 """ The actual API class for configuring IPython
168 """ The actual API class for configuring IPython
169
169
170 You should do all of the IPython configuration by getting an IPApi object
170 You should do all of the IPython configuration by getting an IPApi object
171 with IPython.ipapi.get() and using the attributes and methods of the
171 with IPython.ipapi.get() and using the attributes and methods of the
172 returned object."""
172 returned object."""
173
173
174 def __init__(self,ip):
174 def __init__(self,ip):
175
175
176 # All attributes exposed here are considered to be the public API of
176 # All attributes exposed here are considered to be the public API of
177 # IPython. As needs dictate, some of these may be wrapped as
177 # IPython. As needs dictate, some of these may be wrapped as
178 # properties.
178 # properties.
179
179
180 self.magic = ip.ipmagic
180 self.magic = ip.ipmagic
181
181
182 self.system = ip.system
182 self.system = ip.system
183
183
184 self.set_hook = ip.set_hook
184 self.set_hook = ip.set_hook
185
185
186 self.set_custom_exc = ip.set_custom_exc
186 self.set_custom_exc = ip.set_custom_exc
187
187
188 self.user_ns = ip.user_ns
188 self.user_ns = ip.user_ns
189 self.user_ns['_ip'] = self
189 self.user_ns['_ip'] = self
190
190
191 self.set_crash_handler = ip.set_crash_handler
191 self.set_crash_handler = ip.set_crash_handler
192
192
193 # Session-specific data store, which can be used to store
193 # Session-specific data store, which can be used to store
194 # data that should persist through the ipython session.
194 # data that should persist through the ipython session.
195 self.meta = ip.meta
195 self.meta = ip.meta
196
196
197 # The ipython instance provided
197 # The ipython instance provided
198 self.IP = ip
198 self.IP = ip
199
199
200 self.extensions = {}
200 self.extensions = {}
201
201
202 self.dbg = DebugTools(self)
202 self.dbg = DebugTools(self)
203
203
204 global _recent
204 global _recent
205 _recent = self
205 _recent = self
206
206
207 # Use a property for some things which are added to the instance very
207 # Use a property for some things which are added to the instance very
208 # late. I don't have time right now to disentangle the initialization
208 # late. I don't have time right now to disentangle the initialization
209 # order issues, so a property lets us delay item extraction while
209 # order issues, so a property lets us delay item extraction while
210 # providing a normal attribute API.
210 # providing a normal attribute API.
211 def get_db(self):
211 def get_db(self):
212 """A handle to persistent dict-like database (a PickleShareDB object)"""
212 """A handle to persistent dict-like database (a PickleShareDB object)"""
213 return self.IP.db
213 return self.IP.db
214
214
215 db = property(get_db,None,None,get_db.__doc__)
215 db = property(get_db,None,None,get_db.__doc__)
216
216
217 def get_options(self):
217 def get_options(self):
218 """All configurable variables."""
218 """All configurable variables."""
219
219
220 # catch typos by disabling new attribute creation. If new attr creation
220 # catch typos by disabling new attribute creation. If new attr creation
221 # is in fact wanted (e.g. when exposing new options), do allow_new_attr(True)
221 # is in fact wanted (e.g. when exposing new options), do allow_new_attr(True)
222 # for the received rc struct.
222 # for the received rc struct.
223
223
224 self.IP.rc.allow_new_attr(False)
224 self.IP.rc.allow_new_attr(False)
225 return self.IP.rc
225 return self.IP.rc
226
226
227 options = property(get_options,None,None,get_options.__doc__)
227 options = property(get_options,None,None,get_options.__doc__)
228
228
229 def expose_magic(self,magicname, func):
229 def expose_magic(self,magicname, func):
230 ''' Expose own function as magic function for ipython
230 ''' Expose own function as magic function for ipython
231
231
232 def foo_impl(self,parameter_s=''):
232 def foo_impl(self,parameter_s=''):
233 """My very own magic!. (Use docstrings, IPython reads them)."""
233 """My very own magic!. (Use docstrings, IPython reads them)."""
234 print 'Magic function. Passed parameter is between < >: <'+parameter_s+'>'
234 print 'Magic function. Passed parameter is between < >: <'+parameter_s+'>'
235 print 'The self object is:',self
235 print 'The self object is:',self
236
236
237 ipapi.expose_magic("foo",foo_impl)
237 ipapi.expose_magic("foo",foo_impl)
238 '''
238 '''
239
239
240 import new
240 import new
241 im = new.instancemethod(func,self.IP, self.IP.__class__)
241 im = new.instancemethod(func,self.IP, self.IP.__class__)
242 old = getattr(self.IP, "magic_" + magicname, None)
242 old = getattr(self.IP, "magic_" + magicname, None)
243 if old:
243 if old:
244 self.dbg.debug_stack("Magic redefinition '%s', old %s" % (magicname,
244 self.dbg.debug_stack("Magic redefinition '%s', old %s" % (magicname,
245 old))
245 old))
246
246
247 setattr(self.IP, "magic_" + magicname, im)
247 setattr(self.IP, "magic_" + magicname, im)
248
248
249 def ex(self,cmd):
249 def ex(self,cmd):
250 """ Execute a normal python statement in user namespace """
250 """ Execute a normal python statement in user namespace """
251 exec cmd in self.user_ns
251 exec cmd in self.user_ns
252
252
253 def ev(self,expr):
253 def ev(self,expr):
254 """ Evaluate python expression expr in user namespace
254 """ Evaluate python expression expr in user namespace
255
255
256 Returns the result of evaluation"""
256 Returns the result of evaluation"""
257 return eval(expr,self.user_ns)
257 return eval(expr,self.user_ns)
258
258
259 def runlines(self,lines):
259 def runlines(self,lines):
260 """ Run the specified lines in interpreter, honoring ipython directives.
260 """ Run the specified lines in interpreter, honoring ipython directives.
261
261
262 This allows %magic and !shell escape notations.
262 This allows %magic and !shell escape notations.
263
263
264 Takes either all lines in one string or list of lines.
264 Takes either all lines in one string or list of lines.
265 """
265 """
266
266
267 def cleanup_ipy_script(script):
267 def cleanup_ipy_script(script):
268 """ Make a script safe for _ip.runlines()
268 """ Make a script safe for _ip.runlines()
269
269
270 - Removes empty lines
270 - Removes empty lines
271 - Suffixes all indented blocks that end with unindented lines with empty lines
271 - Suffixes all indented blocks that end with unindented lines with empty lines
272
272
273 """
273 """
274 res = []
274 res = []
275 lines = script.splitlines()
275 lines = script.splitlines()
276
276 level = 0
277 level = 0
277 for l in lines:
278 for l in lines:
278 lstripped = l.lstrip()
279 lstripped = l.lstrip()
279 stripped = l.strip()
280 stripped = l.strip()
280 if not stripped:
281 if not stripped:
281 continue
282 continue
282 newlevel = len(l) - len(lstripped)
283 newlevel = len(l) - len(lstripped)
283 if level > 0 and newlevel == 0 and not stripped.endswith(':'):
284 def is_secondary_block_start(s):
285 if not s.endswith(':'):
286 return False
287 if (s.startswith('elif') or
288 s.startswith('else') or
289 s.startswith('except') or
290 s.startswith('finally')):
291 return True
292
293 if level > 0 and newlevel == 0 and not is_secondary_block_start(stripped):
284 # add empty line
294 # add empty line
285 res.append('')
295 res.append('')
296
286 res.append(l)
297 res.append(l)
287 level = newlevel
298 level = newlevel
288 return '\n'.join(res) + '\n'
299 return '\n'.join(res) + '\n'
289
300
290 if isinstance(lines,basestring):
301 if isinstance(lines,basestring):
291 script = lines
302 script = lines
292 else:
303 else:
293 script = '\n'.join(lines)
304 script = '\n'.join(lines)
294 clean=cleanup_ipy_script(script)
305 clean=cleanup_ipy_script(script)
295
306 # print "_ip.runlines() script:\n",clean #dbg
296 self.IP.runlines(clean)
307 self.IP.runlines(clean)
297 def to_user_ns(self,vars, interactive = True):
308 def to_user_ns(self,vars, interactive = True):
298 """Inject a group of variables into the IPython user namespace.
309 """Inject a group of variables into the IPython user namespace.
299
310
300 Inputs:
311 Inputs:
301
312
302 - vars: string with variable names separated by whitespace, or a
313 - vars: string with variable names separated by whitespace, or a
303 dict with name/value pairs.
314 dict with name/value pairs.
304
315
305 - interactive: if True (default), the var will be listed with
316 - interactive: if True (default), the var will be listed with
306 %whos et. al.
317 %whos et. al.
307
318
308 This utility routine is meant to ease interactive debugging work,
319 This utility routine is meant to ease interactive debugging work,
309 where you want to easily propagate some internal variable in your code
320 where you want to easily propagate some internal variable in your code
310 up to the interactive namespace for further exploration.
321 up to the interactive namespace for further exploration.
311
322
312 When you run code via %run, globals in your script become visible at
323 When you run code via %run, globals in your script become visible at
313 the interactive prompt, but this doesn't happen for locals inside your
324 the interactive prompt, but this doesn't happen for locals inside your
314 own functions and methods. Yet when debugging, it is common to want
325 own functions and methods. Yet when debugging, it is common to want
315 to explore some internal variables further at the interactive propmt.
326 to explore some internal variables further at the interactive propmt.
316
327
317 Examples:
328 Examples:
318
329
319 To use this, you first must obtain a handle on the ipython object as
330 To use this, you first must obtain a handle on the ipython object as
320 indicated above, via:
331 indicated above, via:
321
332
322 import IPython.ipapi
333 import IPython.ipapi
323 ip = IPython.ipapi.get()
334 ip = IPython.ipapi.get()
324
335
325 Once this is done, inside a routine foo() where you want to expose
336 Once this is done, inside a routine foo() where you want to expose
326 variables x and y, you do the following:
337 variables x and y, you do the following:
327
338
328 def foo():
339 def foo():
329 ...
340 ...
330 x = your_computation()
341 x = your_computation()
331 y = something_else()
342 y = something_else()
332
343
333 # This pushes x and y to the interactive prompt immediately, even
344 # This pushes x and y to the interactive prompt immediately, even
334 # if this routine crashes on the next line after:
345 # if this routine crashes on the next line after:
335 ip.to_user_ns('x y')
346 ip.to_user_ns('x y')
336 ...
347 ...
337
348
338 # To expose *ALL* the local variables from the function, use:
349 # To expose *ALL* the local variables from the function, use:
339 ip.to_user_ns(locals())
350 ip.to_user_ns(locals())
340
351
341 ...
352 ...
342 # return
353 # return
343
354
344
355
345 If you need to rename variables, the dict input makes it easy. For
356 If you need to rename variables, the dict input makes it easy. For
346 example, this call exposes variables 'foo' as 'x' and 'bar' as 'y'
357 example, this call exposes variables 'foo' as 'x' and 'bar' as 'y'
347 in IPython user namespace:
358 in IPython user namespace:
348
359
349 ip.to_user_ns(dict(x=foo,y=bar))
360 ip.to_user_ns(dict(x=foo,y=bar))
350 """
361 """
351
362
352 # print 'vars given:',vars # dbg
363 # print 'vars given:',vars # dbg
353
364
354 # We need a dict of name/value pairs to do namespace updates.
365 # We need a dict of name/value pairs to do namespace updates.
355 if isinstance(vars,dict):
366 if isinstance(vars,dict):
356 # If a dict was given, no need to change anything.
367 # If a dict was given, no need to change anything.
357 vdict = vars
368 vdict = vars
358 elif isinstance(vars,basestring):
369 elif isinstance(vars,basestring):
359 # If a string with names was given, get the caller's frame to
370 # If a string with names was given, get the caller's frame to
360 # evaluate the given names in
371 # evaluate the given names in
361 cf = sys._getframe(1)
372 cf = sys._getframe(1)
362 vdict = {}
373 vdict = {}
363 for name in vars.split():
374 for name in vars.split():
364 try:
375 try:
365 vdict[name] = eval(name,cf.f_globals,cf.f_locals)
376 vdict[name] = eval(name,cf.f_globals,cf.f_locals)
366 except:
377 except:
367 print ('could not get var. %s from %s' %
378 print ('could not get var. %s from %s' %
368 (name,cf.f_code.co_name))
379 (name,cf.f_code.co_name))
369 else:
380 else:
370 raise ValueError('vars must be a string or a dict')
381 raise ValueError('vars must be a string or a dict')
371
382
372 # Propagate variables to user namespace
383 # Propagate variables to user namespace
373 self.user_ns.update(vdict)
384 self.user_ns.update(vdict)
374
385
375 # And configure interactive visibility
386 # And configure interactive visibility
376 config_ns = self.IP.user_config_ns
387 config_ns = self.IP.user_config_ns
377 if interactive:
388 if interactive:
378 for name,val in vdict.iteritems():
389 for name,val in vdict.iteritems():
379 config_ns.pop(name,None)
390 config_ns.pop(name,None)
380 else:
391 else:
381 for name,val in vdict.iteritems():
392 for name,val in vdict.iteritems():
382 config_ns[name] = val
393 config_ns[name] = val
383
394
384
395
385 def expand_alias(self,line):
396 def expand_alias(self,line):
386 """ Expand an alias in the command line
397 """ Expand an alias in the command line
387
398
388 Returns the provided command line, possibly with the first word
399 Returns the provided command line, possibly with the first word
389 (command) translated according to alias expansion rules.
400 (command) translated according to alias expansion rules.
390
401
391 [ipython]|16> _ip.expand_aliases("np myfile.txt")
402 [ipython]|16> _ip.expand_aliases("np myfile.txt")
392 <16> 'q:/opt/np/notepad++.exe myfile.txt'
403 <16> 'q:/opt/np/notepad++.exe myfile.txt'
393 """
404 """
394
405
395 pre,fn,rest = self.IP.split_user_input(line)
406 pre,fn,rest = self.IP.split_user_input(line)
396 res = pre + self.IP.expand_aliases(fn,rest)
407 res = pre + self.IP.expand_aliases(fn,rest)
397 return res
408 return res
398
409
399 def itpl(self, s, depth = 1):
410 def itpl(self, s, depth = 1):
400 """ Expand Itpl format string s.
411 """ Expand Itpl format string s.
401
412
402 Only callable from command line (i.e. prefilter results);
413 Only callable from command line (i.e. prefilter results);
403 If you use in your scripts, you need to use a bigger depth!
414 If you use in your scripts, you need to use a bigger depth!
404 """
415 """
405 return self.IP.var_expand(s, depth)
416 return self.IP.var_expand(s, depth)
406
417
407 def defalias(self, name, cmd):
418 def defalias(self, name, cmd):
408 """ Define a new alias
419 """ Define a new alias
409
420
410 _ip.defalias('bb','bldmake bldfiles')
421 _ip.defalias('bb','bldmake bldfiles')
411
422
412 Creates a new alias named 'bb' in ipython user namespace
423 Creates a new alias named 'bb' in ipython user namespace
413 """
424 """
414
425
415 self.dbg.check_hotname(name)
426 self.dbg.check_hotname(name)
416
427
417
428
418 if name in self.IP.alias_table:
429 if name in self.IP.alias_table:
419 self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')" %
430 self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')" %
420 (name, cmd, self.IP.alias_table[name]))
431 (name, cmd, self.IP.alias_table[name]))
421
432
422
433
423 if callable(cmd):
434 if callable(cmd):
424 self.IP.alias_table[name] = cmd
435 self.IP.alias_table[name] = cmd
425 import IPython.shadowns
436 import IPython.shadowns
426 setattr(IPython.shadowns, name,cmd)
437 setattr(IPython.shadowns, name,cmd)
427 return
438 return
428
439
429 if isinstance(cmd,basestring):
440 if isinstance(cmd,basestring):
430 nargs = cmd.count('%s')
441 nargs = cmd.count('%s')
431 if nargs>0 and cmd.find('%l')>=0:
442 if nargs>0 and cmd.find('%l')>=0:
432 raise Exception('The %s and %l specifiers are mutually exclusive '
443 raise Exception('The %s and %l specifiers are mutually exclusive '
433 'in alias definitions.')
444 'in alias definitions.')
434
445
435 self.IP.alias_table[name] = (nargs,cmd)
446 self.IP.alias_table[name] = (nargs,cmd)
436 return
447 return
437
448
438 # just put it in - it's probably (0,'foo')
449 # just put it in - it's probably (0,'foo')
439 self.IP.alias_table[name] = cmd
450 self.IP.alias_table[name] = cmd
440
451
441 def defmacro(self, *args):
452 def defmacro(self, *args):
442 """ Define a new macro
453 """ Define a new macro
443
454
444 2 forms of calling:
455 2 forms of calling:
445
456
446 mac = _ip.defmacro('print "hello"\nprint "world"')
457 mac = _ip.defmacro('print "hello"\nprint "world"')
447
458
448 (doesn't put the created macro on user namespace)
459 (doesn't put the created macro on user namespace)
449
460
450 _ip.defmacro('build', 'bldmake bldfiles\nabld build winscw udeb')
461 _ip.defmacro('build', 'bldmake bldfiles\nabld build winscw udeb')
451
462
452 (creates a macro named 'build' in user namespace)
463 (creates a macro named 'build' in user namespace)
453 """
464 """
454
465
455 import IPython.macro
466 import IPython.macro
456
467
457 if len(args) == 1:
468 if len(args) == 1:
458 return IPython.macro.Macro(args[0])
469 return IPython.macro.Macro(args[0])
459 elif len(args) == 2:
470 elif len(args) == 2:
460 self.user_ns[args[0]] = IPython.macro.Macro(args[1])
471 self.user_ns[args[0]] = IPython.macro.Macro(args[1])
461 else:
472 else:
462 return Exception("_ip.defmacro must be called with 1 or 2 arguments")
473 return Exception("_ip.defmacro must be called with 1 or 2 arguments")
463
474
464 def set_next_input(self, s):
475 def set_next_input(self, s):
465 """ Sets the 'default' input string for the next command line.
476 """ Sets the 'default' input string for the next command line.
466
477
467 Requires readline.
478 Requires readline.
468
479
469 Example:
480 Example:
470
481
471 [D:\ipython]|1> _ip.set_next_input("Hello Word")
482 [D:\ipython]|1> _ip.set_next_input("Hello Word")
472 [D:\ipython]|2> Hello Word_ # cursor is here
483 [D:\ipython]|2> Hello Word_ # cursor is here
473 """
484 """
474
485
475 self.IP.rl_next_input = s
486 self.IP.rl_next_input = s
476
487
477 def load(self, mod):
488 def load(self, mod):
478 """ Load an extension.
489 """ Load an extension.
479
490
480 Some modules should (or must) be 'load()':ed, rather than just imported.
491 Some modules should (or must) be 'load()':ed, rather than just imported.
481
492
482 Loading will do:
493 Loading will do:
483
494
484 - run init_ipython(ip)
495 - run init_ipython(ip)
485 - run ipython_firstrun(ip)
496 - run ipython_firstrun(ip)
486
497
487 """
498 """
488 if mod in self.extensions:
499 if mod in self.extensions:
489 # just to make sure we don't init it twice
500 # just to make sure we don't init it twice
490 # note that if you 'load' a module that has already been
501 # note that if you 'load' a module that has already been
491 # imported, init_ipython gets run anyway
502 # imported, init_ipython gets run anyway
492
503
493 return self.extensions[mod]
504 return self.extensions[mod]
494 __import__(mod)
505 __import__(mod)
495 m = sys.modules[mod]
506 m = sys.modules[mod]
496 if hasattr(m,'init_ipython'):
507 if hasattr(m,'init_ipython'):
497 m.init_ipython(self)
508 m.init_ipython(self)
498
509
499 if hasattr(m,'ipython_firstrun'):
510 if hasattr(m,'ipython_firstrun'):
500 already_loaded = self.db.get('firstrun_done', set())
511 already_loaded = self.db.get('firstrun_done', set())
501 if mod not in already_loaded:
512 if mod not in already_loaded:
502 m.ipython_firstrun(self)
513 m.ipython_firstrun(self)
503 already_loaded.add(mod)
514 already_loaded.add(mod)
504 self.db['firstrun_done'] = already_loaded
515 self.db['firstrun_done'] = already_loaded
505
516
506 self.extensions[mod] = m
517 self.extensions[mod] = m
507 return m
518 return m
508
519
509
520
510 class DebugTools:
521 class DebugTools:
511 """ Used for debugging mishaps in api usage
522 """ Used for debugging mishaps in api usage
512
523
513 So far, tracing redefinitions is supported.
524 So far, tracing redefinitions is supported.
514 """
525 """
515
526
516 def __init__(self, ip):
527 def __init__(self, ip):
517 self.ip = ip
528 self.ip = ip
518 self.debugmode = False
529 self.debugmode = False
519 self.hotnames = set()
530 self.hotnames = set()
520
531
521 def hotname(self, name_to_catch):
532 def hotname(self, name_to_catch):
522 self.hotnames.add(name_to_catch)
533 self.hotnames.add(name_to_catch)
523
534
524 def debug_stack(self, msg = None):
535 def debug_stack(self, msg = None):
525 if not self.debugmode:
536 if not self.debugmode:
526 return
537 return
527
538
528 import traceback
539 import traceback
529 if msg is not None:
540 if msg is not None:
530 print '====== %s ========' % msg
541 print '====== %s ========' % msg
531 traceback.print_stack()
542 traceback.print_stack()
532
543
533 def check_hotname(self,name):
544 def check_hotname(self,name):
534 if name in self.hotnames:
545 if name in self.hotnames:
535 self.debug_stack( "HotName '%s' caught" % name)
546 self.debug_stack( "HotName '%s' caught" % name)
536
547
537 def launch_new_instance(user_ns = None,shellclass = None):
548 def launch_new_instance(user_ns = None,shellclass = None):
538 """ Make and start a new ipython instance.
549 """ Make and start a new ipython instance.
539
550
540 This can be called even without having an already initialized
551 This can be called even without having an already initialized
541 ipython session running.
552 ipython session running.
542
553
543 This is also used as the egg entry point for the 'ipython' script.
554 This is also used as the egg entry point for the 'ipython' script.
544
555
545 """
556 """
546 ses = make_session(user_ns,shellclass)
557 ses = make_session(user_ns,shellclass)
547 ses.mainloop()
558 ses.mainloop()
548
559
549
560
550 def make_user_ns(user_ns = None):
561 def make_user_ns(user_ns = None):
551 """Return a valid user interactive namespace.
562 """Return a valid user interactive namespace.
552
563
553 This builds a dict with the minimal information needed to operate as a
564 This builds a dict with the minimal information needed to operate as a
554 valid IPython user namespace, which you can pass to the various embedding
565 valid IPython user namespace, which you can pass to the various embedding
555 classes in ipython.
566 classes in ipython.
556 """
567 """
557
568
558 if user_ns is None:
569 if user_ns is None:
559 # Set __name__ to __main__ to better match the behavior of the
570 # Set __name__ to __main__ to better match the behavior of the
560 # normal interpreter.
571 # normal interpreter.
561 user_ns = {'__name__' :'__main__',
572 user_ns = {'__name__' :'__main__',
562 '__builtins__' : __builtin__,
573 '__builtins__' : __builtin__,
563 }
574 }
564 else:
575 else:
565 user_ns.setdefault('__name__','__main__')
576 user_ns.setdefault('__name__','__main__')
566 user_ns.setdefault('__builtins__',__builtin__)
577 user_ns.setdefault('__builtins__',__builtin__)
567
578
568 return user_ns
579 return user_ns
569
580
570
581
571 def make_user_global_ns(ns = None):
582 def make_user_global_ns(ns = None):
572 """Return a valid user global namespace.
583 """Return a valid user global namespace.
573
584
574 Similar to make_user_ns(), but global namespaces are really only needed in
585 Similar to make_user_ns(), but global namespaces are really only needed in
575 embedded applications, where there is a distinction between the user's
586 embedded applications, where there is a distinction between the user's
576 interactive namespace and the global one where ipython is running."""
587 interactive namespace and the global one where ipython is running."""
577
588
578 if ns is None: ns = {}
589 if ns is None: ns = {}
579 return ns
590 return ns
580
591
581
592
582 def make_session(user_ns = None, shellclass = None):
593 def make_session(user_ns = None, shellclass = None):
583 """Makes, but does not launch an IPython session.
594 """Makes, but does not launch an IPython session.
584
595
585 Later on you can call obj.mainloop() on the returned object.
596 Later on you can call obj.mainloop() on the returned object.
586
597
587 Inputs:
598 Inputs:
588
599
589 - user_ns(None): a dict to be used as the user's namespace with initial
600 - user_ns(None): a dict to be used as the user's namespace with initial
590 data.
601 data.
591
602
592 WARNING: This should *not* be run when a session exists already."""
603 WARNING: This should *not* be run when a session exists already."""
593
604
594 import IPython.Shell
605 import IPython.Shell
595 if shellclass is None:
606 if shellclass is None:
596 return IPython.Shell.start(user_ns)
607 return IPython.Shell.start(user_ns)
597 return shellclass(user_ns = user_ns)
608 return shellclass(user_ns = user_ns)
@@ -1,528 +1,552 b''
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <?xml-stylesheet ekr_test?>
2 <?xml-stylesheet ekr_test?>
3 <leo_file>
3 <leo_file>
4 <leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/>
4 <leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/>
5 <globals body_outline_ratio="0.307814992026">
5 <globals body_outline_ratio="0.307814992026">
6 <global_window_position top="180" left="223" height="627" width="1280"/>
6 <global_window_position top="257" left="131" height="627" width="1280"/>
7 <global_log_window_position top="0" left="0" height="0" width="0"/>
7 <global_log_window_position top="0" left="0" height="0" width="0"/>
8 </globals>
8 </globals>
9 <preferences/>
9 <preferences/>
10 <find_panel_settings/>
10 <find_panel_settings/>
11 <vnodes>
11 <vnodes>
12 <v t="vivainio.20080222193236" a="E"><vh>Documentation</vh>
12 <v t="vivainio.20080222193236" a="E"><vh>Documentation</vh>
13 <v t="vivainio.20080223121915" tnodeList="vivainio.20080223121915,vivainio.20080222193236.1,vivainio.20080223133858,vivainio.20080223133922,vivainio.20080223133947,vivainio.20080223134018,vivainio.20080223134100,vivainio.20080223134118,vivainio.20080223134433,vivainio.20080223142207,vivainio.20080223134136"><vh>@nosent ILeo_doc.txt</vh>
13 <v t="vivainio.20080223121915" tnodeList="vivainio.20080223121915,vivainio.20080222193236.1,vivainio.20080223133858,vivainio.20080223133922,vivainio.20080223133947,vivainio.20080223134018,vivainio.20080223134100,vivainio.20080223134118,vivainio.20080223134433,vivainio.20080223142207,vivainio.20080223134136"><vh>@nosent ILeo_doc.txt</vh>
14 <v t="vivainio.20080222193236.1"><vh>Documentation</vh>
14 <v t="vivainio.20080222193236.1"><vh>Documentation</vh>
15 <v t="vivainio.20080223133858"><vh>Introduction</vh></v>
15 <v t="vivainio.20080223133858"><vh>Introduction</vh></v>
16 <v t="vivainio.20080223133922"><vh>Installation</vh></v>
16 <v t="vivainio.20080223133922"><vh>Installation</vh></v>
17 <v t="vivainio.20080223133947"><vh>Accessing IPython from Leo</vh></v>
17 <v t="vivainio.20080223133947"><vh>Accessing IPython from Leo</vh></v>
18 <v t="vivainio.20080223134018"><vh>Accessing Leo nodes from IPython</vh></v>
18 <v t="vivainio.20080223134018"><vh>Accessing Leo nodes from IPython</vh></v>
19 <v t="vivainio.20080223134100"><vh>Cl definitions</vh></v>
19 <v t="vivainio.20080223134100"><vh>Cl definitions</vh></v>
20 <v t="vivainio.20080223134118"><vh>Special node types</vh></v>
20 <v t="vivainio.20080223134118"><vh>Special node types</vh></v>
21 <v t="vivainio.20080223134433"><vh>Custom push</vh></v>
21 <v t="vivainio.20080223134433"><vh>Custom push</vh></v>
22 <v t="vivainio.20080223142207" a="E"><vh>Code snippets</vh></v>
22 <v t="vivainio.20080223142207" a="E"><vh>Code snippets</vh></v>
23 <v t="vivainio.20080223134136"><vh>Acknowledgements and history</vh></v>
23 <v t="vivainio.20080223134136"><vh>Acknowledgements and history</vh></v>
24 </v>
24 </v>
25 </v>
25 </v>
26 </v>
26 </v>
27 <v t="vivainio.20080218184525"><vh>@chapters</vh></v>
27 <v t="vivainio.20080218184525"><vh>@chapters</vh></v>
28 <v t="vivainio.20080223133721" a="E"><vh>@settings</vh>
28 <v t="vivainio.20080223133721" a="E"><vh>@settings</vh>
29 <v t="vivainio.20080316092617"><vh>@@string ipython_argv = ipython -pylab</vh></v>
29 <v t="vivainio.20080316092617"><vh>@@string ipython_argv = ipython -pylab</vh></v>
30 <v t="vivainio.20080223133721.1"><vh>@enabled-plugins</vh></v>
30 <v t="vivainio.20080223133721.1"><vh>@enabled-plugins</vh></v>
31 </v>
31 </v>
32 <v t="vivainio.20080218184540"><vh>@ipy-startup</vh>
32 <v t="vivainio.20080218184540"><vh>@ipy-startup</vh>
33 <v t="vivainio.20080218184613.1"><vh>b</vh></v>
33 <v t="vivainio.20080218184613.1"><vh>b</vh></v>
34 <v t="vivainio.20080218200031"><vh>Some classes P</vh>
34 <v t="vivainio.20080218200031"><vh>Some classes P</vh>
35 <v t="vivainio.20080218190816"><vh>File-like access</vh></v>
35 <v t="vivainio.20080218190816"><vh>File-like access</vh></v>
36 <v t="vivainio.20080218200106"><vh>csv data</vh></v>
36 <v t="vivainio.20080218200106"><vh>csv data</vh></v>
37 <v t="vivainio.20080219225120"><vh>String list</vh></v>
37 <v t="vivainio.20080219225120"><vh>String list</vh></v>
38 <v t="vivainio.20080219230342"><vh>slist to leo</vh></v>
38 <v t="vivainio.20080219230342"><vh>slist to leo</vh></v>
39 </v>
39 </v>
40 </v>
40 </v>
41 <v t="vivainio.20080218195413"><vh>Class tests</vh>
41 <v t="vivainio.20080218195413" a="E"><vh>Class tests</vh>
42 <v t="vivainio.20080218200509"><vh>csvr</vh></v>
42 <v t="vivainio.20080218200509"><vh>csvr</vh></v>
43 <v t="vivainio.20080218191007"><vh>tempfile</vh></v>
43 <v t="vivainio.20080218191007"><vh>tempfile</vh></v>
44 <v t="vivainio.20080218195413.1"><vh>rfile</vh></v>
44 <v t="vivainio.20080218195413.1"><vh>rfile</vh></v>
45 <v t="vivainio.20080219225804"><vh>strlist</vh></v>
45 <v t="vivainio.20080219225804"><vh>strlist</vh></v>
46 </v>
46 </v>
47 <v t="vivainio.20080222201226" a="V"><vh>IPython script push tests</vh></v>
47 <v t="vivainio.20080218201219" a="E"><vh>Direct variables</vh>
48 <v t="vivainio.20080218201219" a="E"><vh>Direct variables</vh>
48 <v t="vivainio.20080222201226"><vh>NewHeadline</vh></v>
49 <v t="vivainio.20080218201219.2"><vh>bar</vh></v>
49 <v t="vivainio.20080218201219.2"><vh>bar</vh></v>
50 </v>
50 </v>
51 <v t="vivainio.20080316144536" a="E"><vh>pylab tests</vh>
51 <v t="vivainio.20080316144536" a="E"><vh>pylab tests</vh>
52 <v t="vivainio.20080316145539.2" a="TV"><vh>Generate testarr</vh></v>
52 <v t="vivainio.20080316145539.2"><vh>Generate testarr</vh></v>
53 <v t="vivainio.20080316085925"><vh>testarr</vh></v>
53 <v t="vivainio.20080316085925"><vh>testarr</vh></v>
54 <v t="vivainio.20080316085950"><vh>Call plotter on testarr</vh></v>
54 <v t="vivainio.20080316085950"><vh>Call plotter on testarr</vh></v>
55 </v>
55 </v>
56 <v t="vivainio.20080222202211"><vh>test stuff</vh></v>
56 <v t="vivainio.20080222202211"><vh>test stuff</vh></v>
57 <v t="vivainio.20080223142403"><vh>@ipy-results</vh>
57 <v t="vivainio.20080223142403"><vh>@ipy-results</vh>
58 <v t="vivainio.20080223142403.1"><vh>foo</vh></v>
58 <v t="vivainio.20080223142403.1"><vh>foo</vh></v>
59 </v>
59 </v>
60 <v t="vivainio.20080222202211.1" a="E"><vh>spam</vh></v>
60 <v t="vivainio.20080222202211.1" a="E"><vh>spam</vh></v>
61 </vnodes>
61 </vnodes>
62 <tnodes>
62 <tnodes>
63 <t tx="vivainio.20080218184525">?</t>
63 <t tx="vivainio.20080218184525">?</t>
64 <t tx="vivainio.20080218184540">?Direct children of this node will be pushed at ipython bridge startup
64 <t tx="vivainio.20080218184540">?Direct children of this node will be pushed at ipython bridge startup
65
65
66 This node itself will *not* be pushed</t>
66 This node itself will *not* be pushed</t>
67 <t tx="vivainio.20080218184613.1">print "world"</t>
67 <t tx="vivainio.20080218184613.1">print "world"</t>
68 <t tx="vivainio.20080218190816">def rfile(body,n):
68 <t tx="vivainio.20080218190816">def rfile(body,n):
69 """ @cl rfile
69 """ @cl rfile
70
70
71 produces a StringIO (file like obj of the rest of the body) """
71 produces a StringIO (file like obj of the rest of the body) """
72
72
73 import StringIO
73 import StringIO
74 return StringIO.StringIO(body)
74 return StringIO.StringIO(body)
75
75
76 def tmpfile(body,n):
76 def tmpfile(body,n):
77 """ @cl tmpfile
77 """ @cl tmpfile
78
78
79 Produces a temporary file, with node body as contents
79 Produces a temporary file, with node body as contents
80
80
81 """
81 """
82 import tempfile
82 import tempfile
83 h, fname = tempfile.mkstemp()
83 h, fname = tempfile.mkstemp()
84 f = open(fname,'w')
84 f = open(fname,'w')
85 f.write(body)
85 f.write(body)
86 f.close()
86 f.close()
87 return fname
87 return fname
88 </t>
88 </t>
89 <t tx="vivainio.20080218191007">@cl tmpfile
89 <t tx="vivainio.20080218191007">@cl tmpfile
90
90
91 Hello</t>
91 Hello</t>
92 <t tx="vivainio.20080218195413">?</t>
92 <t tx="vivainio.20080218195413">?</t>
93 <t tx="vivainio.20080218195413.1">@cl rfile
93 <t tx="vivainio.20080218195413.1">@cl rfile
94 These
94 These
95 lines
95 lines
96 should
96 should
97 be
97 be
98 readable </t>
98 readable </t>
99 <t tx="vivainio.20080218200031">@others</t>
99 <t tx="vivainio.20080218200031">@others</t>
100 <t tx="vivainio.20080218200106">def csvdata(body,n):
100 <t tx="vivainio.20080218200106">def csvdata(body,n):
101 import csv
101 import csv
102 d = csv.Sniffer().sniff(body)
102 d = csv.Sniffer().sniff(body)
103 reader = csv.reader(body.splitlines(), dialect = d)
103 reader = csv.reader(body.splitlines(), dialect = d)
104 return reader</t>
104 return reader</t>
105 <t tx="vivainio.20080218200509">@cl csvdata
105 <t tx="vivainio.20080218200509">@cl csvdata
106
106
107 a,b,b
107 a,b,b
108 1,2,2</t>
108 1,2,2</t>
109 <t tx="vivainio.20080218201219"></t>
109 <t tx="vivainio.20080218201219"></t>
110 <t tx="vivainio.20080218201219.2">@cl
110 <t tx="vivainio.20080218201219.2">@cl
111 "hello world"</t>
111 "hello world"</t>
112 <t tx="vivainio.20080219225120">import IPython.genutils
112 <t tx="vivainio.20080219225120">import IPython.genutils
113 def slist(body,n):
113 def slist(body,n):
114 return IPython.genutils.SList(body.splitlines())
114 return IPython.genutils.SList(body.splitlines())
115 </t>
115 </t>
116 <t tx="vivainio.20080219225804">@cl slist
116 <t tx="vivainio.20080219225804">@cl slist
117 hello
117 hello
118 world
118 world
119 on
119 on
120 many
120 many
121 lines
121 lines
122 </t>
122 </t>
123 <t tx="vivainio.20080219230342">import ipy_leo
123 <t tx="vivainio.20080219230342">import ipy_leo
124 @ipy_leo.format_for_leo.when_type(IPython.genutils.SList)
124 @ipy_leo.format_for_leo.when_type(IPython.genutils.SList)
125 def format_slist(obj):
125 def format_slist(obj):
126 return "@cl slist\n" + obj.n
126 return "@cl slist\n" + obj.n
127 </t>
127 </t>
128 <t tx="vivainio.20080222193236">?</t>
128 <t tx="vivainio.20080222193236">?</t>
129 <t tx="vivainio.20080222193236.1">@wrap
129 <t tx="vivainio.20080222193236.1">@wrap
130 @nocolor</t>
130 @nocolor</t>
131 <t tx="vivainio.20080222201226">1+2
131 <t tx="vivainio.20080222201226"># test ipython script 'cleanup' with complex blocks
132 1+2
132 print "hello"
133 print "hello"
133 3+4
134 3+4
134
135
135 def f(x):
136 def f(x):
136 return x.upper()
137 return x.upper()
137
138
138 f('hello world')
139
139
140 if 0:
140 if 0:
141 print "foo"
141 print "foo"
142 else:
142 else:
143 print "bar"
143 print "bar"
144
144
145 </t>
145 def g():
146 pass
147
148 g()
149
150 if 1:
151 if 1:
152 print "hello"
153
154 print "world"
155
156 if 1:
157 print "hello"
158
159 print "word"
160 else:
161 print "foo"
162
163 print "bar"
164 print "baz"
165
166 try:
167 raise Exception
168 except:
169 print "exc ok"</t>
146 <t tx="vivainio.20080222202211"></t>
170 <t tx="vivainio.20080222202211"></t>
147 <t tx="vivainio.20080222202211.1" ipython="7d71005506636f6f7264737101284b0c4bde747102732e">@cl rfile
171 <t tx="vivainio.20080222202211.1" ipython="7d71005506636f6f7264737101284b0c4bde747102732e">@cl rfile
148 hello
172 hello
149 world
173 world
150 and whatever</t>
174 and whatever</t>
151 <t tx="vivainio.20080223121915">@others
175 <t tx="vivainio.20080223121915">@others
152 </t>
176 </t>
153 <t tx="vivainio.20080223133721"></t>
177 <t tx="vivainio.20080223133721"></t>
154 <t tx="vivainio.20080223133721.1">ipython.py</t>
178 <t tx="vivainio.20080223133721.1">ipython.py</t>
155 <t tx="vivainio.20080223133858">
179 <t tx="vivainio.20080223133858">
156 Introduction
180 Introduction
157 ============
181 ============
158
182
159 The purpose of ILeo, or leo-ipython bridge, is being a two-way communication
183 The purpose of ILeo, or leo-ipython bridge, is being a two-way communication
160 channel between Leo and IPython. The level of integration is much deeper than
184 channel between Leo and IPython. The level of integration is much deeper than
161 conventional integration in IDEs; most notably, you are able to store *data* in
185 conventional integration in IDEs; most notably, you are able to store *data* in
162 Leo nodes, in addition to mere program code. The possibilities of this are
186 Leo nodes, in addition to mere program code. The possibilities of this are
163 endless, and this degree of integration has not been seen previously in the python
187 endless, and this degree of integration has not been seen previously in the python
164 world.
188 world.
165
189
166 IPython users are accustomed to using things like %edit to produce non-trivial
190 IPython users are accustomed to using things like %edit to produce non-trivial
167 functions/classes (i.e. something that they don't want to enter directly on the
191 functions/classes (i.e. something that they don't want to enter directly on the
168 interactive prompt, but creating a proper script/module involves too much
192 interactive prompt, but creating a proper script/module involves too much
169 overhead). In ILeo, this task consists just going to the Leo window, creating a node
193 overhead). In ILeo, this task consists just going to the Leo window, creating a node
170 and writing the code there, and pressing alt+I (push-to-ipython).
194 and writing the code there, and pressing alt+I (push-to-ipython).
171
195
172 Obviously, you can save the Leo document as usual - this is a great advantage
196 Obviously, you can save the Leo document as usual - this is a great advantage
173 of ILeo over using %edit, you can save your experimental scripts all at one
197 of ILeo over using %edit, you can save your experimental scripts all at one
174 time, without having to organize them into script/module files (before you
198 time, without having to organize them into script/module files (before you
175 really want to, of course!)
199 really want to, of course!)
176 </t>
200 </t>
177 <t tx="vivainio.20080223133922">
201 <t tx="vivainio.20080223133922">
178 Installation
202 Installation
179 ============
203 ============
180
204
181 You need at least Leo 4.4.7, and the development version of IPython (ILeo
205 You need at least Leo 4.4.7, and the development version of IPython (ILeo
182 will be incorporated to IPython 0.8.3).
206 will be incorporated to IPython 0.8.3).
183
207
184 You can get IPython from Launchpad by installing bzr and doing
208 You can get IPython from Launchpad by installing bzr and doing
185
209
186 bzr branch lp:ipython
210 bzr branch lp:ipython
187
211
188 and running "setup.py install".
212 and running "setup.py install".
189
213
190 You need to enable the 'ipython.py' plugin in Leo:
214 You need to enable the 'ipython.py' plugin in Leo:
191
215
192 - Help -&gt; Open LeoSettings.leo
216 - Help -&gt; Open LeoSettings.leo
193
217
194 - Edit @settings--&gt;Plugins--&gt;@enabled-plugins, add/uncomment 'ipython.py'
218 - Edit @settings--&gt;Plugins--&gt;@enabled-plugins, add/uncomment 'ipython.py'
195
219
196 - Alternatively, you can add @settings--&gt;@enabled-plugins with body ipython.py to your leo document.
220 - Alternatively, you can add @settings--&gt;@enabled-plugins with body ipython.py to your leo document.
197
221
198 - Restart Leo. Be sure that you have the console window open (start leo.py from console, or double-click leo.py on windows)
222 - Restart Leo. Be sure that you have the console window open (start leo.py from console, or double-click leo.py on windows)
199
223
200 - Press alt+5 OR alt-x start-ipython to launch IPython in the console that
224 - Press alt+5 OR alt-x start-ipython to launch IPython in the console that
201 started leo. You can start entering IPython commands normally, and Leo will keep
225 started leo. You can start entering IPython commands normally, and Leo will keep
202 running at the same time.
226 running at the same time.
203 </t>
227 </t>
204 <t tx="vivainio.20080223133947">
228 <t tx="vivainio.20080223133947">
205 Accessing IPython from Leo
229 Accessing IPython from Leo
206 ==========================
230 ==========================
207
231
208 IPython code
232 IPython code
209 ------------
233 ------------
210
234
211 Just enter IPython commands on a Leo node and press alt-I to execute
235 Just enter IPython commands on a Leo node and press alt-I to execute
212 push-to-ipython in order to execute the script in IPython. 'commands' is
236 push-to-ipython in order to execute the script in IPython. 'commands' is
213 interpreted loosely here - you can enter function and class definitions, in
237 interpreted loosely here - you can enter function and class definitions, in
214 addition to the things you would usually enter at IPython prompt - calculations,
238 addition to the things you would usually enter at IPython prompt - calculations,
215 system commands etc.
239 system commands etc.
216
240
217 Everything that would be legal to enter on IPython prompt is legal to execute
241 Everything that would be legal to enter on IPython prompt is legal to execute
218 from ILeo.
242 from ILeo.
219
243
220 Results will be shows in Leo log window for convenience, in addition to the console.
244 Results will be shows in Leo log window for convenience, in addition to the console.
221
245
222 Suppose that a node had the following contents:
246 Suppose that a node had the following contents:
223 {{{
247 {{{
224 1+2
248 1+2
225 print "hello"
249 print "hello"
226 3+4
250 3+4
227
251
228 def f(x):
252 def f(x):
229 return x.upper()
253 return x.upper()
230
254
231 f('hello world')
255 f('hello world')
232 }}}
256 }}}
233
257
234 If you press alt+I on that node, you will see the following in Leo log window (IPython tab):
258 If you press alt+I on that node, you will see the following in Leo log window (IPython tab):
235
259
236 {{{
260 {{{
237 In: 1+2
261 In: 1+2
238 &lt;2&gt; 3
262 &lt;2&gt; 3
239 In: 3+4
263 In: 3+4
240 &lt;4&gt; 7
264 &lt;4&gt; 7
241 In: f('hello world')
265 In: f('hello world')
242 &lt;6&gt; 'HELLO WORLD'
266 &lt;6&gt; 'HELLO WORLD'
243 }}}
267 }}}
244
268
245 (numbers like &lt;6&gt; mean IPython output history indices; the actual object can be
269 (numbers like &lt;6&gt; mean IPython output history indices; the actual object can be
246 referenced with _6 as usual in IPython).
270 referenced with _6 as usual in IPython).
247
271
248
272
249 Plain Python code
273 Plain Python code
250 -----------------
274 -----------------
251
275
252 If the headline of the node ends with capital P, alt-I will not run the code
276 If the headline of the node ends with capital P, alt-I will not run the code
253 through IPython translation mechanism but use the direct python 'exec' statement
277 through IPython translation mechanism but use the direct python 'exec' statement
254 (in IPython user namespace) to execute the code. It wont be shown in IPython
278 (in IPython user namespace) to execute the code. It wont be shown in IPython
255 history, and sometimes it is safer (and more efficient) to execute things as
279 history, and sometimes it is safer (and more efficient) to execute things as
256 plain Python statements. Large class definitions are good candidates for P
280 plain Python statements. Large class definitions are good candidates for P
257 nodes.
281 nodes.
258 </t>
282 </t>
259 <t tx="vivainio.20080223134018">
283 <t tx="vivainio.20080223134018">
260 Accessing Leo nodes from IPython
284 Accessing Leo nodes from IPython
261 ================================
285 ================================
262
286
263 The real fun starts when you start entering text to leo nodes, and are using
287 The real fun starts when you start entering text to leo nodes, and are using
264 that as data (input/output) for your IPython work.
288 that as data (input/output) for your IPython work.
265
289
266 Accessing Leo nodes happens through the variable 'wb' (short for "WorkBook")
290 Accessing Leo nodes happens through the variable 'wb' (short for "WorkBook")
267 that exist in the IPython user namespace. Nodes that are directly accessible are
291 that exist in the IPython user namespace. Nodes that are directly accessible are
268 the ones that have simple names which could also be Python variable names;
292 the ones that have simple names which could also be Python variable names;
269 'foo_1' will be accessible directly from IPython, whereas 'my scripts' will not.
293 'foo_1' will be accessible directly from IPython, whereas 'my scripts' will not.
270 If you want to access a node with arbitrary headline, add a child node '@a foo'
294 If you want to access a node with arbitrary headline, add a child node '@a foo'
271 (@a stands for 'anchor'). Then, the parent of '@a foo' is accessible through
295 (@a stands for 'anchor'). Then, the parent of '@a foo' is accessible through
272 'wb.foo'.
296 'wb.foo'.
273
297
274 You can see what nodes are accessible be entering (in IPython) wb.&lt;TAB&gt;. Example:
298 You can see what nodes are accessible be entering (in IPython) wb.&lt;TAB&gt;. Example:
275
299
276 [C:leo/src]|12&gt; wb.
300 [C:leo/src]|12&gt; wb.
277 wb.b wb.tempfile wb.rfile wb.NewHeadline
301 wb.b wb.tempfile wb.rfile wb.NewHeadline
278 wb.bar wb.Docs wb.strlist wb.csvr
302 wb.bar wb.Docs wb.strlist wb.csvr
279 [C:leo/src]|12&gt; wb.tempfile
303 [C:leo/src]|12&gt; wb.tempfile
280 &lt;12&gt; &lt;ipy_leo.LeoNode object at 0x044B6D90&gt;
304 &lt;12&gt; &lt;ipy_leo.LeoNode object at 0x044B6D90&gt;
281
305
282 So here, we meet the 'LeoNode' class that is your key to manipulating Leo
306 So here, we meet the 'LeoNode' class that is your key to manipulating Leo
283 content from IPython!
307 content from IPython!
284
308
285 LeoNode
309 LeoNode
286 -------
310 -------
287
311
288 Suppose that we had a node with headline 'spam' and body:
312 Suppose that we had a node with headline 'spam' and body:
289
313
290 ['12',2222+32]
314 ['12',2222+32]
291
315
292 we can access it from IPython (or from scripts entered into other Leo nodes!) by doing:
316 we can access it from IPython (or from scripts entered into other Leo nodes!) by doing:
293
317
294 C:leo/src]|19&gt; wb.spam.v
318 C:leo/src]|19&gt; wb.spam.v
295 &lt;19&gt; ['12', 2254]
319 &lt;19&gt; ['12', 2254]
296
320
297 'v' attribute stands for 'value', which means the node contents will be run
321 'v' attribute stands for 'value', which means the node contents will be run
298 through 'eval' and everything you would be able to enter into IPython prompt
322 through 'eval' and everything you would be able to enter into IPython prompt
299 will be converted to objects. This mechanism can be extended far beyond direct
323 will be converted to objects. This mechanism can be extended far beyond direct
300 evaluation (see '@cl definitions').
324 evaluation (see '@cl definitions').
301
325
302 'v' attribute also has a setter, i.e. you can do:
326 'v' attribute also has a setter, i.e. you can do:
303
327
304 wb.spam.v = "mystring"
328 wb.spam.v = "mystring"
305
329
306 Which will result in the node 'spam' having the following text:
330 Which will result in the node 'spam' having the following text:
307
331
308 'mystring'
332 'mystring'
309
333
310 What assignment to 'v' does can be configured through generic functions
334 What assignment to 'v' does can be configured through generic functions
311 ('simplegeneric' module, will be explained later).
335 ('simplegeneric' module, will be explained later).
312
336
313 Besides v, you can set the body text directly through
337 Besides v, you can set the body text directly through
314
338
315 wb.spam.b = "some\nstring",
339 wb.spam.b = "some\nstring",
316
340
317 headline by
341 headline by
318
342
319 wb.spam.h = 'new_headline'
343 wb.spam.h = 'new_headline'
320
344
321 (obviously you must access the node through wb.new_headline from that point
345 (obviously you must access the node through wb.new_headline from that point
322 onwards), and access the contents as string list (IPython SList) through
346 onwards), and access the contents as string list (IPython SList) through
323 'wb.spam.l'.
347 'wb.spam.l'.
324
348
325 If you do 'wb.foo.v = 12' when node named 'foo' does not exist, the node titled
349 If you do 'wb.foo.v = 12' when node named 'foo' does not exist, the node titled
326 'foo' will be automatically created and assigned body 12.
350 'foo' will be automatically created and assigned body 12.
327
351
328 LeoNode also supports go() that focuses the node in the Leo window, and ipush()
352 LeoNode also supports go() that focuses the node in the Leo window, and ipush()
329 that simulates pressing alt+I on the node.
353 that simulates pressing alt+I on the node.
330
354
331 You can access unknownAttributes by .uA property dictionary. Unknown attributes
355 You can access unknownAttributes by .uA property dictionary. Unknown attributes
332 allow you to store arbitrary (pickleable) python objects in the Leo nodes; the
356 allow you to store arbitrary (pickleable) python objects in the Leo nodes; the
333 attributes are stored when you save the .leo document, and recreated when you
357 attributes are stored when you save the .leo document, and recreated when you
334 open the document again. The attributes are not visible anywhere, but can be
358 open the document again. The attributes are not visible anywhere, but can be
335 used for domain-specific metatada. Example:
359 used for domain-specific metatada. Example:
336
360
337 [C:leo/src]|12&gt; wb.spam.uA['coords'] = (12,222)
361 [C:leo/src]|12&gt; wb.spam.uA['coords'] = (12,222)
338 [C:leo/src]|13&gt; wb.spam.uA
362 [C:leo/src]|13&gt; wb.spam.uA
339 &lt;13&gt; {'coords': (12, 222)}
363 &lt;13&gt; {'coords': (12, 222)}
340
364
341 Accessing children with iteration and dict notation
365 Accessing children with iteration and dict notation
342 ---------------------------------------------------
366 ---------------------------------------------------
343
367
344 Sometimes, you may want to treat a node as a 'database', where the nodes
368 Sometimes, you may want to treat a node as a 'database', where the nodes
345 children represent elements in the database. You can create a new child node for
369 children represent elements in the database. You can create a new child node for
346 node 'spam', with headline 'foo bar' like this:
370 node 'spam', with headline 'foo bar' like this:
347
371
348 wb.spam['foo bar'] = "Hello"
372 wb.spam['foo bar'] = "Hello"
349
373
350 And assign a new value for it by doing
374 And assign a new value for it by doing
351
375
352 wb.spam['foo bar'].v = "Hello again"
376 wb.spam['foo bar'].v = "Hello again"
353
377
354 Note how you can't use .v when you first create the node - i.e. the node needs
378 Note how you can't use .v when you first create the node - i.e. the node needs
355 to be initialized by simple assignment, that will be interpreted as assignment
379 to be initialized by simple assignment, that will be interpreted as assignment
356 to '.v'. This is a conscious design choice.
380 to '.v'. This is a conscious design choice.
357
381
358 If you try to do wb.spam['bar'] = 'Hello', ILeo will assign '@k bar' as the
382 If you try to do wb.spam['bar'] = 'Hello', ILeo will assign '@k bar' as the
359 headline for the child instead, because 'bar' is a legal python name (and as
383 headline for the child instead, because 'bar' is a legal python name (and as
360 such would be incorporated in the workbook namespace). This is done to avoid
384 such would be incorporated in the workbook namespace). This is done to avoid
361 crowding the workbook namespace with extraneous items. The item will still be
385 crowding the workbook namespace with extraneous items. The item will still be
362 accessible as wb.spam['bar']
386 accessible as wb.spam['bar']
363
387
364 LeoNodes are iterable, so to see the headlines of all the children of 'spam' do:
388 LeoNodes are iterable, so to see the headlines of all the children of 'spam' do:
365
389
366 for n in wb.spam:
390 for n in wb.spam:
367 print n.h
391 print n.h
368 </t>
392 </t>
369 <t tx="vivainio.20080223134100">
393 <t tx="vivainio.20080223134100">
370 @cl definitions
394 @cl definitions
371 ===============
395 ===============
372
396
373 If the first line in the body text is of the form '@cl sometext', IPython will
397 If the first line in the body text is of the form '@cl sometext', IPython will
374 evaluate 'sometext' and call the result with the rest of the body when you do
398 evaluate 'sometext' and call the result with the rest of the body when you do
375 'wb.foo.v'. An example is in place here. Suppose that we have defined a class (I
399 'wb.foo.v'. An example is in place here. Suppose that we have defined a class (I
376 use the term class in a non-python sense here)
400 use the term class in a non-python sense here)
377
401
378 {{{
402 {{{
379 def rfile(body,node):
403 def rfile(body,node):
380 """ @cl rfile
404 """ @cl rfile
381
405
382 produces a StringIO (file like obj) of the rest of the body """
406 produces a StringIO (file like obj) of the rest of the body """
383
407
384 import StringIO
408 import StringIO
385 return StringIO.StringIO(body)
409 return StringIO.StringIO(body)
386 }}}
410 }}}
387
411
388 (note that node is ignored here - but it could be used to access headline,
412 (note that node is ignored here - but it could be used to access headline,
389 children etc.),
413 children etc.),
390
414
391 Now, let's say you have node 'spam' with text
415 Now, let's say you have node 'spam' with text
392
416
393 {{{
417 {{{
394 @cl rfile
418 @cl rfile
395 hello
419 hello
396 world
420 world
397 and whatever
421 and whatever
398 }}}
422 }}}
399
423
400 Now, in IPython, we can do this:
424 Now, in IPython, we can do this:
401
425
402 {{{
426 {{{
403 [C:leo/src]|22&gt; f = wb.spam.v
427 [C:leo/src]|22&gt; f = wb.spam.v
404 [C:leo/src]|23&gt; f
428 [C:leo/src]|23&gt; f
405 &lt;23&gt; &lt;StringIO.StringIO instance at 0x04E7E490&gt;
429 &lt;23&gt; &lt;StringIO.StringIO instance at 0x04E7E490&gt;
406 [C:leo/src]|24&gt; f.readline()
430 [C:leo/src]|24&gt; f.readline()
407 &lt;24&gt; u'hello\n'
431 &lt;24&gt; u'hello\n'
408 [C:leo/src]|25&gt; f.readline()
432 [C:leo/src]|25&gt; f.readline()
409 &lt;25&gt; u'world\n'
433 &lt;25&gt; u'world\n'
410 [C:leo/src]|26&gt; f.readline()
434 [C:leo/src]|26&gt; f.readline()
411 &lt;26&gt; u'and whatever'
435 &lt;26&gt; u'and whatever'
412 [C:leo/src]|27&gt; f.readline()
436 [C:leo/src]|27&gt; f.readline()
413 &lt;27&gt; u''
437 &lt;27&gt; u''
414 }}}
438 }}}
415
439
416 You should declare new @cl types to make ILeo as convenient your problem domain
440 You should declare new @cl types to make ILeo as convenient your problem domain
417 as possible. For example, a "@cl etree" could return the elementtree object for
441 as possible. For example, a "@cl etree" could return the elementtree object for
418 xml content.
442 xml content.
419 </t>
443 </t>
420 <t tx="vivainio.20080223134118">
444 <t tx="vivainio.20080223134118">
421 Special node types
445 Special node types
422 ==================
446 ==================
423
447
424 @ipy-startup
448 @ipy-startup
425 ------------
449 ------------
426
450
427 If this node exist, the *direct children* of this will be pushed to IPython when
451 If this node exist, the *direct children* of this will be pushed to IPython when
428 ILeo is started (you press alt+5). Use it to push your own @cl definitions etc.
452 ILeo is started (you press alt+5). Use it to push your own @cl definitions etc.
429 The contents of of the node itself will be ignored.
453 The contents of of the node itself will be ignored.
430
454
431 @ipy-results
455 @ipy-results
432 ------------
456 ------------
433
457
434 When you create a new node (wb.foo.v = 'stuff'), the node foo will be created as
458 When you create a new node (wb.foo.v = 'stuff'), the node foo will be created as
435 a child of this node. If @ipy-results does not exist, the new node will be created after the currently selected node.
459 a child of this node. If @ipy-results does not exist, the new node will be created after the currently selected node.
436
460
437 @a nodes
461 @a nodes
438 --------
462 --------
439
463
440 You can attach these as children of existing nodes to provide a way to access
464 You can attach these as children of existing nodes to provide a way to access
441 nodes with arbitrary headlines, or to provide aliases to other nodes. If
465 nodes with arbitrary headlines, or to provide aliases to other nodes. If
442 multiple @a nodes are attached as children of a node, all the names can be used
466 multiple @a nodes are attached as children of a node, all the names can be used
443 to access the same object.
467 to access the same object.
444 </t>
468 </t>
445 <t tx="vivainio.20080223134136">
469 <t tx="vivainio.20080223134136">
446 Acknowledgements &amp; History
470 Acknowledgements &amp; History
447 ==========================
471 ==========================
448
472
449 This idea got started when I (Ville) saw this post by Edward Ream (the author of
473 This idea got started when I (Ville) saw this post by Edward Ream (the author of
450 Leo) on IPython developer mailing list:
474 Leo) on IPython developer mailing list:
451
475
452 http://lists.ipython.scipy.org/pipermail/ipython-dev/2008-January/003551.html
476 http://lists.ipython.scipy.org/pipermail/ipython-dev/2008-January/003551.html
453
477
454 I was using FreeMind as mind mapping software, and so I had an immediate use
478 I was using FreeMind as mind mapping software, and so I had an immediate use
455 case for Leo (which, incidentally, is superior to FreeMind as mind mapper). The
479 case for Leo (which, incidentally, is superior to FreeMind as mind mapper). The
456 wheels started rolling, I got obsessed with the power of this concept
480 wheels started rolling, I got obsessed with the power of this concept
457 (everything clicked together), and Edwards excitement paralleled mine.
481 (everything clicked together), and Edwards excitement paralleled mine.
458 Everything was mind-bogglingly easy/trivial, something that is typical of all
482 Everything was mind-bogglingly easy/trivial, something that is typical of all
459 revolutionary technologies (think Python here).
483 revolutionary technologies (think Python here).
460
484
461 The discussion that "built" ILeo is here:
485 The discussion that "built" ILeo is here:
462 http://sourceforge.net/forum/forum.php?thread_id=1911662&amp;forum_id=10226
486 http://sourceforge.net/forum/forum.php?thread_id=1911662&amp;forum_id=10226
463
487
464 ?</t>
488 ?</t>
465 <t tx="vivainio.20080223134433">
489 <t tx="vivainio.20080223134433">
466 Declaring custom push-to-ipython handlers
490 Declaring custom push-to-ipython handlers
467 =========================================
491 =========================================
468
492
469 Sometimes, you might want to configure what alt+I on a node does. You can do
493 Sometimes, you might want to configure what alt+I on a node does. You can do
470 that by creating your own push function and expose it using
494 that by creating your own push function and expose it using
471 ipy_leo.expose_ileo_push(f, priority). The function should check whether the
495 ipy_leo.expose_ileo_push(f, priority). The function should check whether the
472 node should by handled by the function and raise IPython.ipapi.TryNext if it
496 node should by handled by the function and raise IPython.ipapi.TryNext if it
473 will not do the handling, giving the next function in the chain a chance to see
497 will not do the handling, giving the next function in the chain a chance to see
474 whether it should handle the push.
498 whether it should handle the push.
475
499
476 This example would print an uppercase version of node body if the node headline ends
500 This example would print an uppercase version of node body if the node headline ends
477 with U (yes, this is completely useless!):
501 with U (yes, this is completely useless!):
478
502
479 {{{
503 {{{
480 def push_upcase(node):
504 def push_upcase(node):
481 if not node.h.endswith('U'):
505 if not node.h.endswith('U'):
482 raise TryNext
506 raise TryNext
483 print node.b.upper()
507 print node.b.upper()
484
508
485 ipy_leo.expose_ileo_push(push_upcase, 12)
509 ipy_leo.expose_ileo_push(push_upcase, 12)
486 }}}
510 }}}
487
511
488 (the priority should be between 0-100 - typically, you don't need to care about
512 (the priority should be between 0-100 - typically, you don't need to care about
489 it and can usually omit the argument altogether)
513 it and can usually omit the argument altogether)
490 </t>
514 </t>
491 <t tx="vivainio.20080223142207">
515 <t tx="vivainio.20080223142207">
492 Example code snippets
516 Example code snippets
493 =====================
517 =====================
494
518
495 Get list of all headlines of all the nodes in leo:
519 Get list of all headlines of all the nodes in leo:
496
520
497 [node.h for node in wb]
521 [node.h for node in wb]
498
522
499 Create node with headline 'baz', empty body:
523 Create node with headline 'baz', empty body:
500 wb.baz
524 wb.baz
501
525
502 Create 10 child nodes for baz, where i is headline and 'Hello ' + i is body:
526 Create 10 child nodes for baz, where i is headline and 'Hello ' + i is body:
503
527
504 for i in range(10):
528 for i in range(10):
505 wb.baz[i] = 'Hello %d' % i
529 wb.baz[i] = 'Hello %d' % i
506
530
507
531
508 </t>
532 </t>
509 <t tx="vivainio.20080223142403"></t>
533 <t tx="vivainio.20080223142403"></t>
510 <t tx="vivainio.20080223142403.1">12</t>
534 <t tx="vivainio.20080223142403.1">12</t>
511 <t tx="vivainio.20080316085925">array([[ 0, 1, 2],
535 <t tx="vivainio.20080316085925">array([[ 0, 1, 2],
512 [ 3, 4, 5],
536 [ 3, 4, 5],
513 [ 6, 7, 8],
537 [ 6, 7, 8],
514 [ 9, 10, 11]])</t>
538 [ 9, 10, 11]])</t>
515 <t tx="vivainio.20080316085950"># press alt+i here to plot testarr
539 <t tx="vivainio.20080316085950"># press alt+i here to plot testarr
516
540
517 plot(wb.testarr.v)</t>
541 plot(wb.testarr.v)</t>
518 <t tx="vivainio.20080316092617"></t>
542 <t tx="vivainio.20080316092617"></t>
519 <t tx="vivainio.20080316144536">Quickstart:
543 <t tx="vivainio.20080316144536">Quickstart:
520 easy_install numpy
544 easy_install numpy
521 easy_install matplotlib
545 easy_install matplotlib
522
546
523 Make sure you have '@string ipython-argv = ipython -pylab' in @settings. We currently recommend using TkAgg as the backend (it's also the default)</t>
547 Make sure you have '@string ipython-argv = ipython -pylab' in @settings. We currently recommend using TkAgg as the backend (it's also the default)</t>
524 <t tx="vivainio.20080316145539.2">#press alt+i here to generate an array for plotter
548 <t tx="vivainio.20080316145539.2">#press alt+i here to generate an array for plotter
525
549
526 wb.testarr.v = arange(12).reshape(4,3)</t>
550 wb.testarr.v = arange(12).reshape(4,3)</t>
527 </tnodes>
551 </tnodes>
528 </leo_file>
552 </leo_file>
General Comments 0
You need to be logged in to leave comments. Login now