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