##// END OF EJS Templates
ipy_leo: @ipy-startup
Ville M. Vainio -
Show More
@@ -1,284 +1,291 b''
1 """ Leo plugin for IPython
1 """ Leo plugin for IPython
2
2
3 Example use:
3 Example use:
4
4
5 nodes.foo = "hello world"
5 nodes.foo = "hello world"
6
6
7 -> create '@ipy foo' node with text "hello world"
7 -> create '@ipy foo' node with text "hello world"
8
8
9 Access works also, and so does tab completion.
9 Access works also, and so does tab completion.
10
10
11 """
11 """
12 import IPython.ipapi
12 import IPython.ipapi
13 import IPython.genutils
13 import IPython.genutils
14 import IPython.generics
14 import IPython.generics
15 import re
15 import re
16
16
17
17
18
18
19 ip = IPython.ipapi.get()
19 ip = IPython.ipapi.get()
20 leo = ip.user_ns['leox']
20 leo = ip.user_ns['leox']
21 c,g = leo.c, leo.g
21 c,g = leo.c, leo.g
22
22
23 # will probably be overwritten by user, but handy for experimentation early on
23 # will probably be overwritten by user, but handy for experimentation early on
24 ip.user_ns['c'] = c
24 ip.user_ns['c'] = c
25 ip.user_ns['g'] = g
25 ip.user_ns['g'] = g
26
26
27
27
28 from IPython.external.simplegeneric import generic
28 from IPython.external.simplegeneric import generic
29 import pprint
29 import pprint
30
30
31 @generic
31 @generic
32 def format_for_leo(obj):
32 def format_for_leo(obj):
33 """ Convert obj to string representiation (for editing in Leo)"""
33 """ Convert obj to string representiation (for editing in Leo)"""
34 return pprint.pformat(obj)
34 return pprint.pformat(obj)
35
35
36 @format_for_leo.when_type(list)
36 @format_for_leo.when_type(list)
37 def format_list(obj):
37 def format_list(obj):
38 return "\n".join(str(s) for s in obj)
38 return "\n".join(str(s) for s in obj)
39
39
40 nodename_re = r'(@ipy?[\w-]+)?\s?(\w+)'
40 nodename_re = r'(@ipy?[\w-]+)?\s?(\w+)'
41
41
42 def all_cells():
42 def all_cells():
43 d = {}
43 d = {}
44 for p in c.allNodes_iter():
44 for p in c.allNodes_iter():
45 h = p.headString()
45 h = p.headString()
46 if h.startswith('@') and len(h.split()) == 1:
46 if h.startswith('@') and len(h.split()) == 1:
47 continue
47 continue
48 mo = re.match(nodename_re, h)
48 mo = re.match(nodename_re, h)
49 if not mo:
49 if not mo:
50 continue
50 continue
51 d[mo.group(2)] = p.copy()
51 d[mo.group(2)] = p.copy()
52 return d
52 return d
53
53
54
54
55 class TrivialLeoWorkbook:
55 class TrivialLeoWorkbook:
56 """ class to find cells with simple syntax
56 """ class to find cells with simple syntax
57
57
58 """
58 """
59 def __getattr__(self, key):
59 def __getattr__(self, key):
60 cells = all_cells()
60 cells = all_cells()
61 p = cells[key]
61 p = cells[key]
62 body = p.bodyString()
62 body = p.bodyString()
63 return eval_body(body)
63 return eval_body(body)
64 def __setattr__(self,key,val):
64 def __setattr__(self,key,val):
65 cells = all_cells()
65 cells = all_cells()
66 p = cells.get(key,None)
66 p = cells.get(key,None)
67 if p is None:
67 if p is None:
68 add_var(key,val)
68 add_var(key,val)
69 else:
69 else:
70 c.setBodyString(p,format_for_leo(val))
70 c.setBodyString(p,format_for_leo(val))
71 def __str__(self):
71 def __str__(self):
72 return "<TrivialLeoWorkbook>"
72 return "<TrivialLeoWorkbook>"
73 __repr__ = __str__
73 __repr__ = __str__
74
74
75 ip.user_ns['nodes'] = TrivialLeoWorkbook()
75 ip.user_ns['nodes'] = TrivialLeoWorkbook()
76
76
77
77
78 class LeoNode(object):
78 class LeoNode(object):
79 def __init__(self,p):
79 def __init__(self,p):
80 self.p = p.copy()
80 self.p = p.copy()
81
81
82 def get_h(self): return self.p.headString()
82 def get_h(self): return self.p.headString()
83 def set_h(self,val):
83 def set_h(self,val):
84 print "set head",val
84 print "set head",val
85 c.beginUpdate()
85 c.beginUpdate()
86 try:
86 try:
87 c.setHeadString(self.p,val)
87 c.setHeadString(self.p,val)
88 finally:
88 finally:
89 c.endUpdate()
89 c.endUpdate()
90
90
91 h = property( get_h, set_h)
91 h = property( get_h, set_h)
92
92
93 def get_b(self): return self.p.bodyString()
93 def get_b(self): return self.p.bodyString()
94 def set_b(self,val):
94 def set_b(self,val):
95 print "set body",val
95 print "set body",val
96 c.beginUpdate()
96 c.beginUpdate()
97 try:
97 try:
98 c.setBodyString(self.p, val)
98 c.setBodyString(self.p, val)
99 finally:
99 finally:
100 c.endUpdate()
100 c.endUpdate()
101
101
102 b = property(get_b, set_b)
102 b = property(get_b, set_b)
103
103
104 def set_val(self, val):
104 def set_val(self, val):
105 self.b = pprint.pformat(val)
105 self.b = pprint.pformat(val)
106
106
107 v = property(lambda self: ip.ev(self.b.strip()), set_val)
107 v = property(lambda self: ip.ev(self.b.strip()), set_val)
108
108
109 def set_l(self,val):
109 def set_l(self,val):
110 self.b = '\n'.join(val )
110 self.b = '\n'.join(val )
111 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
111 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
112 set_l)
112 set_l)
113
113
114 def __iter__(self):
114 def __iter__(self):
115 return (LeoNode(p) for p in self.p.children_iter())
115 return (LeoNode(p) for p in self.p.children_iter())
116
116
117
117
118 class LeoWorkbook:
118 class LeoWorkbook:
119 """ class for 'advanced' node access """
119 """ class for 'advanced' node access """
120 def __getattr__(self, key):
120 def __getattr__(self, key):
121 if key.startswith('_') or key == 'trait_names':
121 if key.startswith('_') or key == 'trait_names':
122 raise AttributeError
122 raise AttributeError
123 cells = all_cells()
123 cells = all_cells()
124 p = cells.get(key, None)
124 p = cells.get(key, None)
125 if p is None:
125 if p is None:
126 p = add_var(key,None)
126 p = add_var(key,None)
127
127
128 return LeoNode(p)
128 return LeoNode(p)
129
129
130 def __str__(self):
130 def __str__(self):
131 return "<LeoWorkbook>"
131 return "<LeoWorkbook>"
132 __repr__ = __str__
132 __repr__ = __str__
133 ip.user_ns['wb'] = LeoWorkbook()
133 ip.user_ns['wb'] = LeoWorkbook()
134
134
135
135
136 _dummyval = object()
136 _dummyval = object()
137 @IPython.generics.complete_object.when_type(LeoWorkbook)
137 @IPython.generics.complete_object.when_type(LeoWorkbook)
138 def workbook_complete(obj, prev):
138 def workbook_complete(obj, prev):
139 return all_cells().keys()
139 return all_cells().keys()
140
140
141
141
142 def add_var(varname, value = _dummyval):
142 def add_var(varname, value = _dummyval):
143 c.beginUpdate()
143 c.beginUpdate()
144 try:
144 try:
145
145
146 nodename = '@ipy-var ' + varname
146 nodename = '@ipy-var ' + varname
147 p2 = g.findNodeAnywhere(c,nodename)
147 p2 = g.findNodeAnywhere(c,nodename)
148 if not c.positionExists(p2):
148 if not c.positionExists(p2):
149 p2 = c.currentPosition().insertAfter()
149 p2 = c.currentPosition().insertAfter()
150 c.setHeadString(p2,'@ipy ' + varname)
150 c.setHeadString(p2,'@ipy ' + varname)
151
151
152 c.setCurrentPosition(p2)
152 c.setCurrentPosition(p2)
153 if value is _dummyval:
153 if value is _dummyval:
154 val = ip.user_ns[varname]
154 val = ip.user_ns[varname]
155 else:
155 else:
156 val = value
156 val = value
157 if val is not None:
157 if val is not None:
158 formatted = format_for_leo(val)
158 formatted = format_for_leo(val)
159 c.setBodyString(p2,formatted)
159 c.setBodyString(p2,formatted)
160 return p2
160 return p2
161 finally:
161 finally:
162 c.endUpdate()
162 c.endUpdate()
163
163
164 def add_file(self,fname):
164 def add_file(self,fname):
165 p2 = c.currentPosition().insertAfter()
165 p2 = c.currentPosition().insertAfter()
166
166
167 def push_script(p):
167 def push_script(p):
168 c.beginUpdate()
168 c.beginUpdate()
169 try:
169 try:
170 ohist = ip.IP.output_hist
170 ohist = ip.IP.output_hist
171 hstart = len(ip.IP.input_hist)
171 hstart = len(ip.IP.input_hist)
172 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
172 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
173
173
174 script = g.splitLines(script + '\n')
174 script = g.splitLines(script + '\n')
175 script = ''.join(z for z in script if z.strip())
175 script = ''.join(z for z in script if z.strip())
176
176
177 ip.runlines(script)
177 ip.runlines(script)
178
178
179 has_output = False
179 has_output = False
180 for idx in range(hstart,len(ip.IP.input_hist)):
180 for idx in range(hstart,len(ip.IP.input_hist)):
181 val = ohist.get(idx,None)
181 val = ohist.get(idx,None)
182 if val is None:
182 if val is None:
183 continue
183 continue
184 has_output = True
184 has_output = True
185 inp = ip.IP.input_hist[idx]
185 inp = ip.IP.input_hist[idx]
186 if inp.strip():
186 if inp.strip():
187 g.es('In: %s' % (inp[:40], ), tabName = 'IPython')
187 g.es('In: %s' % (inp[:40], ), tabName = 'IPython')
188
188
189 g.es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)), tabName = 'IPython')
189 g.es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)), tabName = 'IPython')
190
190
191 if not has_output:
191 if not has_output:
192 g.es('ipy run: %s' %( p.headString(),), tabName = 'IPython')
192 g.es('ipy run: %s' %( p.headString(),), tabName = 'IPython')
193 finally:
193 finally:
194 c.endUpdate()
194 c.endUpdate()
195
195
196
196
197 def eval_body(body):
197 def eval_body(body):
198 try:
198 try:
199 val = ip.ev(body)
199 val = ip.ev(body)
200 except:
200 except:
201 # just use stringlist if it's not completely legal python expression
201 # just use stringlist if it's not completely legal python expression
202 val = IPython.genutils.SList(body.splitlines())
202 val = IPython.genutils.SList(body.splitlines())
203 return val
203 return val
204
204
205 def push_variable(p,varname):
205 def push_variable(p,varname):
206 body = p.bodyString()
206 body = p.bodyString()
207 val = eval_body(body.strip())
207 val = eval_body(body.strip())
208 ip.user_ns[varname] = val
208 ip.user_ns[varname] = val
209 g.es('ipy var: %s' % (varname,), tabName = "IPython")
209 g.es('ipy var: %s' % (varname,), tabName = "IPython")
210
210
211 def push_plain_python(p):
211 def push_plain_python(p):
212 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
212 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
213 exec script in ip.user_ns
213 exec script in ip.user_ns
214 g.es('ipy plain: %s' % (p.headString(),), tabName = "IPython")
214 g.es('ipy plain: %s' % (p.headString(),), tabName = "IPython")
215
215
216 def push_from_leo(p):
216 def push_from_leo(p):
217 h = p.headString()
217 h = p.headString()
218 tup = h.split(None,1)
218 tup = h.split(None,1)
219 # @ipy foo is variable foo
219 # @ipy foo is variable foo
220 if len(tup) == 2 and tup[0] == '@ipy':
220 if len(tup) == 2 and tup[0] == '@ipy':
221 varname = tup[1]
221 varname = tup[1]
222 push_variable(p,varname)
222 push_variable(p,varname)
223 return
223 return
224 if h.endswith('P'):
224 if h.endswith('P'):
225 push_plain_python(p)
225 push_plain_python(p)
226 return
226 return
227
227
228 push_script(p)
228 push_script(p)
229 return
229 return
230
230
231
231
232 ip.user_ns['leox'].push = push_from_leo
232 ip.user_ns['leox'].push = push_from_leo
233
233
234 def leo_f(self,s):
234 def leo_f(self,s):
235 """ open file(s) in Leo
235 """ open file(s) in Leo
236
236
237 Takes an mglob pattern, e.g. '%leo *.cpp' or %leo 'rec:*.cpp'
237 Takes an mglob pattern, e.g. '%leo *.cpp' or %leo 'rec:*.cpp'
238 """
238 """
239 import os
239 import os
240 from IPython.external import mglob
240 from IPython.external import mglob
241
241
242 files = mglob.expand(s)
242 files = mglob.expand(s)
243 c.beginUpdate()
243 c.beginUpdate()
244 try:
244 try:
245 for fname in files:
245 for fname in files:
246 p = g.findNodeAnywhere(c,'@auto ' + fname)
246 p = g.findNodeAnywhere(c,'@auto ' + fname)
247 if not p:
247 if not p:
248 p = c.currentPosition().insertAfter()
248 p = c.currentPosition().insertAfter()
249
249
250 p.setHeadString('@auto ' + fname)
250 p.setHeadString('@auto ' + fname)
251 if os.path.isfile(fname):
251 if os.path.isfile(fname):
252 c.setBodyString(p,open(fname).read())
252 c.setBodyString(p,open(fname).read())
253 c.selectPosition(p)
253 c.selectPosition(p)
254 finally:
254 finally:
255 c.endUpdate()
255 c.endUpdate()
256
256
257 ip.expose_magic('leo',leo_f)
257 ip.expose_magic('leo',leo_f)
258
258
259 def leoref_f(self,s):
259 def leoref_f(self,s):
260 import textwrap
260 import textwrap
261 print textwrap.dedent("""\
261 print textwrap.dedent("""\
262 %leo file - open file in leo
262 %leo file - open file in leo
263 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
263 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
264 wb.foo.v = 12 - assign to body of node foo
264 wb.foo.v = 12 - assign to body of node foo
265 wb.foo.b - read or write the body of node foo
265 wb.foo.b - read or write the body of node foo
266 wb.foo.l - body of node foo as string list
266 wb.foo.l - body of node foo as string list
267
267
268 for el in wb.foo:
268 for el in wb.foo:
269 print el.v
269 print el.v
270
270
271
272 """
271 """
273 )
272 )
274 ip.expose_magic('leoref',leoref_f)
273 ip.expose_magic('leoref',leoref_f)
275
274
276 def show_welcome():
275 def show_welcome():
277 print "------------------"
276 print "------------------"
278 print "Welcome to Leo-enabled IPython session!"
277 print "Welcome to Leo-enabled IPython session!"
279 print "Try %leoref for quick reference."
278 print "Try %leoref for quick reference."
280 import IPython.platutils
279 import IPython.platutils
281 IPython.platutils.set_term_title('Leo IPython')
280 IPython.platutils.set_term_title('Leo IPython')
282 IPython.platutils.freeze_term_title()
281 IPython.platutils.freeze_term_title()
282
283 def run_leo_startup_node():
284 p = g.findNodeAnywhere(c,'@ipy-startup')
285 if p:
286 print "Running @ipy-startup"
287 push_script(p)
288
289 run_leo_startup_node()
283 show_welcome()
290 show_welcome()
284
291
General Comments 0
You need to be logged in to leave comments. Login now