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