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