##// END OF EJS Templates
Lots of cleanup and update_commander - requires cvs leo to work
Ville M. Vainio -
Show More
@@ -1,455 +1,474 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
12
13 ip = IPython.ipapi.get()
14 leo = ip.user_ns['leox']
15 c,g = leo.c, leo.g
16
13
17 # will probably be overwritten by user, but handy for experimentation early on
14 def init_ipython(ipy):
18 ip.user_ns['c'] = c
15 """ This will be run by _ip.load('ipy_leo')
19 ip.user_ns['g'] = g
16
17 Leo still needs to run update_commander() after this.
18
19 """
20 global ip
21 ip = ipy
22 ip.set_hook('complete_command', mb_completer, str_key = 'mb')
23 ip.expose_magic('mb',mb_f)
24 ip.expose_magic('leo',leo_f)
25 ip.expose_magic('leoref',leoref_f)
26 expose_ileo_push(push_cl_node,100)
27 # this should be the LAST one that will be executed, and it will never raise TryNext
28 expose_ileo_push(push_ipython_script, 1000)
29 expose_ileo_push(push_plain_python, 100)
30 ip.user_ns['wb'] = LeoWorkbook()
31
32 show_welcome()
20
33
21
34
35 def update_commander(new_leox):
36 """ Set the Leo commander to use
37
38 This will be run every time Leo does ipython-launch; basically,
39 when the user switches the document he is focusing on, he should do
40 ipython-launch to tell ILeo what document the commands apply to.
41
42 """
43
44 global c,g
45 c,g = new_leox.c, new_leox.g
46 print "Set Leo Commander:",c.frame.getTitle()
47
48 # will probably be overwritten by user, but handy for experimentation early on
49 ip.user_ns['c'] = c
50 ip.user_ns['g'] = g
51 ip.user_ns['_leo'] = new_leox
52
53 new_leox.push = push_position_from_leo
54 run_leo_startup_node()
55
22 from IPython.external.simplegeneric import generic
56 from IPython.external.simplegeneric import generic
23 import pprint
57 import pprint
24
58
25 def es(s):
59 def es(s):
26 g.es(s, tabName = 'IPython')
60 g.es(s, tabName = 'IPython')
27 pass
61 pass
28
62
29 @generic
63 @generic
30 def format_for_leo(obj):
64 def format_for_leo(obj):
31 """ Convert obj to string representiation (for editing in Leo)"""
65 """ Convert obj to string representiation (for editing in Leo)"""
32 return pprint.pformat(obj)
66 return pprint.pformat(obj)
33
67
34 @format_for_leo.when_type(list)
68 @format_for_leo.when_type(list)
35 def format_list(obj):
69 def format_list(obj):
36 return "\n".join(str(s) for s in obj)
70 return "\n".join(str(s) for s in obj)
37
71
38 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
72 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
39 def valid_attribute(s):
73 def valid_attribute(s):
40 return attribute_re.match(s)
74 return attribute_re.match(s)
41
75
42 def all_cells():
76 def all_cells():
43 d = {}
77 d = {}
44 for p in c.allNodes_iter():
78 for p in c.allNodes_iter():
45 h = p.headString()
79 h = p.headString()
46 if h.startswith('@a '):
80 if h.startswith('@a '):
47 d[h.lstrip('@a ').strip()] = p.parent().copy()
81 d[h.lstrip('@a ').strip()] = p.parent().copy()
48 elif not valid_attribute(h):
82 elif not valid_attribute(h):
49 continue
83 continue
50 d[h] = p.copy()
84 d[h] = p.copy()
51 return d
85 return d
52
53
54
86
55 def eval_node(n):
87 def eval_node(n):
56 body = n.b
88 body = n.b
57 if not body.startswith('@cl'):
89 if not body.startswith('@cl'):
58 # plain python repr node, just eval it
90 # plain python repr node, just eval it
59 return ip.ev(n.b)
91 return ip.ev(n.b)
60 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
92 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
61 first, rest = body.split('\n',1)
93 first, rest = body.split('\n',1)
62 tup = first.split(None, 1)
94 tup = first.split(None, 1)
63 # @cl alone SPECIAL USE-> dump var to user_ns
95 # @cl alone SPECIAL USE-> dump var to user_ns
64 if len(tup) == 1:
96 if len(tup) == 1:
65 val = ip.ev(rest)
97 val = ip.ev(rest)
66 ip.user_ns[n.h] = val
98 ip.user_ns[n.h] = val
67 es("%s = %s" % (n.h, repr(val)[:20] ))
99 es("%s = %s" % (n.h, repr(val)[:20] ))
68 return val
100 return val
69
101
70 cl, hd = tup
102 cl, hd = tup
71
103
72 xformer = ip.ev(hd.strip())
104 xformer = ip.ev(hd.strip())
73 es('Transform w/ %s' % repr(xformer))
105 es('Transform w/ %s' % repr(xformer))
74 return xformer(rest, n)
106 return xformer(rest, n)
75
107
76 class LeoNode(object, UserDict.DictMixin):
108 class LeoNode(object, UserDict.DictMixin):
77 """ Node in Leo outline
109 """ Node in Leo outline
78
110
79 Most important attributes (getters/setters available:
111 Most important attributes (getters/setters available:
80 .v - evaluate node, can also be alligned
112 .v - evaluate node, can also be alligned
81 .b, .h - body string, headline string
113 .b, .h - body string, headline string
82 .l - value as string list
114 .l - value as string list
83
115
84 Also supports iteration,
116 Also supports iteration,
85
117
86 setitem / getitem (indexing):
118 setitem / getitem (indexing):
87 wb.foo['key'] = 12
119 wb.foo['key'] = 12
88 assert wb.foo['key'].v == 12
120 assert wb.foo['key'].v == 12
89
121
90 Note the asymmetry on setitem and getitem! Also other
122 Note the asymmetry on setitem and getitem! Also other
91 dict methods are available.
123 dict methods are available.
92
124
93 .ipush() - run push-to-ipython
125 .ipush() - run push-to-ipython
126
127 Minibuffer command access (tab completion works):
128
129 mb save-to-file
94
130
95 """
131 """
96 def __init__(self,p):
132 def __init__(self,p):
97 self.p = p.copy()
133 self.p = p.copy()
98
134
99 def __str__(self):
135 def __str__(self):
100 return "<LeoNode %s>" % str(self.p)
136 return "<LeoNode %s>" % str(self.p)
101
137
102 __repr__ = __str__
138 __repr__ = __str__
103
139
104 def __get_h(self): return self.p.headString()
140 def __get_h(self): return self.p.headString()
105 def __set_h(self,val):
141 def __set_h(self,val):
106 print "set head",val
142 print "set head",val
107 c.beginUpdate()
143 c.beginUpdate()
108 try:
144 try:
109 c.setHeadString(self.p,val)
145 c.setHeadString(self.p,val)
110 finally:
146 finally:
111 c.endUpdate()
147 c.endUpdate()
112
148
113 h = property( __get_h, __set_h, doc = "Node headline string")
149 h = property( __get_h, __set_h, doc = "Node headline string")
114
150
115 def __get_b(self): return self.p.bodyString()
151 def __get_b(self): return self.p.bodyString()
116 def __set_b(self,val):
152 def __set_b(self,val):
117 print "set body",val
153 print "set body",val
118 c.beginUpdate()
154 c.beginUpdate()
119 try:
155 try:
120 c.setBodyString(self.p, val)
156 c.setBodyString(self.p, val)
121 finally:
157 finally:
122 c.endUpdate()
158 c.endUpdate()
123
159
124 b = property(__get_b, __set_b, doc = "Nody body string")
160 b = property(__get_b, __set_b, doc = "Nody body string")
125
161
126 def __set_val(self, val):
162 def __set_val(self, val):
127 self.b = format_for_leo(val)
163 self.b = format_for_leo(val)
128
164
129 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
165 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
130
166
131 def __set_l(self,val):
167 def __set_l(self,val):
132 self.b = '\n'.join(val )
168 self.b = '\n'.join(val )
133 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
169 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
134 __set_l, doc = "Node value as string list")
170 __set_l, doc = "Node value as string list")
135
171
136 def __iter__(self):
172 def __iter__(self):
137 """ Iterate through nodes direct children """
173 """ Iterate through nodes direct children """
138
174
139 return (LeoNode(p) for p in self.p.children_iter())
175 return (LeoNode(p) for p in self.p.children_iter())
140
176
141 def __children(self):
177 def __children(self):
142 d = {}
178 d = {}
143 for child in self:
179 for child in self:
144 head = child.h
180 head = child.h
145 tup = head.split(None,1)
181 tup = head.split(None,1)
146 if len(tup) > 1 and tup[0] == '@k':
182 if len(tup) > 1 and tup[0] == '@k':
147 d[tup[1]] = child
183 d[tup[1]] = child
148 continue
184 continue
149
185
150 if not valid_attribute(head):
186 if not valid_attribute(head):
151 d[head] = child
187 d[head] = child
152 continue
188 continue
153 return d
189 return d
154 def keys(self):
190 def keys(self):
155 d = self.__children()
191 d = self.__children()
156 return d.keys()
192 return d.keys()
157 def __getitem__(self, key):
193 def __getitem__(self, key):
158 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
194 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
159
195
160 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
196 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
161 """
197 """
162 key = str(key)
198 key = str(key)
163 d = self.__children()
199 d = self.__children()
164 return d[key]
200 return d[key]
165 def __setitem__(self, key, val):
201 def __setitem__(self, key, val):
166 """ You can do wb.foo['My Stuff'] = 12 to create children
202 """ You can do wb.foo['My Stuff'] = 12 to create children
167
203
168 This will create 'My Stuff' as a child of foo (if it does not exist), and
204 This will create 'My Stuff' as a child of foo (if it does not exist), and
169 do .v = 12 assignment.
205 do .v = 12 assignment.
170
206
171 Exception:
207 Exception:
172
208
173 wb.foo['bar'] = 12
209 wb.foo['bar'] = 12
174
210
175 will create a child with headline '@k bar', because bar is a valid python name
211 will create a child with headline '@k bar', because bar is a valid python name
176 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
212 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
177 """
213 """
178 key = str(key)
214 key = str(key)
179 d = self.__children()
215 d = self.__children()
180 if key in d:
216 if key in d:
181 d[key].v = val
217 d[key].v = val
182 return
218 return
183
219
184 if not valid_attribute(key):
220 if not valid_attribute(key):
185 head = key
221 head = key
186 else:
222 else:
187 head = '@k ' + key
223 head = '@k ' + key
188 p = c.createLastChildNode(self.p, head, '')
224 p = c.createLastChildNode(self.p, head, '')
189 LeoNode(p).v = val
225 LeoNode(p).v = val
190
226
191 def ipush(self):
227 def ipush(self):
192 """ Does push-to-ipython on the node """
228 """ Does push-to-ipython on the node """
193 push_from_leo(self)
229 push_from_leo(self)
194
230
195 def go(self):
231 def go(self):
196 """ Set node as current node (to quickly see it in Outline) """
232 """ Set node as current node (to quickly see it in Outline) """
197 c.beginUpdate()
233 c.beginUpdate()
198 try:
234 try:
199 c.setCurrentPosition(self.p)
235 c.setCurrentPosition(self.p)
200 finally:
236 finally:
201 c.endUpdate()
237 c.endUpdate()
202
238
203 def script(self):
239 def script(self):
204 """ Method to get the 'tangled' contents of the node
240 """ Method to get the 'tangled' contents of the node
205
241
206 (parse @others, << section >> references etc.)
242 (parse @others, << section >> references etc.)
207 """
243 """
208 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
244 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
209
245
210 def __get_uA(self):
246 def __get_uA(self):
211 p = self.p
247 p = self.p
212 # Create the uA if necessary.
248 # Create the uA if necessary.
213 if not hasattr(p.v.t,'unknownAttributes'):
249 if not hasattr(p.v.t,'unknownAttributes'):
214 p.v.t.unknownAttributes = {}
250 p.v.t.unknownAttributes = {}
215
251
216 d = p.v.t.unknownAttributes.setdefault('ipython', {})
252 d = p.v.t.unknownAttributes.setdefault('ipython', {})
217 return d
253 return d
218
254
219 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
255 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
220
256
221
257
222 class LeoWorkbook:
258 class LeoWorkbook:
223 """ class for 'advanced' node access
259 """ class for 'advanced' node access
224
260
225 Has attributes for all "discoverable" nodes. Node is discoverable if it
261 Has attributes for all "discoverable" nodes. Node is discoverable if it
226 either
262 either
227
263
228 - has a valid python name (Foo, bar_12)
264 - has a valid python name (Foo, bar_12)
229 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
265 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
230
266
231 """
267 """
232 def __getattr__(self, key):
268 def __getattr__(self, key):
233 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
269 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
234 raise AttributeError
270 raise AttributeError
235 cells = all_cells()
271 cells = all_cells()
236 p = cells.get(key, None)
272 p = cells.get(key, None)
237 if p is None:
273 if p is None:
238 p = add_var(key)
274 p = add_var(key)
239
275
240 return LeoNode(p)
276 return LeoNode(p)
241
277
242 def __str__(self):
278 def __str__(self):
243 return "<LeoWorkbook>"
279 return "<LeoWorkbook>"
244 def __setattr__(self,key, val):
280 def __setattr__(self,key, val):
245 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
281 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
246
282
247 __repr__ = __str__
283 __repr__ = __str__
248
284
249 def __iter__(self):
285 def __iter__(self):
250 """ Iterate all (even non-exposed) nodes """
286 """ Iterate all (even non-exposed) nodes """
251 cells = all_cells()
287 cells = all_cells()
252 return (LeoNode(p) for p in c.allNodes_iter())
288 return (LeoNode(p) for p in c.allNodes_iter())
253
289
254 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
290 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
255
291
256 def match_h(self, regex):
292 def match_h(self, regex):
257 cmp = re.compile(regex)
293 cmp = re.compile(regex)
258 for node in self:
294 for node in self:
259 if re.match(cmp, node.h, re.IGNORECASE):
295 if re.match(cmp, node.h, re.IGNORECASE):
260 yield node
296 yield node
261 return
297 return
262
263 ip.user_ns['wb'] = LeoWorkbook()
264
265
266
298
267 @IPython.generics.complete_object.when_type(LeoWorkbook)
299 @IPython.generics.complete_object.when_type(LeoWorkbook)
268 def workbook_complete(obj, prev):
300 def workbook_complete(obj, prev):
269 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
301 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
270
302
271
303
272 def add_var(varname):
304 def add_var(varname):
273 c.beginUpdate()
305 c.beginUpdate()
274 try:
306 try:
275 p2 = g.findNodeAnywhere(c,varname)
307 p2 = g.findNodeAnywhere(c,varname)
276 if p2:
308 if p2:
277 return
309 return
278
310
279 rootpos = g.findNodeAnywhere(c,'@ipy-results')
311 rootpos = g.findNodeAnywhere(c,'@ipy-results')
280 if not rootpos:
312 if not rootpos:
281 rootpos = c.currentPosition()
313 rootpos = c.currentPosition()
282 p2 = rootpos.insertAsLastChild()
314 p2 = rootpos.insertAsLastChild()
283 c.setHeadString(p2,varname)
315 c.setHeadString(p2,varname)
284 return p2
316 return p2
285 finally:
317 finally:
286 c.endUpdate()
318 c.endUpdate()
287
319
288 def add_file(self,fname):
320 def add_file(self,fname):
289 p2 = c.currentPosition().insertAfter()
321 p2 = c.currentPosition().insertAfter()
290
322
291 push_from_leo = CommandChainDispatcher()
323 push_from_leo = CommandChainDispatcher()
292
324
293 def expose_ileo_push(f, prio = 0):
325 def expose_ileo_push(f, prio = 0):
294 push_from_leo.add(f, prio)
326 push_from_leo.add(f, prio)
295
327
296 def push_ipython_script(node):
328 def push_ipython_script(node):
297 """ Execute the node body in IPython, as if it was entered in interactive prompt """
329 """ Execute the node body in IPython, as if it was entered in interactive prompt """
298 c.beginUpdate()
330 c.beginUpdate()
299 try:
331 try:
300 ohist = ip.IP.output_hist
332 ohist = ip.IP.output_hist
301 hstart = len(ip.IP.input_hist)
333 hstart = len(ip.IP.input_hist)
302 script = node.script()
334 script = node.script()
303
335
304 script = g.splitLines(script + '\n')
336 script = g.splitLines(script + '\n')
305
337
306 ip.runlines(script)
338 ip.runlines(script)
307
339
308 has_output = False
340 has_output = False
309 for idx in range(hstart,len(ip.IP.input_hist)):
341 for idx in range(hstart,len(ip.IP.input_hist)):
310 val = ohist.get(idx,None)
342 val = ohist.get(idx,None)
311 if val is None:
343 if val is None:
312 continue
344 continue
313 has_output = True
345 has_output = True
314 inp = ip.IP.input_hist[idx]
346 inp = ip.IP.input_hist[idx]
315 if inp.strip():
347 if inp.strip():
316 es('In: %s' % (inp[:40], ))
348 es('In: %s' % (inp[:40], ))
317
349
318 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
350 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
319
351
320 if not has_output:
352 if not has_output:
321 es('ipy run: %s (%d LL)' %( node.h,len(script)))
353 es('ipy run: %s (%d LL)' %( node.h,len(script)))
322 finally:
354 finally:
323 c.endUpdate()
355 c.endUpdate()
324
356
325 # this should be the LAST one that will be executed, and it will never raise TryNext
326 expose_ileo_push(push_ipython_script, 1000)
327
357
328 def eval_body(body):
358 def eval_body(body):
329 try:
359 try:
330 val = ip.ev(body)
360 val = ip.ev(body)
331 except:
361 except:
332 # just use stringlist if it's not completely legal python expression
362 # just use stringlist if it's not completely legal python expression
333 val = IPython.genutils.SList(body.splitlines())
363 val = IPython.genutils.SList(body.splitlines())
334 return val
364 return val
335
365
336 def push_plain_python(node):
366 def push_plain_python(node):
337 if not node.h.endswith('P'):
367 if not node.h.endswith('P'):
338 raise TryNext
368 raise TryNext
339 script = node.script()
369 script = node.script()
340 lines = script.count('\n')
370 lines = script.count('\n')
341 try:
371 try:
342 exec script in ip.user_ns
372 exec script in ip.user_ns
343 except:
373 except:
344 print " -- Exception in script:\n"+script + "\n --"
374 print " -- Exception in script:\n"+script + "\n --"
345 raise
375 raise
346 es('ipy plain: %s (%d LL)' % (node.h,lines))
376 es('ipy plain: %s (%d LL)' % (node.h,lines))
347
377
348 expose_ileo_push(push_plain_python, 100)
349
378
350 def push_cl_node(node):
379 def push_cl_node(node):
351 """ If node starts with @cl, eval it
380 """ If node starts with @cl, eval it
352
381
353 The result is put to root @ipy-results node
382 The result is put to root @ipy-results node
354 """
383 """
355 if not node.b.startswith('@cl'):
384 if not node.b.startswith('@cl'):
356 raise TryNext
385 raise TryNext
357
386
358 p2 = g.findNodeAnywhere(c,'@ipy-results')
387 p2 = g.findNodeAnywhere(c,'@ipy-results')
359 val = node.v
388 val = node.v
360 if p2:
389 if p2:
361 es("=> @ipy-results")
390 es("=> @ipy-results")
362 LeoNode(p2).v = val
391 LeoNode(p2).v = val
363 es(val)
392 es(val)
364
393
365 expose_ileo_push(push_cl_node,100)
394
366
395
367 def push_position_from_leo(p):
396 def push_position_from_leo(p):
368 push_from_leo(LeoNode(p))
397 push_from_leo(LeoNode(p))
369
370 ip.user_ns['leox'].push = push_position_from_leo
371
398
372 def leo_f(self,s):
399 def leo_f(self,s):
373 """ open file(s) in Leo
400 """ open file(s) in Leo
374
401
375 Takes an mglob pattern, e.g. '%leo *.cpp' or %leo 'rec:*.cpp'
402 Takes an mglob pattern, e.g. '%leo *.cpp' or %leo 'rec:*.cpp'
376 """
403 """
377 import os
404 import os
378 from IPython.external import mglob
405 from IPython.external import mglob
379
406
380 files = mglob.expand(s)
407 files = mglob.expand(s)
381 c.beginUpdate()
408 c.beginUpdate()
382 try:
409 try:
383 for fname in files:
410 for fname in files:
384 p = g.findNodeAnywhere(c,'@auto ' + fname)
411 p = g.findNodeAnywhere(c,'@auto ' + fname)
385 if not p:
412 if not p:
386 p = c.currentPosition().insertAfter()
413 p = c.currentPosition().insertAfter()
387
414
388 p.setHeadString('@auto ' + fname)
415 p.setHeadString('@auto ' + fname)
389 if os.path.isfile(fname):
416 if os.path.isfile(fname):
390 c.setBodyString(p,open(fname).read())
417 c.setBodyString(p,open(fname).read())
391 c.selectPosition(p)
418 c.selectPosition(p)
392 finally:
419 finally:
393 c.endUpdate()
420 c.endUpdate()
394
421
395 ip.expose_magic('leo',leo_f)
422
396
423
397 def leoref_f(self,s):
424 def leoref_f(self,s):
398 """ Quick reference for ILeo """
425 """ Quick reference for ILeo """
399 import textwrap
426 import textwrap
400 print textwrap.dedent("""\
427 print textwrap.dedent("""\
401 %leo file - open file in leo
428 %leo file - open file in leo
402 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
429 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
403 wb.foo.v = 12 - assign to body of node foo
430 wb.foo.v = 12 - assign to body of node foo
404 wb.foo.b - read or write the body of node foo
431 wb.foo.b - read or write the body of node foo
405 wb.foo.l - body of node foo as string list
432 wb.foo.l - body of node foo as string list
406
433
407 for el in wb.foo:
434 for el in wb.foo:
408 print el.v
435 print el.v
409
436
410 """
437 """
411 )
438 )
412 ip.expose_magic('leoref',leoref_f)
413
439
414 from ipy_leo import *
415
440
416 ip = IPython.ipapi.get()
417
441
418 def mb_f(self, arg):
442 def mb_f(self, arg):
419 """ Execute leo minibuffer commands """
443 """ Execute leo minibuffer commands
444
445 Example:
446 mb save-to-file
447 """
420 c.executeMinibufferCommand(arg)
448 c.executeMinibufferCommand(arg)
421
449
422 def mb_completer(self,event):
450 def mb_completer(self,event):
423 """ Custom completer for minibuffer """
451 """ Custom completer for minibuffer """
424 cmd_param = event.line.split()
452 cmd_param = event.line.split()
425 if event.line.endswith(' '):
453 if event.line.endswith(' '):
426 cmd_param.append('')
454 cmd_param.append('')
427 if len(cmd_param) > 2:
455 if len(cmd_param) > 2:
428 return ip.IP.Completer.file_matches(event.symbol)
456 return ip.IP.Completer.file_matches(event.symbol)
429 cmds = c.commandsDict.keys()
457 cmds = c.commandsDict.keys()
430 cmds.sort()
458 cmds.sort()
431 return cmds
459 return cmds
432
460
433 pass
434 ip.set_hook('complete_command', mb_completer, str_key = 'mb')
435 ip.expose_magic('mb',mb_f)
436
437
438 def show_welcome():
461 def show_welcome():
439 print "------------------"
462 print "------------------"
440 print "Welcome to Leo-enabled IPython session!"
463 print "Welcome to Leo-enabled IPython session!"
441 print "Try %leoref for quick reference."
464 print "Try %leoref for quick reference."
442 import IPython.platutils
465 import IPython.platutils
443 IPython.platutils.set_term_title('ILeo')
466 IPython.platutils.set_term_title('ILeo')
444 IPython.platutils.freeze_term_title()
467 IPython.platutils.freeze_term_title()
445
468
446 def run_leo_startup_node():
469 def run_leo_startup_node():
447 p = g.findNodeAnywhere(c,'@ipy-startup')
470 p = g.findNodeAnywhere(c,'@ipy-startup')
448 if p:
471 if p:
449 print "Running @ipy-startup nodes"
472 print "Running @ipy-startup nodes"
450 for n in LeoNode(p):
473 for n in LeoNode(p):
451 push_from_leo(n)
474 push_from_leo(n)
452
453 run_leo_startup_node()
454 show_welcome()
455
General Comments 0
You need to be logged in to leave comments. Login now