##// END OF EJS Templates
fix %rep docs
vivainio -
Show More
@@ -1,239 +1,241 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 """ History related magics and functionality """
3 """ History related magics and functionality """
4
4
5 import fnmatch
5 import fnmatch
6
6
7 def magic_history(self, parameter_s = ''):
7 def magic_history(self, parameter_s = ''):
8 """Print input history (_i<n> variables), with most recent last.
8 """Print input history (_i<n> variables), with most recent last.
9
9
10 %history -> print at most 40 inputs (some may be multi-line)\\
10 %history -> print at most 40 inputs (some may be multi-line)\\
11 %history n -> print at most n inputs\\
11 %history n -> print at most n inputs\\
12 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
12 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
13
13
14 Each input's number <n> is shown, and is accessible as the
14 Each input's number <n> is shown, and is accessible as the
15 automatically generated variable _i<n>. Multi-line statements are
15 automatically generated variable _i<n>. Multi-line statements are
16 printed starting at a new line for easy copy/paste.
16 printed starting at a new line for easy copy/paste.
17
17
18
18
19 Options:
19 Options:
20
20
21 -n: do NOT print line numbers. This is useful if you want to get a
21 -n: do NOT print line numbers. This is useful if you want to get a
22 printout of many lines which can be directly pasted into a text
22 printout of many lines which can be directly pasted into a text
23 editor.
23 editor.
24
24
25 This feature is only available if numbered prompts are in use.
25 This feature is only available if numbered prompts are in use.
26
26
27 -t: (default) print the 'translated' history, as IPython understands it.
27 -t: (default) print the 'translated' history, as IPython understands it.
28 IPython filters your input and converts it all into valid Python source
28 IPython filters your input and converts it all into valid Python source
29 before executing it (things like magics or aliases are turned into
29 before executing it (things like magics or aliases are turned into
30 function calls, for example). With this option, you'll see the native
30 function calls, for example). With this option, you'll see the native
31 history instead of the user-entered version: '%cd /' will be seen as
31 history instead of the user-entered version: '%cd /' will be seen as
32 '_ip.magic("%cd /")' instead of '%cd /'.
32 '_ip.magic("%cd /")' instead of '%cd /'.
33
33
34 -r: print the 'raw' history, i.e. the actual commands you typed.
34 -r: print the 'raw' history, i.e. the actual commands you typed.
35
35
36 -g: treat the arg as a pattern to grep for in (full) history.
36 -g: treat the arg as a pattern to grep for in (full) history.
37 This includes the "shadow history" (almost all commands ever written).
37 This includes the "shadow history" (almost all commands ever written).
38 Use '%hist -g' to show full shadow history (may be very long).
38 Use '%hist -g' to show full shadow history (may be very long).
39 In shadow history, every index nuwber starts with 0.
39 In shadow history, every index nuwber starts with 0.
40
40
41
41
42 """
42 """
43
43
44 ip = self.api
44 ip = self.api
45 shell = self.shell
45 shell = self.shell
46 if not shell.outputcache.do_full_cache:
46 if not shell.outputcache.do_full_cache:
47 print 'This feature is only available if numbered prompts are in use.'
47 print 'This feature is only available if numbered prompts are in use.'
48 return
48 return
49 opts,args = self.parse_options(parameter_s,'gntsr',mode='list')
49 opts,args = self.parse_options(parameter_s,'gntsr',mode='list')
50
50
51 if opts.has_key('t'):
51 if opts.has_key('t'):
52 input_hist = shell.input_hist
52 input_hist = shell.input_hist
53 elif opts.has_key('r'):
53 elif opts.has_key('r'):
54 input_hist = shell.input_hist_raw
54 input_hist = shell.input_hist_raw
55 else:
55 else:
56 input_hist = shell.input_hist
56 input_hist = shell.input_hist
57
57
58
58
59 default_length = 40
59 default_length = 40
60 pattern = None
60 pattern = None
61 if opts.has_key('g'):
61 if opts.has_key('g'):
62 init = 1
62 init = 1
63 final = len(input_hist)
63 final = len(input_hist)
64 parts = parameter_s.split(None,1)
64 parts = parameter_s.split(None,1)
65 if len(parts) == 1:
65 if len(parts) == 1:
66 parts += '*'
66 parts += '*'
67 head, pattern = parts
67 head, pattern = parts
68 pattern = "*" + pattern + "*"
68 pattern = "*" + pattern + "*"
69 elif len(args) == 0:
69 elif len(args) == 0:
70 final = len(input_hist)
70 final = len(input_hist)
71 init = max(1,final-default_length)
71 init = max(1,final-default_length)
72 elif len(args) == 1:
72 elif len(args) == 1:
73 final = len(input_hist)
73 final = len(input_hist)
74 init = max(1,final-int(args[0]))
74 init = max(1,final-int(args[0]))
75 elif len(args) == 2:
75 elif len(args) == 2:
76 init,final = map(int,args)
76 init,final = map(int,args)
77 else:
77 else:
78 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
78 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
79 print self.magic_hist.__doc__
79 print self.magic_hist.__doc__
80 return
80 return
81 width = len(str(final))
81 width = len(str(final))
82 line_sep = ['','\n']
82 line_sep = ['','\n']
83 print_nums = not opts.has_key('n')
83 print_nums = not opts.has_key('n')
84
84
85 found = False
85 found = False
86 if pattern is not None:
86 if pattern is not None:
87 sh = ip.IP.shadowhist.all()
87 sh = ip.IP.shadowhist.all()
88 for idx, s in sh:
88 for idx, s in sh:
89 if fnmatch.fnmatch(s, pattern):
89 if fnmatch.fnmatch(s, pattern):
90 print "0%d: %s" %(idx, s)
90 print "0%d: %s" %(idx, s)
91 found = True
91 found = True
92
92
93 if found:
93 if found:
94 print "==="
94 print "==="
95 print "^shadow history ends, fetch by %rep <number> (must start with 0)"
95 print "^shadow history ends, fetch by %rep <number> (must start with 0)"
96 print "=== start of normal history ==="
96 print "=== start of normal history ==="
97
97
98 for in_num in range(init,final):
98 for in_num in range(init,final):
99 inline = input_hist[in_num]
99 inline = input_hist[in_num]
100 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
100 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
101 continue
101 continue
102
102
103 multiline = int(inline.count('\n') > 1)
103 multiline = int(inline.count('\n') > 1)
104 if print_nums:
104 if print_nums:
105 print '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
105 print '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
106 print inline,
106 print inline,
107
107
108
108
109
109
110 def magic_hist(self, parameter_s=''):
110 def magic_hist(self, parameter_s=''):
111 """Alternate name for %history."""
111 """Alternate name for %history."""
112 return self.magic_history(parameter_s)
112 return self.magic_history(parameter_s)
113
113
114
114
115
115
116 def rep_f(self, arg):
116 def rep_f(self, arg):
117 r""" Repeat a command, or get command to input line for editing
117 r""" Repeat a command, or get command to input line for editing
118
118
119 - %rep (no arguments):
119 - %rep (no arguments):
120
120
121 Place a string version of last input to the next input prompt. Allows you
121 Place a string version of last computation result (stored in the special '_'
122 to create elaborate command lines without using copy-paste::
122 variable) to the next input prompt. Allows you to create elaborate command
123 lines without using copy-paste::
123
124
124 $ l = ["hei", "vaan"]
125 $ l = ["hei", "vaan"]
125 $ "".join(l)
126 $ "".join(l)
126 ==> heivaan
127 ==> heivaan
127 $ %rep
128 $ %rep
128 $ heivaan_ <== cursor blinking
129 $ heivaan_ <== cursor blinking
129
130
130 %rep 45
131 %rep 45
131
132
132 Place history line 45 to next input prompt. Use %hist to find out the number.
133 Place history line 45 to next input prompt. Use %hist to find out the
134 number.
133
135
134 %rep 1-4 6-7 3
136 %rep 1-4 6-7 3
135
137
136 Repeat the specified lines immediately. Input slice syntax is the same as
138 Repeat the specified lines immediately. Input slice syntax is the same as
137 in %macro and %save.
139 in %macro and %save.
138
140
139 %rep foo
141 %rep foo
140
142
141 Place the most recent line that has the substring "foo" to next input.
143 Place the most recent line that has the substring "foo" to next input.
142 (e.g. 'svn ci -m foobar').
144 (e.g. 'svn ci -m foobar').
143
145
144 """
146 """
145
147
146
148
147 opts,args = self.parse_options(arg,'',mode='list')
149 opts,args = self.parse_options(arg,'',mode='list')
148 ip = self.api
150 ip = self.api
149 if not args:
151 if not args:
150 ip.set_next_input(str(ip.user_ns["_"]))
152 ip.set_next_input(str(ip.user_ns["_"]))
151 return
153 return
152
154
153 if len(args) == 1 and not '-' in args[0]:
155 if len(args) == 1 and not '-' in args[0]:
154 arg = args[0]
156 arg = args[0]
155 if len(arg) > 1 and arg.startswith('0'):
157 if len(arg) > 1 and arg.startswith('0'):
156 # get from shadow hist
158 # get from shadow hist
157 num = int(arg[1:])
159 num = int(arg[1:])
158 line = self.shadowhist.get(num)
160 line = self.shadowhist.get(num)
159 ip.set_next_input(str(line))
161 ip.set_next_input(str(line))
160 return
162 return
161 try:
163 try:
162 num = int(args[0])
164 num = int(args[0])
163 ip.set_next_input(str(ip.IP.input_hist_raw[num]).rstrip())
165 ip.set_next_input(str(ip.IP.input_hist_raw[num]).rstrip())
164 return
166 return
165 except ValueError:
167 except ValueError:
166 pass
168 pass
167
169
168 for h in reversed(self.shell.input_hist_raw):
170 for h in reversed(self.shell.input_hist_raw):
169 if 'rep' in h:
171 if 'rep' in h:
170 continue
172 continue
171 if fnmatch.fnmatch(h,'*' + arg + '*'):
173 if fnmatch.fnmatch(h,'*' + arg + '*'):
172 ip.set_next_input(str(h).rstrip())
174 ip.set_next_input(str(h).rstrip())
173 return
175 return
174
176
175
177
176 try:
178 try:
177 lines = self.extract_input_slices(args, True)
179 lines = self.extract_input_slices(args, True)
178 print "lines",lines
180 print "lines",lines
179 ip.runlines(lines)
181 ip.runlines(lines)
180 except ValueError:
182 except ValueError:
181 print "Not found in recent history:", args
183 print "Not found in recent history:", args
182
184
183
185
184
186
185 _sentinel = object()
187 _sentinel = object()
186
188
187 class ShadowHist:
189 class ShadowHist:
188 def __init__(self,db):
190 def __init__(self,db):
189 # cmd => idx mapping
191 # cmd => idx mapping
190 self.curidx = 0
192 self.curidx = 0
191 self.db = db
193 self.db = db
192
194
193 def inc_idx(self):
195 def inc_idx(self):
194 idx = self.db.get('shadowhist_idx', 1)
196 idx = self.db.get('shadowhist_idx', 1)
195 self.db['shadowhist_idx'] = idx + 1
197 self.db['shadowhist_idx'] = idx + 1
196 return idx
198 return idx
197
199
198 def add(self, ent):
200 def add(self, ent):
199 old = self.db.hget('shadowhist', ent, _sentinel)
201 old = self.db.hget('shadowhist', ent, _sentinel)
200 if old is not _sentinel:
202 if old is not _sentinel:
201 return
203 return
202 newidx = self.inc_idx()
204 newidx = self.inc_idx()
203 #print "new",newidx # dbg
205 #print "new",newidx # dbg
204 self.db.hset('shadowhist',ent, newidx)
206 self.db.hset('shadowhist',ent, newidx)
205
207
206 def all(self):
208 def all(self):
207 d = self.db.hdict('shadowhist')
209 d = self.db.hdict('shadowhist')
208 items = [(i,s) for (s,i) in d.items()]
210 items = [(i,s) for (s,i) in d.items()]
209 items.sort()
211 items.sort()
210 return items
212 return items
211
213
212 def get(self, idx):
214 def get(self, idx):
213 all = self.all()
215 all = self.all()
214
216
215 for k, v in all:
217 for k, v in all:
216 #print k,v
218 #print k,v
217 if k == idx:
219 if k == idx:
218 return v
220 return v
219
221
220 def test_shist():
222 def test_shist():
221 from IPython.Extensions import pickleshare
223 from IPython.Extensions import pickleshare
222 db = pickleshare.PickleShareDB('~/shist')
224 db = pickleshare.PickleShareDB('~/shist')
223 s = ShadowHist(db)
225 s = ShadowHist(db)
224 s.add('hello')
226 s.add('hello')
225 s.add('world')
227 s.add('world')
226 s.add('hello')
228 s.add('hello')
227 s.add('hello')
229 s.add('hello')
228 s.add('karhu')
230 s.add('karhu')
229 print "all",s.all()
231 print "all",s.all()
230 print s.get(2)
232 print s.get(2)
231
233
232 def init_ipython(ip):
234 def init_ipython(ip):
233 ip.expose_magic("rep",rep_f)
235 ip.expose_magic("rep",rep_f)
234 ip.expose_magic("hist",magic_hist)
236 ip.expose_magic("hist",magic_hist)
235 ip.expose_magic("history",magic_history)
237 ip.expose_magic("history",magic_history)
236
238
237 import ipy_completers
239 import ipy_completers
238 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
240 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
239 #test_shist()
241 #test_shist()
General Comments 0
You need to be logged in to leave comments. Login now