##// END OF EJS Templates
doc, changelog
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

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