##// END OF EJS Templates
remove obsolete InputList completely
Satrajit Ghosh -
Show More
@@ -1,513 +1,512 b''
1 """ History related magics and functionality """
1 """ History related magics and functionality """
2 #-----------------------------------------------------------------------------
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2010 The IPython Development Team.
3 # Copyright (C) 2010 The IPython Development Team.
4 #
4 #
5 # Distributed under the terms of the BSD License.
5 # Distributed under the terms of the BSD License.
6 #
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 from __future__ import print_function
13 from __future__ import print_function
14
14
15 # Stdlib imports
15 # Stdlib imports
16 import fnmatch
16 import fnmatch
17 import json
17 import json
18 import os
18 import os
19 import sys
19 import sys
20
20
21 # Our own packages
21 # Our own packages
22 import IPython.utils.io
22 import IPython.utils.io
23
23
24 from IPython.core.inputlist import InputList
25 from IPython.utils.pickleshare import PickleShareDB
24 from IPython.utils.pickleshare import PickleShareDB
26 from IPython.utils.io import ask_yes_no
25 from IPython.utils.io import ask_yes_no
27 from IPython.utils.warn import warn
26 from IPython.utils.warn import warn
28
27
29 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
30 # Classes and functions
29 # Classes and functions
31 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
32
31
33 class HistoryManager(object):
32 class HistoryManager(object):
34 """A class to organize all history-related functionality in one place.
33 """A class to organize all history-related functionality in one place.
35 """
34 """
36 # Public interface
35 # Public interface
37
36
38 # An instance of the IPython shell we are attached to
37 # An instance of the IPython shell we are attached to
39 shell = None
38 shell = None
40 # An InputList instance to hold processed history
39 # A list to hold processed history
41 input_hist_parsed = None
40 input_hist_parsed = None
42 # An InputList instance to hold raw history (as typed by user)
41 # A list to hold raw history (as typed by user)
43 input_hist_raw = None
42 input_hist_raw = None
44 # A list of directories visited during session
43 # A list of directories visited during session
45 dir_hist = None
44 dir_hist = None
46 # A dict of output history, keyed with ints from the shell's execution count
45 # A dict of output history, keyed with ints from the shell's execution count
47 output_hist = None
46 output_hist = None
48 # String with path to the history file
47 # String with path to the history file
49 hist_file = None
48 hist_file = None
50 # PickleShareDB instance holding the raw data for the shadow history
49 # PickleShareDB instance holding the raw data for the shadow history
51 shadow_db = None
50 shadow_db = None
52 # ShadowHist instance with the actual shadow history
51 # ShadowHist instance with the actual shadow history
53 shadow_hist = None
52 shadow_hist = None
54
53
55 # Private interface
54 # Private interface
56 # Variables used to store the three last inputs from the user. On each new
55 # Variables used to store the three last inputs from the user. On each new
57 # history update, we populate the user's namespace with these, shifted as
56 # history update, we populate the user's namespace with these, shifted as
58 # necessary.
57 # necessary.
59 _i00, _i, _ii, _iii = '','','',''
58 _i00, _i, _ii, _iii = '','','',''
60
59
61 def __init__(self, shell):
60 def __init__(self, shell):
62 """Create a new history manager associated with a shell instance.
61 """Create a new history manager associated with a shell instance.
63 """
62 """
64 # We need a pointer back to the shell for various tasks.
63 # We need a pointer back to the shell for various tasks.
65 self.shell = shell
64 self.shell = shell
66
65
67 # List of input with multi-line handling.
66 # List of input with multi-line handling.
68 self.input_hist_parsed = []
67 self.input_hist_parsed = []
69 # This one will hold the 'raw' input history, without any
68 # This one will hold the 'raw' input history, without any
70 # pre-processing. This will allow users to retrieve the input just as
69 # pre-processing. This will allow users to retrieve the input just as
71 # it was exactly typed in by the user, with %hist -r.
70 # it was exactly typed in by the user, with %hist -r.
72 self.input_hist_raw = []
71 self.input_hist_raw = []
73
72
74 # list of visited directories
73 # list of visited directories
75 try:
74 try:
76 self.dir_hist = [os.getcwd()]
75 self.dir_hist = [os.getcwd()]
77 except OSError:
76 except OSError:
78 self.dir_hist = []
77 self.dir_hist = []
79
78
80 # dict of output history
79 # dict of output history
81 self.output_hist = {}
80 self.output_hist = {}
82
81
83 # Now the history file
82 # Now the history file
84 if shell.profile:
83 if shell.profile:
85 histfname = 'history-%s' % shell.profile
84 histfname = 'history-%s' % shell.profile
86 else:
85 else:
87 histfname = 'history'
86 histfname = 'history'
88 self.hist_file = os.path.join(shell.ipython_dir, histfname + '.json')
87 self.hist_file = os.path.join(shell.ipython_dir, histfname + '.json')
89
88
90 # Objects related to shadow history management
89 # Objects related to shadow history management
91 self._init_shadow_hist()
90 self._init_shadow_hist()
92
91
93 self._i00, self._i, self._ii, self._iii = '','','',''
92 self._i00, self._i, self._ii, self._iii = '','','',''
94
93
95 # Object is fully initialized, we can now call methods on it.
94 # Object is fully initialized, we can now call methods on it.
96
95
97 # Fill the history zero entry, user counter starts at 1
96 # Fill the history zero entry, user counter starts at 1
98 self.store_inputs('\n', '\n')
97 self.store_inputs('\n', '\n')
99
98
100 def _init_shadow_hist(self):
99 def _init_shadow_hist(self):
101 try:
100 try:
102 self.shadow_db = PickleShareDB(os.path.join(
101 self.shadow_db = PickleShareDB(os.path.join(
103 self.shell.ipython_dir, 'db'))
102 self.shell.ipython_dir, 'db'))
104 except UnicodeDecodeError:
103 except UnicodeDecodeError:
105 print("Your ipython_dir can't be decoded to unicode!")
104 print("Your ipython_dir can't be decoded to unicode!")
106 print("Please set HOME environment variable to something that")
105 print("Please set HOME environment variable to something that")
107 print(r"only has ASCII characters, e.g. c:\home")
106 print(r"only has ASCII characters, e.g. c:\home")
108 print("Now it is", self.ipython_dir)
107 print("Now it is", self.ipython_dir)
109 sys.exit()
108 sys.exit()
110 self.shadow_hist = ShadowHist(self.shadow_db, self.shell)
109 self.shadow_hist = ShadowHist(self.shadow_db, self.shell)
111
110
112 def populate_readline_history(self):
111 def populate_readline_history(self):
113 """Populate the readline history from the raw history.
112 """Populate the readline history from the raw history.
114
113
115 We only store one copy of the raw history, which is persisted to a json
114 We only store one copy of the raw history, which is persisted to a json
116 file on disk. The readline history is repopulated from the contents of
115 file on disk. The readline history is repopulated from the contents of
117 this file."""
116 this file."""
118
117
119 try:
118 try:
120 self.shell.readline.clear_history()
119 self.shell.readline.clear_history()
121 except AttributeError:
120 except AttributeError:
122 pass
121 pass
123 else:
122 else:
124 for h in self.input_hist_raw:
123 for h in self.input_hist_raw:
125 if not h.isspace():
124 if not h.isspace():
126 for line in h.splitlines():
125 for line in h.splitlines():
127 self.shell.readline.add_history(line)
126 self.shell.readline.add_history(line)
128
127
129 def save_history(self):
128 def save_history(self):
130 """Save input history to a file (via readline library)."""
129 """Save input history to a file (via readline library)."""
131 hist = dict(raw=self.input_hist_raw, #[-self.shell.history_length:],
130 hist = dict(raw=self.input_hist_raw, #[-self.shell.history_length:],
132 parsed=self.input_hist_parsed) #[-self.shell.history_length:])
131 parsed=self.input_hist_parsed) #[-self.shell.history_length:])
133 with open(self.hist_file,'wt') as hfile:
132 with open(self.hist_file,'wt') as hfile:
134 json.dump(hist, hfile,
133 json.dump(hist, hfile,
135 sort_keys=True, indent=4)
134 sort_keys=True, indent=4)
136
135
137 def reload_history(self):
136 def reload_history(self):
138 """Reload the input history from disk file."""
137 """Reload the input history from disk file."""
139
138
140 with open(self.hist_file,'rt') as hfile:
139 with open(self.hist_file,'rt') as hfile:
141 hist = json.load(hfile)
140 hist = json.load(hfile)
142 self.input_hist_parsed = hist['parsed']
141 self.input_hist_parsed = hist['parsed']
143 self.input_hist_raw = hist['raw']
142 self.input_hist_raw = hist['raw']
144 if self.shell.has_readline:
143 if self.shell.has_readline:
145 self.populate_readline_history()
144 self.populate_readline_history()
146
145
147 def get_history(self, index=None, raw=False, output=True):
146 def get_history(self, index=None, raw=False, output=True):
148 """Get the history list.
147 """Get the history list.
149
148
150 Get the input and output history.
149 Get the input and output history.
151
150
152 Parameters
151 Parameters
153 ----------
152 ----------
154 index : n or (n1, n2) or None
153 index : n or (n1, n2) or None
155 If n, then the last entries. If a tuple, then all in
154 If n, then the last entries. If a tuple, then all in
156 range(n1, n2). If None, then all entries. Raises IndexError if
155 range(n1, n2). If None, then all entries. Raises IndexError if
157 the format of index is incorrect.
156 the format of index is incorrect.
158 raw : bool
157 raw : bool
159 If True, return the raw input.
158 If True, return the raw input.
160 output : bool
159 output : bool
161 If True, then return the output as well.
160 If True, then return the output as well.
162
161
163 Returns
162 Returns
164 -------
163 -------
165 If output is True, then return a dict of tuples, keyed by the prompt
164 If output is True, then return a dict of tuples, keyed by the prompt
166 numbers and with values of (input, output). If output is False, then
165 numbers and with values of (input, output). If output is False, then
167 a dict, keyed by the prompt number with the values of input. Raises
166 a dict, keyed by the prompt number with the values of input. Raises
168 IndexError if no history is found.
167 IndexError if no history is found.
169 """
168 """
170 if raw:
169 if raw:
171 input_hist = self.input_hist_raw
170 input_hist = self.input_hist_raw
172 else:
171 else:
173 input_hist = self.input_hist_parsed
172 input_hist = self.input_hist_parsed
174 if output:
173 if output:
175 output_hist = self.output_hist
174 output_hist = self.output_hist
176 n = len(input_hist)
175 n = len(input_hist)
177 if index is None:
176 if index is None:
178 start=0; stop=n
177 start=0; stop=n
179 elif isinstance(index, int):
178 elif isinstance(index, int):
180 start=n-index; stop=n
179 start=n-index; stop=n
181 elif isinstance(index, tuple) and len(index) == 2:
180 elif isinstance(index, tuple) and len(index) == 2:
182 start=index[0]; stop=index[1]
181 start=index[0]; stop=index[1]
183 else:
182 else:
184 raise IndexError('Not a valid index for the input history: %r'
183 raise IndexError('Not a valid index for the input history: %r'
185 % index)
184 % index)
186 hist = {}
185 hist = {}
187 for i in range(start, stop):
186 for i in range(start, stop):
188 if output:
187 if output:
189 hist[i] = (input_hist[i], output_hist.get(i))
188 hist[i] = (input_hist[i], output_hist.get(i))
190 else:
189 else:
191 hist[i] = input_hist[i]
190 hist[i] = input_hist[i]
192 if not hist:
191 if not hist:
193 raise IndexError('No history for range of indices: %r' % index)
192 raise IndexError('No history for range of indices: %r' % index)
194 return hist
193 return hist
195
194
196 def store_inputs(self, source, source_raw=None):
195 def store_inputs(self, source, source_raw=None):
197 """Store source and raw input in history and create input cache
196 """Store source and raw input in history and create input cache
198 variables _i*.
197 variables _i*.
199
198
200 Parameters
199 Parameters
201 ----------
200 ----------
202 source : str
201 source : str
203 Python input.
202 Python input.
204
203
205 source_raw : str, optional
204 source_raw : str, optional
206 If given, this is the raw input without any IPython transformations
205 If given, this is the raw input without any IPython transformations
207 applied to it. If not given, ``source`` is used.
206 applied to it. If not given, ``source`` is used.
208 """
207 """
209 if source_raw is None:
208 if source_raw is None:
210 source_raw = source
209 source_raw = source
211 self.input_hist_parsed.append(source)
210 self.input_hist_parsed.append(source)
212 self.input_hist_raw.append(source_raw)
211 self.input_hist_raw.append(source_raw)
213 self.shadow_hist.add(source)
212 self.shadow_hist.add(source)
214
213
215 # update the auto _i variables
214 # update the auto _i variables
216 self._iii = self._ii
215 self._iii = self._ii
217 self._ii = self._i
216 self._ii = self._i
218 self._i = self._i00
217 self._i = self._i00
219 self._i00 = source_raw
218 self._i00 = source_raw
220
219
221 # hackish access to user namespace to create _i1,_i2... dynamically
220 # hackish access to user namespace to create _i1,_i2... dynamically
222 new_i = '_i%s' % self.shell.execution_count
221 new_i = '_i%s' % self.shell.execution_count
223 to_main = {'_i': self._i,
222 to_main = {'_i': self._i,
224 '_ii': self._ii,
223 '_ii': self._ii,
225 '_iii': self._iii,
224 '_iii': self._iii,
226 new_i : self._i00 }
225 new_i : self._i00 }
227 self.shell.user_ns.update(to_main)
226 self.shell.user_ns.update(to_main)
228
227
229 def sync_inputs(self):
228 def sync_inputs(self):
230 """Ensure raw and translated histories have same length."""
229 """Ensure raw and translated histories have same length."""
231 if len(self.input_hist_parsed) != len (self.input_hist_raw):
230 if len(self.input_hist_parsed) != len (self.input_hist_raw):
232 self.input_hist_raw = InputList(self.input_hist_parsed)
231 self.input_hist_raw[:] = self.input_hist_parsed
233
232
234 def reset(self):
233 def reset(self):
235 """Clear all histories managed by this object."""
234 """Clear all histories managed by this object."""
236 self.input_hist_parsed[:] = []
235 self.input_hist_parsed[:] = []
237 self.input_hist_raw[:] = []
236 self.input_hist_raw[:] = []
238 self.output_hist.clear()
237 self.output_hist.clear()
239 # The directory history can't be completely empty
238 # The directory history can't be completely empty
240 self.dir_hist[:] = [os.getcwd()]
239 self.dir_hist[:] = [os.getcwd()]
241
240
242
241
243 def magic_history(self, parameter_s = ''):
242 def magic_history(self, parameter_s = ''):
244 """Print input history (_i<n> variables), with most recent last.
243 """Print input history (_i<n> variables), with most recent last.
245
244
246 %history -> print at most 40 inputs (some may be multi-line)\\
245 %history -> print at most 40 inputs (some may be multi-line)\\
247 %history n -> print at most n inputs\\
246 %history n -> print at most n inputs\\
248 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
247 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
249
248
250 By default, input history is printed without line numbers so it can be
249 By default, input history is printed without line numbers so it can be
251 directly pasted into an editor.
250 directly pasted into an editor.
252
251
253 With -n, each input's number <n> is shown, and is accessible as the
252 With -n, each input's number <n> is shown, and is accessible as the
254 automatically generated variable _i<n> as well as In[<n>]. Multi-line
253 automatically generated variable _i<n> as well as In[<n>]. Multi-line
255 statements are printed starting at a new line for easy copy/paste.
254 statements are printed starting at a new line for easy copy/paste.
256
255
257 Options:
256 Options:
258
257
259 -n: print line numbers for each input.
258 -n: print line numbers for each input.
260 This feature is only available if numbered prompts are in use.
259 This feature is only available if numbered prompts are in use.
261
260
262 -o: also print outputs for each input.
261 -o: also print outputs for each input.
263
262
264 -p: print classic '>>>' python prompts before each input. This is useful
263 -p: print classic '>>>' python prompts before each input. This is useful
265 for making documentation, and in conjunction with -o, for producing
264 for making documentation, and in conjunction with -o, for producing
266 doctest-ready output.
265 doctest-ready output.
267
266
268 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
267 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
269
268
270 -t: print the 'translated' history, as IPython understands it. IPython
269 -t: print the 'translated' history, as IPython understands it. IPython
271 filters your input and converts it all into valid Python source before
270 filters your input and converts it all into valid Python source before
272 executing it (things like magics or aliases are turned into function
271 executing it (things like magics or aliases are turned into function
273 calls, for example). With this option, you'll see the native history
272 calls, for example). With this option, you'll see the native history
274 instead of the user-entered version: '%cd /' will be seen as
273 instead of the user-entered version: '%cd /' will be seen as
275 'get_ipython().magic("%cd /")' instead of '%cd /'.
274 'get_ipython().magic("%cd /")' instead of '%cd /'.
276
275
277 -g: treat the arg as a pattern to grep for in (full) history.
276 -g: treat the arg as a pattern to grep for in (full) history.
278 This includes the "shadow history" (almost all commands ever written).
277 This includes the "shadow history" (almost all commands ever written).
279 Use '%hist -g' to show full shadow history (may be very long).
278 Use '%hist -g' to show full shadow history (may be very long).
280 In shadow history, every index nuwber starts with 0.
279 In shadow history, every index nuwber starts with 0.
281
280
282 -f FILENAME: instead of printing the output to the screen, redirect it to
281 -f FILENAME: instead of printing the output to the screen, redirect it to
283 the given file. The file is always overwritten, though IPython asks for
282 the given file. The file is always overwritten, though IPython asks for
284 confirmation first if it already exists.
283 confirmation first if it already exists.
285 """
284 """
286
285
287 if not self.shell.displayhook.do_full_cache:
286 if not self.shell.displayhook.do_full_cache:
288 print('This feature is only available if numbered prompts are in use.')
287 print('This feature is only available if numbered prompts are in use.')
289 return
288 return
290 opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list')
289 opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list')
291
290
292 # Check if output to specific file was requested.
291 # Check if output to specific file was requested.
293 try:
292 try:
294 outfname = opts['f']
293 outfname = opts['f']
295 except KeyError:
294 except KeyError:
296 outfile = IPython.utils.io.Term.cout # default
295 outfile = IPython.utils.io.Term.cout # default
297 # We don't want to close stdout at the end!
296 # We don't want to close stdout at the end!
298 close_at_end = False
297 close_at_end = False
299 else:
298 else:
300 if os.path.exists(outfname):
299 if os.path.exists(outfname):
301 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
300 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
302 print('Aborting.')
301 print('Aborting.')
303 return
302 return
304
303
305 outfile = open(outfname,'w')
304 outfile = open(outfname,'w')
306 close_at_end = True
305 close_at_end = True
307
306
308 if 't' in opts:
307 if 't' in opts:
309 input_hist = self.shell.history_manager.input_hist_parsed
308 input_hist = self.shell.history_manager.input_hist_parsed
310 elif 'r' in opts:
309 elif 'r' in opts:
311 input_hist = self.shell.history_manager.input_hist_raw
310 input_hist = self.shell.history_manager.input_hist_raw
312 else:
311 else:
313 # Raw history is the default
312 # Raw history is the default
314 input_hist = self.shell.history_manager.input_hist_raw
313 input_hist = self.shell.history_manager.input_hist_raw
315
314
316 default_length = 40
315 default_length = 40
317 pattern = None
316 pattern = None
318 if 'g' in opts:
317 if 'g' in opts:
319 init = 1
318 init = 1
320 final = len(input_hist)
319 final = len(input_hist)
321 parts = parameter_s.split(None, 1)
320 parts = parameter_s.split(None, 1)
322 if len(parts) == 1:
321 if len(parts) == 1:
323 parts += '*'
322 parts += '*'
324 head, pattern = parts
323 head, pattern = parts
325 pattern = "*" + pattern + "*"
324 pattern = "*" + pattern + "*"
326 elif len(args) == 0:
325 elif len(args) == 0:
327 final = len(input_hist)-1
326 final = len(input_hist)-1
328 init = max(1,final-default_length)
327 init = max(1,final-default_length)
329 elif len(args) == 1:
328 elif len(args) == 1:
330 final = len(input_hist)
329 final = len(input_hist)
331 init = max(1, final-int(args[0]))
330 init = max(1, final-int(args[0]))
332 elif len(args) == 2:
331 elif len(args) == 2:
333 init, final = map(int, args)
332 init, final = map(int, args)
334 else:
333 else:
335 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
334 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
336 print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout)
335 print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout)
337 return
336 return
338
337
339 width = len(str(final))
338 width = len(str(final))
340 line_sep = ['','\n']
339 line_sep = ['','\n']
341 print_nums = 'n' in opts
340 print_nums = 'n' in opts
342 print_outputs = 'o' in opts
341 print_outputs = 'o' in opts
343 pyprompts = 'p' in opts
342 pyprompts = 'p' in opts
344
343
345 found = False
344 found = False
346 if pattern is not None:
345 if pattern is not None:
347 sh = self.shell.history_manager.shadowhist.all()
346 sh = self.shell.history_manager.shadowhist.all()
348 for idx, s in sh:
347 for idx, s in sh:
349 if fnmatch.fnmatch(s, pattern):
348 if fnmatch.fnmatch(s, pattern):
350 print("0%d: %s" %(idx, s.expandtabs(4)), file=outfile)
349 print("0%d: %s" %(idx, s.expandtabs(4)), file=outfile)
351 found = True
350 found = True
352
351
353 if found:
352 if found:
354 print("===", file=outfile)
353 print("===", file=outfile)
355 print("shadow history ends, fetch by %rep <number> (must start with 0)",
354 print("shadow history ends, fetch by %rep <number> (must start with 0)",
356 file=outfile)
355 file=outfile)
357 print("=== start of normal history ===", file=outfile)
356 print("=== start of normal history ===", file=outfile)
358
357
359 for in_num in range(init, final):
358 for in_num in range(init, final):
360 # Print user history with tabs expanded to 4 spaces. The GUI clients
359 # Print user history with tabs expanded to 4 spaces. The GUI clients
361 # use hard tabs for easier usability in auto-indented code, but we want
360 # use hard tabs for easier usability in auto-indented code, but we want
362 # to produce PEP-8 compliant history for safe pasting into an editor.
361 # to produce PEP-8 compliant history for safe pasting into an editor.
363 inline = input_hist[in_num].expandtabs(4)
362 inline = input_hist[in_num].expandtabs(4)
364
363
365 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
364 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
366 continue
365 continue
367
366
368 multiline = int(inline.count('\n') > 1)
367 multiline = int(inline.count('\n') > 1)
369 if print_nums:
368 if print_nums:
370 print('%s:%s' % (str(in_num).ljust(width), line_sep[multiline]),
369 print('%s:%s' % (str(in_num).ljust(width), line_sep[multiline]),
371 file=outfile)
370 file=outfile)
372 if pyprompts:
371 if pyprompts:
373 print('>>>', file=outfile)
372 print('>>>', file=outfile)
374 if multiline:
373 if multiline:
375 lines = inline.splitlines()
374 lines = inline.splitlines()
376 print('\n... '.join(lines), file=outfile)
375 print('\n... '.join(lines), file=outfile)
377 print('... ', file=outfile)
376 print('... ', file=outfile)
378 else:
377 else:
379 print(inline, end='', file=outfile)
378 print(inline, end='', file=outfile)
380 else:
379 else:
381 print(inline, end='', file=outfile)
380 print(inline, end='', file=outfile)
382 if print_outputs:
381 if print_outputs:
383 output = self.shell.history_manager.output_hist.get(in_num)
382 output = self.shell.history_manager.output_hist.get(in_num)
384 if output is not None:
383 if output is not None:
385 print(repr(output), file=outfile)
384 print(repr(output), file=outfile)
386
385
387 if close_at_end:
386 if close_at_end:
388 outfile.close()
387 outfile.close()
389
388
390
389
391 def magic_hist(self, parameter_s=''):
390 def magic_hist(self, parameter_s=''):
392 """Alternate name for %history."""
391 """Alternate name for %history."""
393 return self.magic_history(parameter_s)
392 return self.magic_history(parameter_s)
394
393
395
394
396 def rep_f(self, arg):
395 def rep_f(self, arg):
397 r""" Repeat a command, or get command to input line for editing
396 r""" Repeat a command, or get command to input line for editing
398
397
399 - %rep (no arguments):
398 - %rep (no arguments):
400
399
401 Place a string version of last computation result (stored in the special '_'
400 Place a string version of last computation result (stored in the special '_'
402 variable) to the next input prompt. Allows you to create elaborate command
401 variable) to the next input prompt. Allows you to create elaborate command
403 lines without using copy-paste::
402 lines without using copy-paste::
404
403
405 $ l = ["hei", "vaan"]
404 $ l = ["hei", "vaan"]
406 $ "".join(l)
405 $ "".join(l)
407 ==> heivaan
406 ==> heivaan
408 $ %rep
407 $ %rep
409 $ heivaan_ <== cursor blinking
408 $ heivaan_ <== cursor blinking
410
409
411 %rep 45
410 %rep 45
412
411
413 Place history line 45 to next input prompt. Use %hist to find out the
412 Place history line 45 to next input prompt. Use %hist to find out the
414 number.
413 number.
415
414
416 %rep 1-4 6-7 3
415 %rep 1-4 6-7 3
417
416
418 Repeat the specified lines immediately. Input slice syntax is the same as
417 Repeat the specified lines immediately. Input slice syntax is the same as
419 in %macro and %save.
418 in %macro and %save.
420
419
421 %rep foo
420 %rep foo
422
421
423 Place the most recent line that has the substring "foo" to next input.
422 Place the most recent line that has the substring "foo" to next input.
424 (e.g. 'svn ci -m foobar').
423 (e.g. 'svn ci -m foobar').
425 """
424 """
426
425
427 opts,args = self.parse_options(arg,'',mode='list')
426 opts,args = self.parse_options(arg,'',mode='list')
428 if not args:
427 if not args:
429 self.set_next_input(str(self.shell.user_ns["_"]))
428 self.set_next_input(str(self.shell.user_ns["_"]))
430 return
429 return
431
430
432 if len(args) == 1 and not '-' in args[0]:
431 if len(args) == 1 and not '-' in args[0]:
433 arg = args[0]
432 arg = args[0]
434 if len(arg) > 1 and arg.startswith('0'):
433 if len(arg) > 1 and arg.startswith('0'):
435 # get from shadow hist
434 # get from shadow hist
436 num = int(arg[1:])
435 num = int(arg[1:])
437 line = self.shell.shadowhist.get(num)
436 line = self.shell.shadowhist.get(num)
438 self.set_next_input(str(line))
437 self.set_next_input(str(line))
439 return
438 return
440 try:
439 try:
441 num = int(args[0])
440 num = int(args[0])
442 self.set_next_input(str(self.shell.input_hist_raw[num]).rstrip())
441 self.set_next_input(str(self.shell.input_hist_raw[num]).rstrip())
443 return
442 return
444 except ValueError:
443 except ValueError:
445 pass
444 pass
446
445
447 for h in reversed(self.shell.input_hist_raw):
446 for h in reversed(self.shell.input_hist_raw):
448 if 'rep' in h:
447 if 'rep' in h:
449 continue
448 continue
450 if fnmatch.fnmatch(h,'*' + arg + '*'):
449 if fnmatch.fnmatch(h,'*' + arg + '*'):
451 self.set_next_input(str(h).rstrip())
450 self.set_next_input(str(h).rstrip())
452 return
451 return
453
452
454 try:
453 try:
455 lines = self.extract_input_slices(args, True)
454 lines = self.extract_input_slices(args, True)
456 print("lines", lines)
455 print("lines", lines)
457 self.run_cell(lines)
456 self.run_cell(lines)
458 except ValueError:
457 except ValueError:
459 print("Not found in recent history:", args)
458 print("Not found in recent history:", args)
460
459
461
460
462 _sentinel = object()
461 _sentinel = object()
463
462
464 class ShadowHist(object):
463 class ShadowHist(object):
465 def __init__(self, db, shell):
464 def __init__(self, db, shell):
466 # cmd => idx mapping
465 # cmd => idx mapping
467 self.curidx = 0
466 self.curidx = 0
468 self.db = db
467 self.db = db
469 self.disabled = False
468 self.disabled = False
470 self.shell = shell
469 self.shell = shell
471
470
472 def inc_idx(self):
471 def inc_idx(self):
473 idx = self.db.get('shadowhist_idx', 1)
472 idx = self.db.get('shadowhist_idx', 1)
474 self.db['shadowhist_idx'] = idx + 1
473 self.db['shadowhist_idx'] = idx + 1
475 return idx
474 return idx
476
475
477 def add(self, ent):
476 def add(self, ent):
478 if self.disabled:
477 if self.disabled:
479 return
478 return
480 try:
479 try:
481 old = self.db.hget('shadowhist', ent, _sentinel)
480 old = self.db.hget('shadowhist', ent, _sentinel)
482 if old is not _sentinel:
481 if old is not _sentinel:
483 return
482 return
484 newidx = self.inc_idx()
483 newidx = self.inc_idx()
485 #print("new", newidx) # dbg
484 #print("new", newidx) # dbg
486 self.db.hset('shadowhist',ent, newidx)
485 self.db.hset('shadowhist',ent, newidx)
487 except:
486 except:
488 self.shell.showtraceback()
487 self.shell.showtraceback()
489 print("WARNING: disabling shadow history")
488 print("WARNING: disabling shadow history")
490 self.disabled = True
489 self.disabled = True
491
490
492 def all(self):
491 def all(self):
493 d = self.db.hdict('shadowhist')
492 d = self.db.hdict('shadowhist')
494 items = [(i,s) for (s,i) in d.iteritems()]
493 items = [(i,s) for (s,i) in d.iteritems()]
495 items.sort()
494 items.sort()
496 return items
495 return items
497
496
498 def get(self, idx):
497 def get(self, idx):
499 all = self.all()
498 all = self.all()
500
499
501 for k, v in all:
500 for k, v in all:
502 if k == idx:
501 if k == idx:
503 return v
502 return v
504
503
505
504
506 def init_ipython(ip):
505 def init_ipython(ip):
507 ip.define_magic("rep",rep_f)
506 ip.define_magic("rep",rep_f)
508 ip.define_magic("hist",magic_hist)
507 ip.define_magic("hist",magic_hist)
509 ip.define_magic("history",magic_history)
508 ip.define_magic("history",magic_history)
510
509
511 # XXX - ipy_completers are in quarantine, need to be updated to new apis
510 # XXX - ipy_completers are in quarantine, need to be updated to new apis
512 #import ipy_completers
511 #import ipy_completers
513 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
512 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,615 +1,614 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Subclass of InteractiveShell for terminal based frontends."""
2 """Subclass of InteractiveShell for terminal based frontends."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2010 The IPython Development Team
7 # Copyright (C) 2008-2010 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import __builtin__
17 import __builtin__
18 import bdb
18 import bdb
19 from contextlib import nested
19 from contextlib import nested
20 import os
20 import os
21 import re
21 import re
22 import sys
22 import sys
23
23
24 from IPython.core.error import TryNext
24 from IPython.core.error import TryNext
25 from IPython.core.usage import interactive_usage, default_banner
25 from IPython.core.usage import interactive_usage, default_banner
26 from IPython.core.inputlist import InputList
27 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
26 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
28 from IPython.lib.inputhook import enable_gui
27 from IPython.lib.inputhook import enable_gui
29 from IPython.lib.pylabtools import pylab_activate
28 from IPython.lib.pylabtools import pylab_activate
30 from IPython.utils.terminal import toggle_set_term_title, set_term_title
29 from IPython.utils.terminal import toggle_set_term_title, set_term_title
31 from IPython.utils.process import abbrev_cwd
30 from IPython.utils.process import abbrev_cwd
32 from IPython.utils.warn import warn
31 from IPython.utils.warn import warn
33 from IPython.utils.text import num_ini_spaces
32 from IPython.utils.text import num_ini_spaces
34 from IPython.utils.traitlets import Int, Str, CBool
33 from IPython.utils.traitlets import Int, Str, CBool
35
34
36
35
37 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
38 # Utilities
37 # Utilities
39 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
40
39
41
40
42 def get_default_editor():
41 def get_default_editor():
43 try:
42 try:
44 ed = os.environ['EDITOR']
43 ed = os.environ['EDITOR']
45 except KeyError:
44 except KeyError:
46 if os.name == 'posix':
45 if os.name == 'posix':
47 ed = 'vi' # the only one guaranteed to be there!
46 ed = 'vi' # the only one guaranteed to be there!
48 else:
47 else:
49 ed = 'notepad' # same in Windows!
48 ed = 'notepad' # same in Windows!
50 return ed
49 return ed
51
50
52
51
53 # store the builtin raw_input globally, and use this always, in case user code
52 # store the builtin raw_input globally, and use this always, in case user code
54 # overwrites it (like wx.py.PyShell does)
53 # overwrites it (like wx.py.PyShell does)
55 raw_input_original = raw_input
54 raw_input_original = raw_input
56
55
57
56
58 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
59 # Main class
58 # Main class
60 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
61
60
62
61
63 class TerminalInteractiveShell(InteractiveShell):
62 class TerminalInteractiveShell(InteractiveShell):
64
63
65 autoedit_syntax = CBool(False, config=True)
64 autoedit_syntax = CBool(False, config=True)
66 banner = Str('')
65 banner = Str('')
67 banner1 = Str(default_banner, config=True)
66 banner1 = Str(default_banner, config=True)
68 banner2 = Str('', config=True)
67 banner2 = Str('', config=True)
69 confirm_exit = CBool(True, config=True)
68 confirm_exit = CBool(True, config=True)
70 # This display_banner only controls whether or not self.show_banner()
69 # This display_banner only controls whether or not self.show_banner()
71 # is called when mainloop/interact are called. The default is False
70 # is called when mainloop/interact are called. The default is False
72 # because for the terminal based application, the banner behavior
71 # because for the terminal based application, the banner behavior
73 # is controlled by Global.display_banner, which IPythonApp looks at
72 # is controlled by Global.display_banner, which IPythonApp looks at
74 # to determine if *it* should call show_banner() by hand or not.
73 # to determine if *it* should call show_banner() by hand or not.
75 display_banner = CBool(False) # This isn't configurable!
74 display_banner = CBool(False) # This isn't configurable!
76 embedded = CBool(False)
75 embedded = CBool(False)
77 embedded_active = CBool(False)
76 embedded_active = CBool(False)
78 editor = Str(get_default_editor(), config=True)
77 editor = Str(get_default_editor(), config=True)
79 pager = Str('less', config=True)
78 pager = Str('less', config=True)
80
79
81 screen_length = Int(0, config=True)
80 screen_length = Int(0, config=True)
82 term_title = CBool(False, config=True)
81 term_title = CBool(False, config=True)
83
82
84 def __init__(self, config=None, ipython_dir=None, user_ns=None,
83 def __init__(self, config=None, ipython_dir=None, user_ns=None,
85 user_global_ns=None, custom_exceptions=((),None),
84 user_global_ns=None, custom_exceptions=((),None),
86 usage=None, banner1=None, banner2=None,
85 usage=None, banner1=None, banner2=None,
87 display_banner=None):
86 display_banner=None):
88
87
89 super(TerminalInteractiveShell, self).__init__(
88 super(TerminalInteractiveShell, self).__init__(
90 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
89 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
91 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
90 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
92 )
91 )
93 self.init_term_title()
92 self.init_term_title()
94 self.init_usage(usage)
93 self.init_usage(usage)
95 self.init_banner(banner1, banner2, display_banner)
94 self.init_banner(banner1, banner2, display_banner)
96
95
97 #-------------------------------------------------------------------------
96 #-------------------------------------------------------------------------
98 # Things related to the terminal
97 # Things related to the terminal
99 #-------------------------------------------------------------------------
98 #-------------------------------------------------------------------------
100
99
101 @property
100 @property
102 def usable_screen_length(self):
101 def usable_screen_length(self):
103 if self.screen_length == 0:
102 if self.screen_length == 0:
104 return 0
103 return 0
105 else:
104 else:
106 num_lines_bot = self.separate_in.count('\n')+1
105 num_lines_bot = self.separate_in.count('\n')+1
107 return self.screen_length - num_lines_bot
106 return self.screen_length - num_lines_bot
108
107
109 def init_term_title(self):
108 def init_term_title(self):
110 # Enable or disable the terminal title.
109 # Enable or disable the terminal title.
111 if self.term_title:
110 if self.term_title:
112 toggle_set_term_title(True)
111 toggle_set_term_title(True)
113 set_term_title('IPython: ' + abbrev_cwd())
112 set_term_title('IPython: ' + abbrev_cwd())
114 else:
113 else:
115 toggle_set_term_title(False)
114 toggle_set_term_title(False)
116
115
117 #-------------------------------------------------------------------------
116 #-------------------------------------------------------------------------
118 # Things related to aliases
117 # Things related to aliases
119 #-------------------------------------------------------------------------
118 #-------------------------------------------------------------------------
120
119
121 def init_alias(self):
120 def init_alias(self):
122 # The parent class defines aliases that can be safely used with any
121 # The parent class defines aliases that can be safely used with any
123 # frontend.
122 # frontend.
124 super(TerminalInteractiveShell, self).init_alias()
123 super(TerminalInteractiveShell, self).init_alias()
125
124
126 # Now define aliases that only make sense on the terminal, because they
125 # Now define aliases that only make sense on the terminal, because they
127 # need direct access to the console in a way that we can't emulate in
126 # need direct access to the console in a way that we can't emulate in
128 # GUI or web frontend
127 # GUI or web frontend
129 if os.name == 'posix':
128 if os.name == 'posix':
130 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
129 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
131 ('man', 'man')]
130 ('man', 'man')]
132 elif os.name == 'nt':
131 elif os.name == 'nt':
133 aliases = [('cls', 'cls')]
132 aliases = [('cls', 'cls')]
134
133
135
134
136 for name, cmd in aliases:
135 for name, cmd in aliases:
137 self.alias_manager.define_alias(name, cmd)
136 self.alias_manager.define_alias(name, cmd)
138
137
139 #-------------------------------------------------------------------------
138 #-------------------------------------------------------------------------
140 # Things related to the banner and usage
139 # Things related to the banner and usage
141 #-------------------------------------------------------------------------
140 #-------------------------------------------------------------------------
142
141
143 def _banner1_changed(self):
142 def _banner1_changed(self):
144 self.compute_banner()
143 self.compute_banner()
145
144
146 def _banner2_changed(self):
145 def _banner2_changed(self):
147 self.compute_banner()
146 self.compute_banner()
148
147
149 def _term_title_changed(self, name, new_value):
148 def _term_title_changed(self, name, new_value):
150 self.init_term_title()
149 self.init_term_title()
151
150
152 def init_banner(self, banner1, banner2, display_banner):
151 def init_banner(self, banner1, banner2, display_banner):
153 if banner1 is not None:
152 if banner1 is not None:
154 self.banner1 = banner1
153 self.banner1 = banner1
155 if banner2 is not None:
154 if banner2 is not None:
156 self.banner2 = banner2
155 self.banner2 = banner2
157 if display_banner is not None:
156 if display_banner is not None:
158 self.display_banner = display_banner
157 self.display_banner = display_banner
159 self.compute_banner()
158 self.compute_banner()
160
159
161 def show_banner(self, banner=None):
160 def show_banner(self, banner=None):
162 if banner is None:
161 if banner is None:
163 banner = self.banner
162 banner = self.banner
164 self.write(banner)
163 self.write(banner)
165
164
166 def compute_banner(self):
165 def compute_banner(self):
167 self.banner = self.banner1
166 self.banner = self.banner1
168 if self.profile:
167 if self.profile:
169 self.banner += '\nIPython profile: %s\n' % self.profile
168 self.banner += '\nIPython profile: %s\n' % self.profile
170 if self.banner2:
169 if self.banner2:
171 self.banner += '\n' + self.banner2
170 self.banner += '\n' + self.banner2
172
171
173 def init_usage(self, usage=None):
172 def init_usage(self, usage=None):
174 if usage is None:
173 if usage is None:
175 self.usage = interactive_usage
174 self.usage = interactive_usage
176 else:
175 else:
177 self.usage = usage
176 self.usage = usage
178
177
179 #-------------------------------------------------------------------------
178 #-------------------------------------------------------------------------
180 # Mainloop and code execution logic
179 # Mainloop and code execution logic
181 #-------------------------------------------------------------------------
180 #-------------------------------------------------------------------------
182
181
183 def mainloop(self, display_banner=None):
182 def mainloop(self, display_banner=None):
184 """Start the mainloop.
183 """Start the mainloop.
185
184
186 If an optional banner argument is given, it will override the
185 If an optional banner argument is given, it will override the
187 internally created default banner.
186 internally created default banner.
188 """
187 """
189
188
190 with nested(self.builtin_trap, self.display_trap):
189 with nested(self.builtin_trap, self.display_trap):
191
190
192 # if you run stuff with -c <cmd>, raw hist is not updated
191 # if you run stuff with -c <cmd>, raw hist is not updated
193 # ensure that it's in sync
192 # ensure that it's in sync
194 self.history_manager.sync_inputs()
193 self.history_manager.sync_inputs()
195
194
196 while 1:
195 while 1:
197 try:
196 try:
198 self.interact(display_banner=display_banner)
197 self.interact(display_banner=display_banner)
199 #self.interact_with_readline()
198 #self.interact_with_readline()
200 # XXX for testing of a readline-decoupled repl loop, call
199 # XXX for testing of a readline-decoupled repl loop, call
201 # interact_with_readline above
200 # interact_with_readline above
202 break
201 break
203 except KeyboardInterrupt:
202 except KeyboardInterrupt:
204 # this should not be necessary, but KeyboardInterrupt
203 # this should not be necessary, but KeyboardInterrupt
205 # handling seems rather unpredictable...
204 # handling seems rather unpredictable...
206 self.write("\nKeyboardInterrupt in interact()\n")
205 self.write("\nKeyboardInterrupt in interact()\n")
207
206
208 def interact(self, display_banner=None):
207 def interact(self, display_banner=None):
209 """Closely emulate the interactive Python console."""
208 """Closely emulate the interactive Python console."""
210
209
211 # batch run -> do not interact
210 # batch run -> do not interact
212 if self.exit_now:
211 if self.exit_now:
213 return
212 return
214
213
215 if display_banner is None:
214 if display_banner is None:
216 display_banner = self.display_banner
215 display_banner = self.display_banner
217 if display_banner:
216 if display_banner:
218 self.show_banner()
217 self.show_banner()
219
218
220 more = False
219 more = False
221
220
222 # Mark activity in the builtins
221 # Mark activity in the builtins
223 __builtin__.__dict__['__IPYTHON__active'] += 1
222 __builtin__.__dict__['__IPYTHON__active'] += 1
224
223
225 if self.has_readline:
224 if self.has_readline:
226 self.readline_startup_hook(self.pre_readline)
225 self.readline_startup_hook(self.pre_readline)
227 # exit_now is set by a call to %Exit or %Quit, through the
226 # exit_now is set by a call to %Exit or %Quit, through the
228 # ask_exit callback.
227 # ask_exit callback.
229
228
230 while not self.exit_now:
229 while not self.exit_now:
231 self.hooks.pre_prompt_hook()
230 self.hooks.pre_prompt_hook()
232 if more:
231 if more:
233 try:
232 try:
234 prompt = self.hooks.generate_prompt(True)
233 prompt = self.hooks.generate_prompt(True)
235 except:
234 except:
236 self.showtraceback()
235 self.showtraceback()
237 if self.autoindent:
236 if self.autoindent:
238 self.rl_do_indent = True
237 self.rl_do_indent = True
239
238
240 else:
239 else:
241 try:
240 try:
242 prompt = self.hooks.generate_prompt(False)
241 prompt = self.hooks.generate_prompt(False)
243 except:
242 except:
244 self.showtraceback()
243 self.showtraceback()
245 try:
244 try:
246 line = self.raw_input(prompt)
245 line = self.raw_input(prompt)
247 if self.exit_now:
246 if self.exit_now:
248 # quick exit on sys.std[in|out] close
247 # quick exit on sys.std[in|out] close
249 break
248 break
250 if self.autoindent:
249 if self.autoindent:
251 self.rl_do_indent = False
250 self.rl_do_indent = False
252
251
253 except KeyboardInterrupt:
252 except KeyboardInterrupt:
254 #double-guard against keyboardinterrupts during kbdint handling
253 #double-guard against keyboardinterrupts during kbdint handling
255 try:
254 try:
256 self.write('\nKeyboardInterrupt\n')
255 self.write('\nKeyboardInterrupt\n')
257 self.resetbuffer()
256 self.resetbuffer()
258 more = False
257 more = False
259 except KeyboardInterrupt:
258 except KeyboardInterrupt:
260 pass
259 pass
261 except EOFError:
260 except EOFError:
262 if self.autoindent:
261 if self.autoindent:
263 self.rl_do_indent = False
262 self.rl_do_indent = False
264 if self.has_readline:
263 if self.has_readline:
265 self.readline_startup_hook(None)
264 self.readline_startup_hook(None)
266 self.write('\n')
265 self.write('\n')
267 self.exit()
266 self.exit()
268 except bdb.BdbQuit:
267 except bdb.BdbQuit:
269 warn('The Python debugger has exited with a BdbQuit exception.\n'
268 warn('The Python debugger has exited with a BdbQuit exception.\n'
270 'Because of how pdb handles the stack, it is impossible\n'
269 'Because of how pdb handles the stack, it is impossible\n'
271 'for IPython to properly format this particular exception.\n'
270 'for IPython to properly format this particular exception.\n'
272 'IPython will resume normal operation.')
271 'IPython will resume normal operation.')
273 except:
272 except:
274 # exceptions here are VERY RARE, but they can be triggered
273 # exceptions here are VERY RARE, but they can be triggered
275 # asynchronously by signal handlers, for example.
274 # asynchronously by signal handlers, for example.
276 self.showtraceback()
275 self.showtraceback()
277 else:
276 else:
278 self.input_splitter.push(line)
277 self.input_splitter.push(line)
279 more = self.input_splitter.push_accepts_more()
278 more = self.input_splitter.push_accepts_more()
280 if (self.SyntaxTB.last_syntax_error and
279 if (self.SyntaxTB.last_syntax_error and
281 self.autoedit_syntax):
280 self.autoedit_syntax):
282 self.edit_syntax_error()
281 self.edit_syntax_error()
283 if not more:
282 if not more:
284 source_raw = self.input_splitter.source_raw_reset()[1]
283 source_raw = self.input_splitter.source_raw_reset()[1]
285 self.run_cell(source_raw)
284 self.run_cell(source_raw)
286
285
287 # We are off again...
286 # We are off again...
288 __builtin__.__dict__['__IPYTHON__active'] -= 1
287 __builtin__.__dict__['__IPYTHON__active'] -= 1
289
288
290 # Turn off the exit flag, so the mainloop can be restarted if desired
289 # Turn off the exit flag, so the mainloop can be restarted if desired
291 self.exit_now = False
290 self.exit_now = False
292
291
293 def raw_input(self, prompt='', continue_prompt=False):
292 def raw_input(self, prompt='', continue_prompt=False):
294 """Write a prompt and read a line.
293 """Write a prompt and read a line.
295
294
296 The returned line does not include the trailing newline.
295 The returned line does not include the trailing newline.
297 When the user enters the EOF key sequence, EOFError is raised.
296 When the user enters the EOF key sequence, EOFError is raised.
298
297
299 Optional inputs:
298 Optional inputs:
300
299
301 - prompt(''): a string to be printed to prompt the user.
300 - prompt(''): a string to be printed to prompt the user.
302
301
303 - continue_prompt(False): whether this line is the first one or a
302 - continue_prompt(False): whether this line is the first one or a
304 continuation in a sequence of inputs.
303 continuation in a sequence of inputs.
305 """
304 """
306 # Code run by the user may have modified the readline completer state.
305 # Code run by the user may have modified the readline completer state.
307 # We must ensure that our completer is back in place.
306 # We must ensure that our completer is back in place.
308
307
309 if self.has_readline:
308 if self.has_readline:
310 self.set_readline_completer()
309 self.set_readline_completer()
311
310
312 try:
311 try:
313 line = raw_input_original(prompt).decode(self.stdin_encoding)
312 line = raw_input_original(prompt).decode(self.stdin_encoding)
314 except ValueError:
313 except ValueError:
315 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
314 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
316 " or sys.stdout.close()!\nExiting IPython!")
315 " or sys.stdout.close()!\nExiting IPython!")
317 self.ask_exit()
316 self.ask_exit()
318 return ""
317 return ""
319
318
320 # Try to be reasonably smart about not re-indenting pasted input more
319 # Try to be reasonably smart about not re-indenting pasted input more
321 # than necessary. We do this by trimming out the auto-indent initial
320 # than necessary. We do this by trimming out the auto-indent initial
322 # spaces, if the user's actual input started itself with whitespace.
321 # spaces, if the user's actual input started itself with whitespace.
323 if self.autoindent:
322 if self.autoindent:
324 if num_ini_spaces(line) > self.indent_current_nsp:
323 if num_ini_spaces(line) > self.indent_current_nsp:
325 line = line[self.indent_current_nsp:]
324 line = line[self.indent_current_nsp:]
326 self.indent_current_nsp = 0
325 self.indent_current_nsp = 0
327
326
328 # store the unfiltered input before the user has any chance to modify
327 # store the unfiltered input before the user has any chance to modify
329 # it.
328 # it.
330 if line.strip():
329 if line.strip():
331 if continue_prompt:
330 if continue_prompt:
332 if self.has_readline and self.readline_use:
331 if self.has_readline and self.readline_use:
333 histlen = self.readline.get_current_history_length()
332 histlen = self.readline.get_current_history_length()
334 if histlen > 1:
333 if histlen > 1:
335 newhist = self.history_manager.input_hist_raw[-1].rstrip()
334 newhist = self.history_manager.input_hist_raw[-1].rstrip()
336 self.readline.remove_history_item(histlen-1)
335 self.readline.remove_history_item(histlen-1)
337 self.readline.replace_history_item(histlen-2,
336 self.readline.replace_history_item(histlen-2,
338 newhist.encode(self.stdin_encoding))
337 newhist.encode(self.stdin_encoding))
339 else:
338 else:
340 self.history_manager.input_hist_raw.append('%s\n' % line)
339 self.history_manager.input_hist_raw.append('%s\n' % line)
341 elif not continue_prompt:
340 elif not continue_prompt:
342 self.history_manager.input_hist_raw.append('\n')
341 self.history_manager.input_hist_raw.append('\n')
343 try:
342 try:
344 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
343 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
345 except:
344 except:
346 # blanket except, in case a user-defined prefilter crashes, so it
345 # blanket except, in case a user-defined prefilter crashes, so it
347 # can't take all of ipython with it.
346 # can't take all of ipython with it.
348 self.showtraceback()
347 self.showtraceback()
349 return ''
348 return ''
350 else:
349 else:
351 return lineout
350 return lineout
352
351
353
352
354 def raw_input(self, prompt=''):
353 def raw_input(self, prompt=''):
355 """Write a prompt and read a line.
354 """Write a prompt and read a line.
356
355
357 The returned line does not include the trailing newline.
356 The returned line does not include the trailing newline.
358 When the user enters the EOF key sequence, EOFError is raised.
357 When the user enters the EOF key sequence, EOFError is raised.
359
358
360 Optional inputs:
359 Optional inputs:
361
360
362 - prompt(''): a string to be printed to prompt the user.
361 - prompt(''): a string to be printed to prompt the user.
363
362
364 - continue_prompt(False): whether this line is the first one or a
363 - continue_prompt(False): whether this line is the first one or a
365 continuation in a sequence of inputs.
364 continuation in a sequence of inputs.
366 """
365 """
367 # Code run by the user may have modified the readline completer state.
366 # Code run by the user may have modified the readline completer state.
368 # We must ensure that our completer is back in place.
367 # We must ensure that our completer is back in place.
369
368
370 if self.has_readline:
369 if self.has_readline:
371 self.set_readline_completer()
370 self.set_readline_completer()
372
371
373 try:
372 try:
374 line = raw_input_original(prompt).decode(self.stdin_encoding)
373 line = raw_input_original(prompt).decode(self.stdin_encoding)
375 except ValueError:
374 except ValueError:
376 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
375 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
377 " or sys.stdout.close()!\nExiting IPython!")
376 " or sys.stdout.close()!\nExiting IPython!")
378 self.ask_exit()
377 self.ask_exit()
379 return ""
378 return ""
380
379
381 # Try to be reasonably smart about not re-indenting pasted input more
380 # Try to be reasonably smart about not re-indenting pasted input more
382 # than necessary. We do this by trimming out the auto-indent initial
381 # than necessary. We do this by trimming out the auto-indent initial
383 # spaces, if the user's actual input started itself with whitespace.
382 # spaces, if the user's actual input started itself with whitespace.
384 if self.autoindent:
383 if self.autoindent:
385 if num_ini_spaces(line) > self.indent_current_nsp:
384 if num_ini_spaces(line) > self.indent_current_nsp:
386 line = line[self.indent_current_nsp:]
385 line = line[self.indent_current_nsp:]
387 self.indent_current_nsp = 0
386 self.indent_current_nsp = 0
388
387
389 return line
388 return line
390
389
391 #-------------------------------------------------------------------------
390 #-------------------------------------------------------------------------
392 # Methods to support auto-editing of SyntaxErrors.
391 # Methods to support auto-editing of SyntaxErrors.
393 #-------------------------------------------------------------------------
392 #-------------------------------------------------------------------------
394
393
395 def edit_syntax_error(self):
394 def edit_syntax_error(self):
396 """The bottom half of the syntax error handler called in the main loop.
395 """The bottom half of the syntax error handler called in the main loop.
397
396
398 Loop until syntax error is fixed or user cancels.
397 Loop until syntax error is fixed or user cancels.
399 """
398 """
400
399
401 while self.SyntaxTB.last_syntax_error:
400 while self.SyntaxTB.last_syntax_error:
402 # copy and clear last_syntax_error
401 # copy and clear last_syntax_error
403 err = self.SyntaxTB.clear_err_state()
402 err = self.SyntaxTB.clear_err_state()
404 if not self._should_recompile(err):
403 if not self._should_recompile(err):
405 return
404 return
406 try:
405 try:
407 # may set last_syntax_error again if a SyntaxError is raised
406 # may set last_syntax_error again if a SyntaxError is raised
408 self.safe_execfile(err.filename,self.user_ns)
407 self.safe_execfile(err.filename,self.user_ns)
409 except:
408 except:
410 self.showtraceback()
409 self.showtraceback()
411 else:
410 else:
412 try:
411 try:
413 f = file(err.filename)
412 f = file(err.filename)
414 try:
413 try:
415 # This should be inside a display_trap block and I
414 # This should be inside a display_trap block and I
416 # think it is.
415 # think it is.
417 sys.displayhook(f.read())
416 sys.displayhook(f.read())
418 finally:
417 finally:
419 f.close()
418 f.close()
420 except:
419 except:
421 self.showtraceback()
420 self.showtraceback()
422
421
423 def _should_recompile(self,e):
422 def _should_recompile(self,e):
424 """Utility routine for edit_syntax_error"""
423 """Utility routine for edit_syntax_error"""
425
424
426 if e.filename in ('<ipython console>','<input>','<string>',
425 if e.filename in ('<ipython console>','<input>','<string>',
427 '<console>','<BackgroundJob compilation>',
426 '<console>','<BackgroundJob compilation>',
428 None):
427 None):
429
428
430 return False
429 return False
431 try:
430 try:
432 if (self.autoedit_syntax and
431 if (self.autoedit_syntax and
433 not self.ask_yes_no('Return to editor to correct syntax error? '
432 not self.ask_yes_no('Return to editor to correct syntax error? '
434 '[Y/n] ','y')):
433 '[Y/n] ','y')):
435 return False
434 return False
436 except EOFError:
435 except EOFError:
437 return False
436 return False
438
437
439 def int0(x):
438 def int0(x):
440 try:
439 try:
441 return int(x)
440 return int(x)
442 except TypeError:
441 except TypeError:
443 return 0
442 return 0
444 # always pass integer line and offset values to editor hook
443 # always pass integer line and offset values to editor hook
445 try:
444 try:
446 self.hooks.fix_error_editor(e.filename,
445 self.hooks.fix_error_editor(e.filename,
447 int0(e.lineno),int0(e.offset),e.msg)
446 int0(e.lineno),int0(e.offset),e.msg)
448 except TryNext:
447 except TryNext:
449 warn('Could not open editor')
448 warn('Could not open editor')
450 return False
449 return False
451 return True
450 return True
452
451
453 #-------------------------------------------------------------------------
452 #-------------------------------------------------------------------------
454 # Things related to GUI support and pylab
453 # Things related to GUI support and pylab
455 #-------------------------------------------------------------------------
454 #-------------------------------------------------------------------------
456
455
457 def enable_pylab(self, gui=None):
456 def enable_pylab(self, gui=None):
458 """Activate pylab support at runtime.
457 """Activate pylab support at runtime.
459
458
460 This turns on support for matplotlib, preloads into the interactive
459 This turns on support for matplotlib, preloads into the interactive
461 namespace all of numpy and pylab, and configures IPython to correcdtly
460 namespace all of numpy and pylab, and configures IPython to correcdtly
462 interact with the GUI event loop. The GUI backend to be used can be
461 interact with the GUI event loop. The GUI backend to be used can be
463 optionally selected with the optional :param:`gui` argument.
462 optionally selected with the optional :param:`gui` argument.
464
463
465 Parameters
464 Parameters
466 ----------
465 ----------
467 gui : optional, string
466 gui : optional, string
468
467
469 If given, dictates the choice of matplotlib GUI backend to use
468 If given, dictates the choice of matplotlib GUI backend to use
470 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
469 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
471 'gtk'), otherwise we use the default chosen by matplotlib (as
470 'gtk'), otherwise we use the default chosen by matplotlib (as
472 dictated by the matplotlib build-time options plus the user's
471 dictated by the matplotlib build-time options plus the user's
473 matplotlibrc configuration file).
472 matplotlibrc configuration file).
474 """
473 """
475 # We want to prevent the loading of pylab to pollute the user's
474 # We want to prevent the loading of pylab to pollute the user's
476 # namespace as shown by the %who* magics, so we execute the activation
475 # namespace as shown by the %who* magics, so we execute the activation
477 # code in an empty namespace, and we update *both* user_ns and
476 # code in an empty namespace, and we update *both* user_ns and
478 # user_ns_hidden with this information.
477 # user_ns_hidden with this information.
479 ns = {}
478 ns = {}
480 gui = pylab_activate(ns, gui)
479 gui = pylab_activate(ns, gui)
481 self.user_ns.update(ns)
480 self.user_ns.update(ns)
482 self.user_ns_hidden.update(ns)
481 self.user_ns_hidden.update(ns)
483 # Now we must activate the gui pylab wants to use, and fix %run to take
482 # Now we must activate the gui pylab wants to use, and fix %run to take
484 # plot updates into account
483 # plot updates into account
485 enable_gui(gui)
484 enable_gui(gui)
486 self.magic_run = self._pylab_magic_run
485 self.magic_run = self._pylab_magic_run
487
486
488 #-------------------------------------------------------------------------
487 #-------------------------------------------------------------------------
489 # Things related to exiting
488 # Things related to exiting
490 #-------------------------------------------------------------------------
489 #-------------------------------------------------------------------------
491
490
492 def ask_exit(self):
491 def ask_exit(self):
493 """ Ask the shell to exit. Can be overiden and used as a callback. """
492 """ Ask the shell to exit. Can be overiden and used as a callback. """
494 self.exit_now = True
493 self.exit_now = True
495
494
496 def exit(self):
495 def exit(self):
497 """Handle interactive exit.
496 """Handle interactive exit.
498
497
499 This method calls the ask_exit callback."""
498 This method calls the ask_exit callback."""
500 if self.confirm_exit:
499 if self.confirm_exit:
501 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
500 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
502 self.ask_exit()
501 self.ask_exit()
503 else:
502 else:
504 self.ask_exit()
503 self.ask_exit()
505
504
506 #------------------------------------------------------------------------
505 #------------------------------------------------------------------------
507 # Magic overrides
506 # Magic overrides
508 #------------------------------------------------------------------------
507 #------------------------------------------------------------------------
509 # Once the base class stops inheriting from magic, this code needs to be
508 # Once the base class stops inheriting from magic, this code needs to be
510 # moved into a separate machinery as well. For now, at least isolate here
509 # moved into a separate machinery as well. For now, at least isolate here
511 # the magics which this class needs to implement differently from the base
510 # the magics which this class needs to implement differently from the base
512 # class, or that are unique to it.
511 # class, or that are unique to it.
513
512
514 def magic_autoindent(self, parameter_s = ''):
513 def magic_autoindent(self, parameter_s = ''):
515 """Toggle autoindent on/off (if available)."""
514 """Toggle autoindent on/off (if available)."""
516
515
517 self.shell.set_autoindent()
516 self.shell.set_autoindent()
518 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
517 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
519
518
520 def magic_cpaste(self, parameter_s=''):
519 def magic_cpaste(self, parameter_s=''):
521 """Paste & execute a pre-formatted code block from clipboard.
520 """Paste & execute a pre-formatted code block from clipboard.
522
521
523 You must terminate the block with '--' (two minus-signs) alone on the
522 You must terminate the block with '--' (two minus-signs) alone on the
524 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
523 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
525 is the new sentinel for this operation)
524 is the new sentinel for this operation)
526
525
527 The block is dedented prior to execution to enable execution of method
526 The block is dedented prior to execution to enable execution of method
528 definitions. '>' and '+' characters at the beginning of a line are
527 definitions. '>' and '+' characters at the beginning of a line are
529 ignored, to allow pasting directly from e-mails, diff files and
528 ignored, to allow pasting directly from e-mails, diff files and
530 doctests (the '...' continuation prompt is also stripped). The
529 doctests (the '...' continuation prompt is also stripped). The
531 executed block is also assigned to variable named 'pasted_block' for
530 executed block is also assigned to variable named 'pasted_block' for
532 later editing with '%edit pasted_block'.
531 later editing with '%edit pasted_block'.
533
532
534 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
533 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
535 This assigns the pasted block to variable 'foo' as string, without
534 This assigns the pasted block to variable 'foo' as string, without
536 dedenting or executing it (preceding >>> and + is still stripped)
535 dedenting or executing it (preceding >>> and + is still stripped)
537
536
538 '%cpaste -r' re-executes the block previously entered by cpaste.
537 '%cpaste -r' re-executes the block previously entered by cpaste.
539
538
540 Do not be alarmed by garbled output on Windows (it's a readline bug).
539 Do not be alarmed by garbled output on Windows (it's a readline bug).
541 Just press enter and type -- (and press enter again) and the block
540 Just press enter and type -- (and press enter again) and the block
542 will be what was just pasted.
541 will be what was just pasted.
543
542
544 IPython statements (magics, shell escapes) are not supported (yet).
543 IPython statements (magics, shell escapes) are not supported (yet).
545
544
546 See also
545 See also
547 --------
546 --------
548 paste: automatically pull code from clipboard.
547 paste: automatically pull code from clipboard.
549 """
548 """
550
549
551 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
550 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
552 par = args.strip()
551 par = args.strip()
553 if opts.has_key('r'):
552 if opts.has_key('r'):
554 self._rerun_pasted()
553 self._rerun_pasted()
555 return
554 return
556
555
557 sentinel = opts.get('s','--')
556 sentinel = opts.get('s','--')
558
557
559 block = self._strip_pasted_lines_for_code(
558 block = self._strip_pasted_lines_for_code(
560 self._get_pasted_lines(sentinel))
559 self._get_pasted_lines(sentinel))
561
560
562 self._execute_block(block, par)
561 self._execute_block(block, par)
563
562
564 def magic_paste(self, parameter_s=''):
563 def magic_paste(self, parameter_s=''):
565 """Paste & execute a pre-formatted code block from clipboard.
564 """Paste & execute a pre-formatted code block from clipboard.
566
565
567 The text is pulled directly from the clipboard without user
566 The text is pulled directly from the clipboard without user
568 intervention and printed back on the screen before execution (unless
567 intervention and printed back on the screen before execution (unless
569 the -q flag is given to force quiet mode).
568 the -q flag is given to force quiet mode).
570
569
571 The block is dedented prior to execution to enable execution of method
570 The block is dedented prior to execution to enable execution of method
572 definitions. '>' and '+' characters at the beginning of a line are
571 definitions. '>' and '+' characters at the beginning of a line are
573 ignored, to allow pasting directly from e-mails, diff files and
572 ignored, to allow pasting directly from e-mails, diff files and
574 doctests (the '...' continuation prompt is also stripped). The
573 doctests (the '...' continuation prompt is also stripped). The
575 executed block is also assigned to variable named 'pasted_block' for
574 executed block is also assigned to variable named 'pasted_block' for
576 later editing with '%edit pasted_block'.
575 later editing with '%edit pasted_block'.
577
576
578 You can also pass a variable name as an argument, e.g. '%paste foo'.
577 You can also pass a variable name as an argument, e.g. '%paste foo'.
579 This assigns the pasted block to variable 'foo' as string, without
578 This assigns the pasted block to variable 'foo' as string, without
580 dedenting or executing it (preceding >>> and + is still stripped)
579 dedenting or executing it (preceding >>> and + is still stripped)
581
580
582 Options
581 Options
583 -------
582 -------
584
583
585 -r: re-executes the block previously entered by cpaste.
584 -r: re-executes the block previously entered by cpaste.
586
585
587 -q: quiet mode: do not echo the pasted text back to the terminal.
586 -q: quiet mode: do not echo the pasted text back to the terminal.
588
587
589 IPython statements (magics, shell escapes) are not supported (yet).
588 IPython statements (magics, shell escapes) are not supported (yet).
590
589
591 See also
590 See also
592 --------
591 --------
593 cpaste: manually paste code into terminal until you mark its end.
592 cpaste: manually paste code into terminal until you mark its end.
594 """
593 """
595 opts,args = self.parse_options(parameter_s,'rq',mode='string')
594 opts,args = self.parse_options(parameter_s,'rq',mode='string')
596 par = args.strip()
595 par = args.strip()
597 if opts.has_key('r'):
596 if opts.has_key('r'):
598 self._rerun_pasted()
597 self._rerun_pasted()
599 return
598 return
600
599
601 text = self.shell.hooks.clipboard_get()
600 text = self.shell.hooks.clipboard_get()
602 block = self._strip_pasted_lines_for_code(text.splitlines())
601 block = self._strip_pasted_lines_for_code(text.splitlines())
603
602
604 # By default, echo back to terminal unless quiet mode is requested
603 # By default, echo back to terminal unless quiet mode is requested
605 if not opts.has_key('q'):
604 if not opts.has_key('q'):
606 write = self.shell.write
605 write = self.shell.write
607 write(self.shell.pycolorize(block))
606 write(self.shell.pycolorize(block))
608 if not block.endswith('\n'):
607 if not block.endswith('\n'):
609 write('\n')
608 write('\n')
610 write("## -- End pasted text --\n")
609 write("## -- End pasted text --\n")
611
610
612 self._execute_block(block, par)
611 self._execute_block(block, par)
613
612
614
613
615 InteractiveShellABC.register(TerminalInteractiveShell)
614 InteractiveShellABC.register(TerminalInteractiveShell)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now