##// END OF EJS Templates
ipy_leo: push_plain_python (if P suffix in headstring)
Ville M. Vainio -
Show More
@@ -1,248 +1,257 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):
212 script = g.getScript(c,p,useSelectedText=False,forcePythonSentinels=False,useSentinels=False)
213 exec script in ip.user_ns
214 g.es('ipy plain: %s' % (p.headString(),), tabName = "IPython")
215
211 def push_from_leo(p):
216 def push_from_leo(p):
212 tup = p.headString().split(None,1)
217 h = p.headString()
218 tup = h.split(None,1)
213 # @ipy foo is variable foo
219 # @ipy foo is variable foo
214 if len(tup) == 2 and tup[0] == '@ipy':
220 if len(tup) == 2 and tup[0] == '@ipy':
215 varname = tup[1]
221 varname = tup[1]
216 push_variable(p,varname)
222 push_variable(p,varname)
217 return
223 return
224 if h.endswith('P'):
225 push_plain_python(p)
226 return
218
227
219 push_script(p)
228 push_script(p)
220 return
229 return
221
230
222
231
223 ip.user_ns['leox'].push = push_from_leo
232 ip.user_ns['leox'].push = push_from_leo
224
233
225 def leo_f(self,s):
234 def leo_f(self,s):
226 """ open file(s) in Leo
235 """ open file(s) in Leo
227
236
228 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'
229 """
238 """
230 import os
239 import os
231 from IPython.external import mglob
240 from IPython.external import mglob
232
241
233 files = mglob.expand(s)
242 files = mglob.expand(s)
234 c.beginUpdate()
243 c.beginUpdate()
235 try:
244 try:
236 for fname in files:
245 for fname in files:
237 p = g.findNodeAnywhere(c,'@auto ' + fname)
246 p = g.findNodeAnywhere(c,'@auto ' + fname)
238 if not p:
247 if not p:
239 p = c.currentPosition().insertAfter()
248 p = c.currentPosition().insertAfter()
240
249
241 p.setHeadString('@auto ' + fname)
250 p.setHeadString('@auto ' + fname)
242 if os.path.isfile(fname):
251 if os.path.isfile(fname):
243 c.setBodyString(p,open(fname).read())
252 c.setBodyString(p,open(fname).read())
244 c.selectPosition(p)
253 c.selectPosition(p)
245 finally:
254 finally:
246 c.endUpdate()
255 c.endUpdate()
247
256
248 ip.expose_magic('leo',leo_f)
257 ip.expose_magic('leo',leo_f)
General Comments 0
You need to be logged in to leave comments. Login now