##// END OF EJS Templates
ipy_leo improvements (%leo opens a file as @auto file)
ville -
Show More
@@ -1,215 +1,248 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 """ class to find cells """
56 """ class to find cells with simple syntax
57
58 """
57 59 def __getattr__(self, key):
58 60 cells = all_cells()
59 61 p = cells[key]
60 62 body = p.bodyString()
61 63 return eval_body(body)
62 64 def __setattr__(self,key,val):
63 65 cells = all_cells()
64 66 p = cells.get(key,None)
65 67 if p is None:
66 68 add_var(key,val)
67 69 else:
68 70 c.setBodyString(p,format_for_leo(val))
69 71 def __str__(self):
70 72 return "<TrivialLeoWorkbook>"
71 73 __repr__ = __str__
72 74
73 75 ip.user_ns['nodes'] = TrivialLeoWorkbook()
74 76
75 77
76 78 class LeoNode(object):
77 79 def __init__(self,p):
78 80 self.p = p.copy()
79 81
80 82 def get_h(self): return self.p.headString()
81 83 def set_h(self,val):
82 print "set head",val
83 c.setHeadString(self.p,val)
84 print "set head",val
85 c.beginUpdate()
86 try:
87 c.setHeadString(self.p,val)
88 finally:
89 c.endUpdate()
84 90
85 91 h = property( get_h, set_h)
86 92
87 93 def get_b(self): return self.p.bodyString()
88 94 def set_b(self,val):
89 print "set body",val
90 c.setBodyString(self.p, val)
95 print "set body",val
96 c.beginUpdate()
97 try:
98 c.setBodyString(self.p, val)
99 finally:
100 c.endUpdate()
91 101
92 102 b = property(get_b, set_b)
93 103
94 104 def set_val(self, val):
95 105 self.b = pprint.pformat(val)
96 106
97 val = property(lambda self: ip.ev(self.b.strip()), set_val)
107 v = property(lambda self: ip.ev(self.b.strip()), set_val)
98 108
99 109 def set_l(self,val):
100 110 self.b = '\n'.join(val )
101 111 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
102 112 set_l)
103 113
104 114 def __iter__(self):
105 115 return (LeoNode(p) for p in self.p.children_iter())
106 116
107 117
108 118 class LeoWorkbook:
109 119 """ class for 'advanced' node access """
110 120 def __getattr__(self, key):
111 121 if key.startswith('_') or key == 'trait_names':
112 122 raise AttributeError
113 123 cells = all_cells()
114 124 p = cells.get(key, None)
115 125 if p is None:
116 126 p = add_var(key,None)
117 127
118 128 return LeoNode(p)
119 129
120 130 def __str__(self):
121 131 return "<LeoWorkbook>"
122 132 __repr__ = __str__
123 133 ip.user_ns['wb'] = LeoWorkbook()
124 134
125 135
126 136 _dummyval = object()
127 137 @IPython.generics.complete_object.when_type(LeoWorkbook)
128 138 def workbook_complete(obj, prev):
129 139 return all_cells().keys()
130 140
131 141
132 142 def add_var(varname, value = _dummyval):
133 nodename = '@ipy-var ' + varname
134 p2 = g.findNodeAnywhere(c,nodename)
135 if not c.positionExists(p2):
136 p2 = c.currentPosition().insertAfter()
137 c.setHeadString(p2,'@ipy ' + varname)
143 c.beginUpdate()
144 try:
138 145
139 c.setCurrentPosition(p2)
140 if value is _dummyval:
141 val = ip.user_ns[varname]
142 else:
143 val = value
144 if val is not None:
145 formatted = format_for_leo(val)
146 c.setBodyString(p2,formatted)
147 return p2
146 nodename = '@ipy-var ' + varname
147 p2 = g.findNodeAnywhere(c,nodename)
148 if not c.positionExists(p2):
149 p2 = c.currentPosition().insertAfter()
150 c.setHeadString(p2,'@ipy ' + varname)
151
152 c.setCurrentPosition(p2)
153 if value is _dummyval:
154 val = ip.user_ns[varname]
155 else:
156 val = value
157 if val is not None:
158 formatted = format_for_leo(val)
159 c.setBodyString(p2,formatted)
160 return p2
161 finally:
162 c.endUpdate()
148 163
149 164 def add_file(self,fname):
150 165 p2 = c.currentPosition().insertAfter()
151 166
152 167 def push_script(p):
153 ohist = ip.IP.output_hist
154 hstart = len(ip.IP.input_hist)
155 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
156
157 script = g.splitLines(script + '\n')
158 script = ''.join(z for z in script if z.strip())
159
160 ip.runlines(script)
161
162 has_output = False
163 for idx in range(hstart,len(ip.IP.input_hist)):
164 val = ohist.get(idx,None)
165 if val is None:
166 continue
167 has_output = True
168 inp = ip.IP.input_hist[idx]
169 if inp.strip():
170 g.es('In: %s' % (inp[:40], ), tabName = 'IPython')
171
172 g.es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)), tabName = 'IPython')
173
174 if not has_output:
175 g.es('ipy run: %s' %( p.headString(),), tabName = 'IPython')
168 c.beginUpdate()
169 try:
170 ohist = ip.IP.output_hist
171 hstart = len(ip.IP.input_hist)
172 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
173
174 script = g.splitLines(script + '\n')
175 script = ''.join(z for z in script if z.strip())
176
177 ip.runlines(script)
178
179 has_output = False
180 for idx in range(hstart,len(ip.IP.input_hist)):
181 val = ohist.get(idx,None)
182 if val is None:
183 continue
184 has_output = True
185 inp = ip.IP.input_hist[idx]
186 if inp.strip():
187 g.es('In: %s' % (inp[:40], ), tabName = 'IPython')
188
189 g.es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)), tabName = 'IPython')
190
191 if not has_output:
192 g.es('ipy run: %s' %( p.headString(),), tabName = 'IPython')
193 finally:
194 c.endUpdate()
176 195
177 196
178 197 def eval_body(body):
179 198 try:
180 199 val = ip.ev(body)
181 200 except:
182 201 # just use stringlist if it's not completely legal python expression
183 202 val = IPython.genutils.SList(body.splitlines())
184 203 return val
185 204
186 205 def push_variable(p,varname):
187 206 body = p.bodyString()
188 207 val = eval_body(body.strip())
189 208 ip.user_ns[varname] = val
190 209 g.es('ipy var: %s' % (varname,), tabName = "IPython")
191 210
192 def push_from_leo(p):
193 # headstring without @ are just scripts
194 if not p.headString().startswith('@'):
195 push_script(p)
196 return
211 def push_from_leo(p):
197 212 tup = p.headString().split(None,1)
198 213 # @ipy foo is variable foo
199 214 if len(tup) == 2 and tup[0] == '@ipy':
200 215 varname = tup[1]
201 216 push_variable(p,varname)
202 217 return
218
219 push_script(p)
220 return
221
203 222
204 223 ip.user_ns['leox'].push = push_from_leo
205 224
206 225 def leo_f(self,s):
207 ip = self.getapi()
208 s = s.strip()
209 if s in ip.user_ns:
210 add_var(s)
211 elif os.path.isfile(s):
212 # todo open file
213 pass
226 """ open file(s) in Leo
227
228 Takes an mglob pattern, e.g. '%leo *.cpp' or %leo 'rec:*.cpp'
229 """
230 import os
231 from IPython.external import mglob
232
233 files = mglob.expand(s)
234 c.beginUpdate()
235 try:
236 for fname in files:
237 p = g.findNodeAnywhere(c,'@auto ' + fname)
238 if not p:
239 p = c.currentPosition().insertAfter()
240
241 p.setHeadString('@auto ' + fname)
242 if os.path.isfile(fname):
243 c.setBodyString(p,open(fname).read())
244 c.selectPosition(p)
245 finally:
246 c.endUpdate()
214 247
215 248 ip.expose_magic('leo',leo_f)
General Comments 0
You need to be logged in to leave comments. Login now