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