##// END OF EJS Templates
Merge pull request #9338 from takluyver/i9239...
Min RK -
r22175:5555aae2 merge
parent child Browse files
Show More
@@ -1,808 +1,810 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 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 import bdb
9 import bdb
10 import os
10 import os
11 import sys
11 import sys
12
12
13 from IPython.core.error import TryNext, UsageError
13 from IPython.core.error import TryNext, UsageError
14 from IPython.core.usage import interactive_usage
14 from IPython.core.usage import interactive_usage
15 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC
15 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC
16 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
16 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
17 from IPython.core.magic import Magics, magics_class, line_magic
17 from IPython.core.magic import Magics, magics_class, line_magic
18 from IPython.lib.clipboard import ClipboardEmpty
18 from IPython.lib.clipboard import ClipboardEmpty
19 from IPython.utils.contexts import NoOpContext
19 from IPython.utils.contexts import NoOpContext
20 from IPython.utils.decorators import undoc
20 from IPython.utils.decorators import undoc
21 from IPython.utils.encoding import get_stream_enc
21 from IPython.utils.encoding import get_stream_enc
22 from IPython.utils import py3compat
22 from IPython.utils import py3compat
23 from IPython.utils.terminal import toggle_set_term_title, set_term_title
23 from IPython.utils.terminal import toggle_set_term_title, set_term_title
24 from IPython.utils.process import abbrev_cwd
24 from IPython.utils.process import abbrev_cwd
25 from warnings import warn
25 from warnings import warn
26 from logging import error
26 from logging import error
27 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
27 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
28 from traitlets import Integer, CBool, Unicode
28 from traitlets import Integer, CBool, Unicode
29
29
30
30
31 def get_default_editor():
31 def get_default_editor():
32 try:
32 try:
33 ed = os.environ['EDITOR']
33 ed = os.environ['EDITOR']
34 if not py3compat.PY3:
34 if not py3compat.PY3:
35 ed = ed.decode()
35 ed = ed.decode()
36 return ed
36 return ed
37 except KeyError:
37 except KeyError:
38 pass
38 pass
39 except UnicodeError:
39 except UnicodeError:
40 warn("$EDITOR environment variable is not pure ASCII. Using platform "
40 warn("$EDITOR environment variable is not pure ASCII. Using platform "
41 "default editor.")
41 "default editor.")
42
42
43 if os.name == 'posix':
43 if os.name == 'posix':
44 return 'vi' # the only one guaranteed to be there!
44 return 'vi' # the only one guaranteed to be there!
45 else:
45 else:
46 return 'notepad' # same in Windows!
46 return 'notepad' # same in Windows!
47
47
48 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
48 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
49 """ Yield pasted lines until the user enters the given sentinel value.
49 """ Yield pasted lines until the user enters the given sentinel value.
50 """
50 """
51 if not quiet:
51 if not quiet:
52 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
52 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
53 % sentinel)
53 % sentinel)
54 prompt = ":"
54 prompt = ":"
55 else:
55 else:
56 prompt = ""
56 prompt = ""
57 while True:
57 while True:
58 try:
58 try:
59 l = py3compat.str_to_unicode(l_input(prompt))
59 l = py3compat.str_to_unicode(l_input(prompt))
60 if l == sentinel:
60 if l == sentinel:
61 return
61 return
62 else:
62 else:
63 yield l
63 yield l
64 except EOFError:
64 except EOFError:
65 print('<EOF>')
65 print('<EOF>')
66 return
66 return
67
67
68 @undoc
68 @undoc
69 def no_op(*a, **kw): pass
69 def no_op(*a, **kw): pass
70
70
71
71
72 class ReadlineNoRecord(object):
72 class ReadlineNoRecord(object):
73 """Context manager to execute some code, then reload readline history
73 """Context manager to execute some code, then reload readline history
74 so that interactive input to the code doesn't appear when pressing up."""
74 so that interactive input to the code doesn't appear when pressing up."""
75 def __init__(self, shell):
75 def __init__(self, shell):
76 self.shell = shell
76 self.shell = shell
77 self._nested_level = 0
77 self._nested_level = 0
78
78
79 def __enter__(self):
79 def __enter__(self):
80 if self._nested_level == 0:
80 if self._nested_level == 0:
81 try:
81 try:
82 self.orig_length = self.current_length()
82 self.orig_length = self.current_length()
83 self.readline_tail = self.get_readline_tail()
83 self.readline_tail = self.get_readline_tail()
84 except (AttributeError, IndexError): # Can fail with pyreadline
84 except (AttributeError, IndexError): # Can fail with pyreadline
85 self.orig_length, self.readline_tail = 999999, []
85 self.orig_length, self.readline_tail = 999999, []
86 self._nested_level += 1
86 self._nested_level += 1
87
87
88 def __exit__(self, type, value, traceback):
88 def __exit__(self, type, value, traceback):
89 self._nested_level -= 1
89 self._nested_level -= 1
90 if self._nested_level == 0:
90 if self._nested_level == 0:
91 # Try clipping the end if it's got longer
91 # Try clipping the end if it's got longer
92 try:
92 try:
93 e = self.current_length() - self.orig_length
93 e = self.current_length() - self.orig_length
94 if e > 0:
94 if e > 0:
95 for _ in range(e):
95 for _ in range(e):
96 self.shell.readline.remove_history_item(self.orig_length)
96 self.shell.readline.remove_history_item(self.orig_length)
97
97
98 # If it still doesn't match, just reload readline history.
98 # If it still doesn't match, just reload readline history.
99 if self.current_length() != self.orig_length \
99 if self.current_length() != self.orig_length \
100 or self.get_readline_tail() != self.readline_tail:
100 or self.get_readline_tail() != self.readline_tail:
101 self.shell.refill_readline_hist()
101 self.shell.refill_readline_hist()
102 except (AttributeError, IndexError):
102 except (AttributeError, IndexError):
103 pass
103 pass
104 # Returning False will cause exceptions to propagate
104 # Returning False will cause exceptions to propagate
105 return False
105 return False
106
106
107 def current_length(self):
107 def current_length(self):
108 return self.shell.readline.get_current_history_length()
108 return self.shell.readline.get_current_history_length()
109
109
110 def get_readline_tail(self, n=10):
110 def get_readline_tail(self, n=10):
111 """Get the last n items in readline history."""
111 """Get the last n items in readline history."""
112 end = self.shell.readline.get_current_history_length() + 1
112 end = self.shell.readline.get_current_history_length() + 1
113 start = max(end-n, 1)
113 start = max(end-n, 1)
114 ghi = self.shell.readline.get_history_item
114 ghi = self.shell.readline.get_history_item
115 return [ghi(x) for x in range(start, end)]
115 return [ghi(x) for x in range(start, end)]
116
116
117
117
118 @magics_class
118 @magics_class
119 class TerminalMagics(Magics):
119 class TerminalMagics(Magics):
120 def __init__(self, shell):
120 def __init__(self, shell):
121 super(TerminalMagics, self).__init__(shell)
121 super(TerminalMagics, self).__init__(shell)
122 self.input_splitter = IPythonInputSplitter()
122 self.input_splitter = IPythonInputSplitter()
123
123
124 def store_or_execute(self, block, name):
124 def store_or_execute(self, block, name):
125 """ Execute a block, or store it in a variable, per the user's request.
125 """ Execute a block, or store it in a variable, per the user's request.
126 """
126 """
127 if name:
127 if name:
128 # If storing it for further editing
128 # If storing it for further editing
129 self.shell.user_ns[name] = SList(block.splitlines())
129 self.shell.user_ns[name] = SList(block.splitlines())
130 print("Block assigned to '%s'" % name)
130 print("Block assigned to '%s'" % name)
131 else:
131 else:
132 b = self.preclean_input(block)
132 b = self.preclean_input(block)
133 self.shell.user_ns['pasted_block'] = b
133 self.shell.user_ns['pasted_block'] = b
134 self.shell.using_paste_magics = True
134 self.shell.using_paste_magics = True
135 try:
135 try:
136 self.shell.run_cell(b)
136 self.shell.run_cell(b)
137 finally:
137 finally:
138 self.shell.using_paste_magics = False
138 self.shell.using_paste_magics = False
139
139
140 def preclean_input(self, block):
140 def preclean_input(self, block):
141 lines = block.splitlines()
141 lines = block.splitlines()
142 while lines and not lines[0].strip():
142 while lines and not lines[0].strip():
143 lines = lines[1:]
143 lines = lines[1:]
144 return strip_email_quotes('\n'.join(lines))
144 return strip_email_quotes('\n'.join(lines))
145
145
146 def rerun_pasted(self, name='pasted_block'):
146 def rerun_pasted(self, name='pasted_block'):
147 """ Rerun a previously pasted command.
147 """ Rerun a previously pasted command.
148 """
148 """
149 b = self.shell.user_ns.get(name)
149 b = self.shell.user_ns.get(name)
150
150
151 # Sanity checks
151 # Sanity checks
152 if b is None:
152 if b is None:
153 raise UsageError('No previous pasted block available')
153 raise UsageError('No previous pasted block available')
154 if not isinstance(b, py3compat.string_types):
154 if not isinstance(b, py3compat.string_types):
155 raise UsageError(
155 raise UsageError(
156 "Variable 'pasted_block' is not a string, can't execute")
156 "Variable 'pasted_block' is not a string, can't execute")
157
157
158 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
158 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
159 self.shell.run_cell(b)
159 self.shell.run_cell(b)
160
160
161 @line_magic
161 @line_magic
162 def autoindent(self, parameter_s = ''):
162 def autoindent(self, parameter_s = ''):
163 """Toggle autoindent on/off (if available)."""
163 """Toggle autoindent on/off (if available)."""
164
164
165 self.shell.set_autoindent()
165 self.shell.set_autoindent()
166 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
166 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
167
167
168 @line_magic
168 @line_magic
169 def cpaste(self, parameter_s=''):
169 def cpaste(self, parameter_s=''):
170 """Paste & execute a pre-formatted code block from clipboard.
170 """Paste & execute a pre-formatted code block from clipboard.
171
171
172 You must terminate the block with '--' (two minus-signs) or Ctrl-D
172 You must terminate the block with '--' (two minus-signs) or Ctrl-D
173 alone on the line. You can also provide your own sentinel with '%paste
173 alone on the line. You can also provide your own sentinel with '%paste
174 -s %%' ('%%' is the new sentinel for this operation).
174 -s %%' ('%%' is the new sentinel for this operation).
175
175
176 The block is dedented prior to execution to enable execution of method
176 The block is dedented prior to execution to enable execution of method
177 definitions. '>' and '+' characters at the beginning of a line are
177 definitions. '>' and '+' characters at the beginning of a line are
178 ignored, to allow pasting directly from e-mails, diff files and
178 ignored, to allow pasting directly from e-mails, diff files and
179 doctests (the '...' continuation prompt is also stripped). The
179 doctests (the '...' continuation prompt is also stripped). The
180 executed block is also assigned to variable named 'pasted_block' for
180 executed block is also assigned to variable named 'pasted_block' for
181 later editing with '%edit pasted_block'.
181 later editing with '%edit pasted_block'.
182
182
183 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
183 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
184 This assigns the pasted block to variable 'foo' as string, without
184 This assigns the pasted block to variable 'foo' as string, without
185 dedenting or executing it (preceding >>> and + is still stripped)
185 dedenting or executing it (preceding >>> and + is still stripped)
186
186
187 '%cpaste -r' re-executes the block previously entered by cpaste.
187 '%cpaste -r' re-executes the block previously entered by cpaste.
188 '%cpaste -q' suppresses any additional output messages.
188 '%cpaste -q' suppresses any additional output messages.
189
189
190 Do not be alarmed by garbled output on Windows (it's a readline bug).
190 Do not be alarmed by garbled output on Windows (it's a readline bug).
191 Just press enter and type -- (and press enter again) and the block
191 Just press enter and type -- (and press enter again) and the block
192 will be what was just pasted.
192 will be what was just pasted.
193
193
194 IPython statements (magics, shell escapes) are not supported (yet).
194 IPython statements (magics, shell escapes) are not supported (yet).
195
195
196 See also
196 See also
197 --------
197 --------
198 paste: automatically pull code from clipboard.
198 paste: automatically pull code from clipboard.
199
199
200 Examples
200 Examples
201 --------
201 --------
202 ::
202 ::
203
203
204 In [8]: %cpaste
204 In [8]: %cpaste
205 Pasting code; enter '--' alone on the line to stop.
205 Pasting code; enter '--' alone on the line to stop.
206 :>>> a = ["world!", "Hello"]
206 :>>> a = ["world!", "Hello"]
207 :>>> print " ".join(sorted(a))
207 :>>> print " ".join(sorted(a))
208 :--
208 :--
209 Hello world!
209 Hello world!
210 """
210 """
211 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
211 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
212 if 'r' in opts:
212 if 'r' in opts:
213 self.rerun_pasted()
213 self.rerun_pasted()
214 return
214 return
215
215
216 quiet = ('q' in opts)
216 quiet = ('q' in opts)
217
217
218 sentinel = opts.get('s', u'--')
218 sentinel = opts.get('s', u'--')
219 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
219 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
220 self.store_or_execute(block, name)
220 self.store_or_execute(block, name)
221
221
222 @line_magic
222 @line_magic
223 def paste(self, parameter_s=''):
223 def paste(self, parameter_s=''):
224 """Paste & execute a pre-formatted code block from clipboard.
224 """Paste & execute a pre-formatted code block from clipboard.
225
225
226 The text is pulled directly from the clipboard without user
226 The text is pulled directly from the clipboard without user
227 intervention and printed back on the screen before execution (unless
227 intervention and printed back on the screen before execution (unless
228 the -q flag is given to force quiet mode).
228 the -q flag is given to force quiet mode).
229
229
230 The block is dedented prior to execution to enable execution of method
230 The block is dedented prior to execution to enable execution of method
231 definitions. '>' and '+' characters at the beginning of a line are
231 definitions. '>' and '+' characters at the beginning of a line are
232 ignored, to allow pasting directly from e-mails, diff files and
232 ignored, to allow pasting directly from e-mails, diff files and
233 doctests (the '...' continuation prompt is also stripped). The
233 doctests (the '...' continuation prompt is also stripped). The
234 executed block is also assigned to variable named 'pasted_block' for
234 executed block is also assigned to variable named 'pasted_block' for
235 later editing with '%edit pasted_block'.
235 later editing with '%edit pasted_block'.
236
236
237 You can also pass a variable name as an argument, e.g. '%paste foo'.
237 You can also pass a variable name as an argument, e.g. '%paste foo'.
238 This assigns the pasted block to variable 'foo' as string, without
238 This assigns the pasted block to variable 'foo' as string, without
239 executing it (preceding >>> and + is still stripped).
239 executing it (preceding >>> and + is still stripped).
240
240
241 Options:
241 Options:
242
242
243 -r: re-executes the block previously entered by cpaste.
243 -r: re-executes the block previously entered by cpaste.
244
244
245 -q: quiet mode: do not echo the pasted text back to the terminal.
245 -q: quiet mode: do not echo the pasted text back to the terminal.
246
246
247 IPython statements (magics, shell escapes) are not supported (yet).
247 IPython statements (magics, shell escapes) are not supported (yet).
248
248
249 See also
249 See also
250 --------
250 --------
251 cpaste: manually paste code into terminal until you mark its end.
251 cpaste: manually paste code into terminal until you mark its end.
252 """
252 """
253 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
253 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
254 if 'r' in opts:
254 if 'r' in opts:
255 self.rerun_pasted()
255 self.rerun_pasted()
256 return
256 return
257 try:
257 try:
258 block = self.shell.hooks.clipboard_get()
258 block = self.shell.hooks.clipboard_get()
259 except TryNext as clipboard_exc:
259 except TryNext as clipboard_exc:
260 message = getattr(clipboard_exc, 'args')
260 message = getattr(clipboard_exc, 'args')
261 if message:
261 if message:
262 error(message[0])
262 error(message[0])
263 else:
263 else:
264 error('Could not get text from the clipboard.')
264 error('Could not get text from the clipboard.')
265 return
265 return
266 except ClipboardEmpty:
266 except ClipboardEmpty:
267 raise UsageError("The clipboard appears to be empty")
267 raise UsageError("The clipboard appears to be empty")
268
268
269 # By default, echo back to terminal unless quiet mode is requested
269 # By default, echo back to terminal unless quiet mode is requested
270 if 'q' not in opts:
270 if 'q' not in opts:
271 write = self.shell.write
271 write = self.shell.write
272 write(self.shell.pycolorize(block))
272 write(self.shell.pycolorize(block))
273 if not block.endswith('\n'):
273 if not block.endswith('\n'):
274 write('\n')
274 write('\n')
275 write("## -- End pasted text --\n")
275 write("## -- End pasted text --\n")
276
276
277 self.store_or_execute(block, name)
277 self.store_or_execute(block, name)
278
278
279 # Class-level: add a '%cls' magic only on Windows
279 # Class-level: add a '%cls' magic only on Windows
280 if sys.platform == 'win32':
280 if sys.platform == 'win32':
281 @line_magic
281 @line_magic
282 def cls(self, s):
282 def cls(self, s):
283 """Clear screen.
283 """Clear screen.
284 """
284 """
285 os.system("cls")
285 os.system("cls")
286
286
287
287
288 class TerminalInteractiveShell(InteractiveShell):
288 class TerminalInteractiveShell(InteractiveShell):
289
289
290 autoedit_syntax = CBool(False, config=True,
290 autoedit_syntax = CBool(False, config=True,
291 help="auto editing of files with syntax errors.")
291 help="auto editing of files with syntax errors.")
292 confirm_exit = CBool(True, config=True,
292 confirm_exit = CBool(True, config=True,
293 help="""
293 help="""
294 Set to confirm when you try to exit IPython with an EOF (Control-D
294 Set to confirm when you try to exit IPython with an EOF (Control-D
295 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
295 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
296 you can force a direct exit without any confirmation.""",
296 you can force a direct exit without any confirmation.""",
297 )
297 )
298 # This display_banner only controls whether or not self.show_banner()
298 # This display_banner only controls whether or not self.show_banner()
299 # is called when mainloop/interact are called. The default is False
299 # is called when mainloop/interact are called. The default is False
300 # because for the terminal based application, the banner behavior
300 # because for the terminal based application, the banner behavior
301 # is controlled by the application.
301 # is controlled by the application.
302 display_banner = CBool(False) # This isn't configurable!
302 display_banner = CBool(False) # This isn't configurable!
303 embedded = CBool(False)
303 embedded = CBool(False)
304 embedded_active = CBool(False)
304 embedded_active = CBool(False)
305 editor = Unicode(get_default_editor(), config=True,
305 editor = Unicode(get_default_editor(), config=True,
306 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
306 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
307 )
307 )
308 pager = Unicode('less', config=True,
308 pager = Unicode('less', config=True,
309 help="The shell program to be used for paging.")
309 help="The shell program to be used for paging.")
310
310
311 screen_length = Integer(0, config=True,
311 screen_length = Integer(0, config=True,
312 help=
312 help=
313 """Number of lines of your screen, used to control printing of very
313 """Number of lines of your screen, used to control printing of very
314 long strings. Strings longer than this number of lines will be sent
314 long strings. Strings longer than this number of lines will be sent
315 through a pager instead of directly printed. The default value for
315 through a pager instead of directly printed. The default value for
316 this is 0, which means IPython will auto-detect your screen size every
316 this is 0, which means IPython will auto-detect your screen size every
317 time it needs to print certain potentially long strings (this doesn't
317 time it needs to print certain potentially long strings (this doesn't
318 change the behavior of the 'print' keyword, it's only triggered
318 change the behavior of the 'print' keyword, it's only triggered
319 internally). If for some reason this isn't working well (it needs
319 internally). If for some reason this isn't working well (it needs
320 curses support), specify it yourself. Otherwise don't change the
320 curses support), specify it yourself. Otherwise don't change the
321 default.""",
321 default.""",
322 )
322 )
323 term_title = CBool(False, config=True,
323 term_title = CBool(False, config=True,
324 help="Enable auto setting the terminal title."
324 help="Enable auto setting the terminal title."
325 )
325 )
326 usage = Unicode(interactive_usage)
326 usage = Unicode(interactive_usage)
327
327
328 # This `using_paste_magics` is used to detect whether the code is being
328 # This `using_paste_magics` is used to detect whether the code is being
329 # executed via paste magics functions
329 # executed via paste magics functions
330 using_paste_magics = CBool(False)
330 using_paste_magics = CBool(False)
331
331
332 # In the terminal, GUI control is done via PyOS_InputHook
332 # In the terminal, GUI control is done via PyOS_InputHook
333 @staticmethod
333 @staticmethod
334 def enable_gui(gui=None, app=None):
334 def enable_gui(gui=None, app=None):
335 """Switch amongst GUI input hooks by name.
335 """Switch amongst GUI input hooks by name.
336 """
336 """
337 # Deferred import
337 # Deferred import
338 from IPython.lib.inputhook import enable_gui as real_enable_gui
338 from IPython.lib.inputhook import enable_gui as real_enable_gui
339 try:
339 try:
340 return real_enable_gui(gui, app)
340 return real_enable_gui(gui, app)
341 except ValueError as e:
341 except ValueError as e:
342 raise UsageError("%s" % e)
342 raise UsageError("%s" % e)
343
343
344 system = InteractiveShell.system_raw
344 system = InteractiveShell.system_raw
345
345
346 #-------------------------------------------------------------------------
346 #-------------------------------------------------------------------------
347 # Overrides of init stages
347 # Overrides of init stages
348 #-------------------------------------------------------------------------
348 #-------------------------------------------------------------------------
349
349
350 def init_display_formatter(self):
350 def init_display_formatter(self):
351 super(TerminalInteractiveShell, self).init_display_formatter()
351 super(TerminalInteractiveShell, self).init_display_formatter()
352 # terminal only supports plaintext
352 # terminal only supports plaintext
353 self.display_formatter.active_types = ['text/plain']
353 self.display_formatter.active_types = ['text/plain']
354
354
355 #-------------------------------------------------------------------------
355 #-------------------------------------------------------------------------
356 # Things related to readline
356 # Things related to readline
357 #-------------------------------------------------------------------------
357 #-------------------------------------------------------------------------
358
358
359 def init_readline(self):
359 def init_readline(self):
360 """Command history completion/saving/reloading."""
360 """Command history completion/saving/reloading."""
361
361
362 if self.readline_use:
362 if self.readline_use:
363 import IPython.utils.rlineimpl as readline
363 import IPython.utils.rlineimpl as readline
364
364
365 self.rl_next_input = None
365 self.rl_next_input = None
366 self.rl_do_indent = False
366 self.rl_do_indent = False
367
367
368 if not self.readline_use or not readline.have_readline:
368 if not self.readline_use or not readline.have_readline:
369 self.readline = None
369 self.readline = None
370 # Set a number of methods that depend on readline to be no-op
370 # Set a number of methods that depend on readline to be no-op
371 self.readline_no_record = NoOpContext()
371 self.readline_no_record = NoOpContext()
372 self.set_readline_completer = no_op
372 self.set_readline_completer = no_op
373 self.set_custom_completer = no_op
373 self.set_custom_completer = no_op
374 if self.readline_use:
374 if self.readline_use:
375 warn('Readline services not available or not loaded.')
375 warn('Readline services not available or not loaded.')
376 else:
376 else:
377 self.has_readline = True
377 self.has_readline = True
378 self.readline = readline
378 self.readline = readline
379 sys.modules['readline'] = readline
379 sys.modules['readline'] = readline
380
380
381 # Platform-specific configuration
381 # Platform-specific configuration
382 if os.name == 'nt':
382 if os.name == 'nt':
383 # FIXME - check with Frederick to see if we can harmonize
383 # FIXME - check with Frederick to see if we can harmonize
384 # naming conventions with pyreadline to avoid this
384 # naming conventions with pyreadline to avoid this
385 # platform-dependent check
385 # platform-dependent check
386 self.readline_startup_hook = readline.set_pre_input_hook
386 self.readline_startup_hook = readline.set_pre_input_hook
387 else:
387 else:
388 self.readline_startup_hook = readline.set_startup_hook
388 self.readline_startup_hook = readline.set_startup_hook
389
389
390 # Readline config order:
390 # Readline config order:
391 # - IPython config (default value)
391 # - IPython config (default value)
392 # - custom inputrc
392 # - custom inputrc
393 # - IPython config (user customized)
393 # - IPython config (user customized)
394
394
395 # load IPython config before inputrc if default
395 # load IPython config before inputrc if default
396 # skip if libedit because parse_and_bind syntax is different
396 # skip if libedit because parse_and_bind syntax is different
397 if not self._custom_readline_config and not readline.uses_libedit:
397 if not self._custom_readline_config and not readline.uses_libedit:
398 for rlcommand in self.readline_parse_and_bind:
398 for rlcommand in self.readline_parse_and_bind:
399 readline.parse_and_bind(rlcommand)
399 readline.parse_and_bind(rlcommand)
400
400
401 # Load user's initrc file (readline config)
401 # Load user's initrc file (readline config)
402 # Or if libedit is used, load editrc.
402 # Or if libedit is used, load editrc.
403 inputrc_name = os.environ.get('INPUTRC')
403 inputrc_name = os.environ.get('INPUTRC')
404 if inputrc_name is None:
404 if inputrc_name is None:
405 inputrc_name = '.inputrc'
405 inputrc_name = '.inputrc'
406 if readline.uses_libedit:
406 if readline.uses_libedit:
407 inputrc_name = '.editrc'
407 inputrc_name = '.editrc'
408 inputrc_name = os.path.join(self.home_dir, inputrc_name)
408 inputrc_name = os.path.join(self.home_dir, inputrc_name)
409 if os.path.isfile(inputrc_name):
409 if os.path.isfile(inputrc_name):
410 try:
410 try:
411 readline.read_init_file(inputrc_name)
411 readline.read_init_file(inputrc_name)
412 except:
412 except:
413 warn('Problems reading readline initialization file <%s>'
413 warn('Problems reading readline initialization file <%s>'
414 % inputrc_name)
414 % inputrc_name)
415
415
416 # load IPython config after inputrc if user has customized
416 # load IPython config after inputrc if user has customized
417 if self._custom_readline_config:
417 if self._custom_readline_config:
418 for rlcommand in self.readline_parse_and_bind:
418 for rlcommand in self.readline_parse_and_bind:
419 readline.parse_and_bind(rlcommand)
419 readline.parse_and_bind(rlcommand)
420
420
421 # Remove some chars from the delimiters list. If we encounter
421 # Remove some chars from the delimiters list. If we encounter
422 # unicode chars, discard them.
422 # unicode chars, discard them.
423 delims = readline.get_completer_delims()
423 delims = readline.get_completer_delims()
424 if not py3compat.PY3:
424 if not py3compat.PY3:
425 delims = delims.encode("ascii", "ignore")
425 delims = delims.encode("ascii", "ignore")
426 for d in self.readline_remove_delims:
426 for d in self.readline_remove_delims:
427 delims = delims.replace(d, "")
427 delims = delims.replace(d, "")
428 delims = delims.replace(ESC_MAGIC, '')
428 delims = delims.replace(ESC_MAGIC, '')
429 readline.set_completer_delims(delims)
429 readline.set_completer_delims(delims)
430 # Store these so we can restore them if something like rpy2 modifies
430 # Store these so we can restore them if something like rpy2 modifies
431 # them.
431 # them.
432 self.readline_delims = delims
432 self.readline_delims = delims
433 # otherwise we end up with a monster history after a while:
433 # otherwise we end up with a monster history after a while:
434 readline.set_history_length(self.history_length)
434 readline.set_history_length(self.history_length)
435
435
436 self.refill_readline_hist()
436 self.refill_readline_hist()
437 self.readline_no_record = ReadlineNoRecord(self)
437 self.readline_no_record = ReadlineNoRecord(self)
438
438
439 # Configure auto-indent for all platforms
439 # Configure auto-indent for all platforms
440 self.set_autoindent(self.autoindent)
440 self.set_autoindent(self.autoindent)
441
441
442 def init_completer(self):
442 def init_completer(self):
443 super(TerminalInteractiveShell, self).init_completer()
443 super(TerminalInteractiveShell, self).init_completer()
444
444
445 # Only configure readline if we truly are using readline.
445 # Only configure readline if we truly are using readline.
446 if self.has_readline:
446 if self.has_readline:
447 self.set_readline_completer()
447 self.set_readline_completer()
448
448
449 def set_readline_completer(self):
449 def set_readline_completer(self):
450 """Reset readline's completer to be our own."""
450 """Reset readline's completer to be our own."""
451 self.readline.set_completer(self.Completer.rlcomplete)
451 self.readline.set_completer(self.Completer.rlcomplete)
452
452
453
453
454 def pre_readline(self):
454 def pre_readline(self):
455 """readline hook to be used at the start of each line.
455 """readline hook to be used at the start of each line.
456
456
457 It handles auto-indent and text from set_next_input."""
457 It handles auto-indent and text from set_next_input."""
458
458
459 if self.rl_do_indent:
459 if self.rl_do_indent:
460 self.readline.insert_text(self._indent_current_str())
460 self.readline.insert_text(self._indent_current_str())
461 if self.rl_next_input is not None:
461 if self.rl_next_input is not None:
462 self.readline.insert_text(self.rl_next_input)
462 self.readline.insert_text(self.rl_next_input)
463 self.rl_next_input = None
463 self.rl_next_input = None
464
464
465 def refill_readline_hist(self):
465 def refill_readline_hist(self):
466 # Load the last 1000 lines from history
466 # Load the last 1000 lines from history
467 self.readline.clear_history()
467 self.readline.clear_history()
468 stdin_encoding = sys.stdin.encoding or "utf-8"
468 stdin_encoding = sys.stdin.encoding or "utf-8"
469 last_cell = u""
469 last_cell = u""
470 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
470 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
471 include_latest=True):
471 include_latest=True):
472 # Ignore blank lines and consecutive duplicates
472 # Ignore blank lines and consecutive duplicates
473 cell = cell.rstrip()
473 cell = cell.rstrip()
474 if cell and (cell != last_cell):
474 if cell and (cell != last_cell):
475 try:
475 try:
476 if self.multiline_history:
476 if self.multiline_history:
477 self.readline.add_history(py3compat.unicode_to_str(cell,
477 self.readline.add_history(py3compat.unicode_to_str(cell,
478 stdin_encoding))
478 stdin_encoding))
479 else:
479 else:
480 for line in cell.splitlines():
480 for line in cell.splitlines():
481 self.readline.add_history(py3compat.unicode_to_str(line,
481 self.readline.add_history(py3compat.unicode_to_str(line,
482 stdin_encoding))
482 stdin_encoding))
483 last_cell = cell
483 last_cell = cell
484
484
485 except TypeError:
485 except (TypeError, ValueError) as e:
486 # The history DB can get corrupted so it returns strings
486 # The history DB can get corrupted so it returns strings
487 # containing null bytes, which readline objects to.
487 # containing null bytes, which readline objects to.
488 continue
488 warn(("Failed to add string to readline history.\n"
489 "Error: {}\n"
490 "Cell: {!r}").format(e, cell))
489
491
490 #-------------------------------------------------------------------------
492 #-------------------------------------------------------------------------
491 # Things related to the terminal
493 # Things related to the terminal
492 #-------------------------------------------------------------------------
494 #-------------------------------------------------------------------------
493
495
494 @property
496 @property
495 def usable_screen_length(self):
497 def usable_screen_length(self):
496 if self.screen_length == 0:
498 if self.screen_length == 0:
497 return 0
499 return 0
498 else:
500 else:
499 num_lines_bot = self.separate_in.count('\n')+1
501 num_lines_bot = self.separate_in.count('\n')+1
500 return self.screen_length - num_lines_bot
502 return self.screen_length - num_lines_bot
501
503
502 def _term_title_changed(self, name, new_value):
504 def _term_title_changed(self, name, new_value):
503 self.init_term_title()
505 self.init_term_title()
504
506
505 def init_term_title(self):
507 def init_term_title(self):
506 # Enable or disable the terminal title.
508 # Enable or disable the terminal title.
507 if self.term_title:
509 if self.term_title:
508 toggle_set_term_title(True)
510 toggle_set_term_title(True)
509 set_term_title('IPython: ' + abbrev_cwd())
511 set_term_title('IPython: ' + abbrev_cwd())
510 else:
512 else:
511 toggle_set_term_title(False)
513 toggle_set_term_title(False)
512
514
513 #-------------------------------------------------------------------------
515 #-------------------------------------------------------------------------
514 # Things related to aliases
516 # Things related to aliases
515 #-------------------------------------------------------------------------
517 #-------------------------------------------------------------------------
516
518
517 def init_alias(self):
519 def init_alias(self):
518 # The parent class defines aliases that can be safely used with any
520 # The parent class defines aliases that can be safely used with any
519 # frontend.
521 # frontend.
520 super(TerminalInteractiveShell, self).init_alias()
522 super(TerminalInteractiveShell, self).init_alias()
521
523
522 # Now define aliases that only make sense on the terminal, because they
524 # Now define aliases that only make sense on the terminal, because they
523 # need direct access to the console in a way that we can't emulate in
525 # need direct access to the console in a way that we can't emulate in
524 # GUI or web frontend
526 # GUI or web frontend
525 if os.name == 'posix':
527 if os.name == 'posix':
526 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
528 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
527 ('man', 'man')]
529 ('man', 'man')]
528 else :
530 else :
529 aliases = []
531 aliases = []
530
532
531 for name, cmd in aliases:
533 for name, cmd in aliases:
532 self.alias_manager.soft_define_alias(name, cmd)
534 self.alias_manager.soft_define_alias(name, cmd)
533
535
534 #-------------------------------------------------------------------------
536 #-------------------------------------------------------------------------
535 # Mainloop and code execution logic
537 # Mainloop and code execution logic
536 #-------------------------------------------------------------------------
538 #-------------------------------------------------------------------------
537
539
538 def mainloop(self, display_banner=None):
540 def mainloop(self, display_banner=None):
539 """Start the mainloop.
541 """Start the mainloop.
540
542
541 If an optional banner argument is given, it will override the
543 If an optional banner argument is given, it will override the
542 internally created default banner.
544 internally created default banner.
543 """
545 """
544
546
545 with self.builtin_trap, self.display_trap:
547 with self.builtin_trap, self.display_trap:
546
548
547 while 1:
549 while 1:
548 try:
550 try:
549 self.interact(display_banner=display_banner)
551 self.interact(display_banner=display_banner)
550 #self.interact_with_readline()
552 #self.interact_with_readline()
551 # XXX for testing of a readline-decoupled repl loop, call
553 # XXX for testing of a readline-decoupled repl loop, call
552 # interact_with_readline above
554 # interact_with_readline above
553 break
555 break
554 except KeyboardInterrupt:
556 except KeyboardInterrupt:
555 # this should not be necessary, but KeyboardInterrupt
557 # this should not be necessary, but KeyboardInterrupt
556 # handling seems rather unpredictable...
558 # handling seems rather unpredictable...
557 self.write("\nKeyboardInterrupt in interact()\n")
559 self.write("\nKeyboardInterrupt in interact()\n")
558
560
559 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
561 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
560 """Store multiple lines as a single entry in history"""
562 """Store multiple lines as a single entry in history"""
561
563
562 # do nothing without readline or disabled multiline
564 # do nothing without readline or disabled multiline
563 if not self.has_readline or not self.multiline_history:
565 if not self.has_readline or not self.multiline_history:
564 return hlen_before_cell
566 return hlen_before_cell
565
567
566 # windows rl has no remove_history_item
568 # windows rl has no remove_history_item
567 if not hasattr(self.readline, "remove_history_item"):
569 if not hasattr(self.readline, "remove_history_item"):
568 return hlen_before_cell
570 return hlen_before_cell
569
571
570 # skip empty cells
572 # skip empty cells
571 if not source_raw.rstrip():
573 if not source_raw.rstrip():
572 return hlen_before_cell
574 return hlen_before_cell
573
575
574 # nothing changed do nothing, e.g. when rl removes consecutive dups
576 # nothing changed do nothing, e.g. when rl removes consecutive dups
575 hlen = self.readline.get_current_history_length()
577 hlen = self.readline.get_current_history_length()
576 if hlen == hlen_before_cell:
578 if hlen == hlen_before_cell:
577 return hlen_before_cell
579 return hlen_before_cell
578
580
579 for i in range(hlen - hlen_before_cell):
581 for i in range(hlen - hlen_before_cell):
580 self.readline.remove_history_item(hlen - i - 1)
582 self.readline.remove_history_item(hlen - i - 1)
581 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
583 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
582 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
584 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
583 stdin_encoding))
585 stdin_encoding))
584 return self.readline.get_current_history_length()
586 return self.readline.get_current_history_length()
585
587
586 def interact(self, display_banner=None):
588 def interact(self, display_banner=None):
587 """Closely emulate the interactive Python console."""
589 """Closely emulate the interactive Python console."""
588
590
589 # batch run -> do not interact
591 # batch run -> do not interact
590 if self.exit_now:
592 if self.exit_now:
591 return
593 return
592
594
593 if display_banner is None:
595 if display_banner is None:
594 display_banner = self.display_banner
596 display_banner = self.display_banner
595
597
596 if isinstance(display_banner, py3compat.string_types):
598 if isinstance(display_banner, py3compat.string_types):
597 self.show_banner(display_banner)
599 self.show_banner(display_banner)
598 elif display_banner:
600 elif display_banner:
599 self.show_banner()
601 self.show_banner()
600
602
601 more = False
603 more = False
602
604
603 if self.has_readline:
605 if self.has_readline:
604 self.readline_startup_hook(self.pre_readline)
606 self.readline_startup_hook(self.pre_readline)
605 hlen_b4_cell = self.readline.get_current_history_length()
607 hlen_b4_cell = self.readline.get_current_history_length()
606 else:
608 else:
607 hlen_b4_cell = 0
609 hlen_b4_cell = 0
608 # exit_now is set by a call to %Exit or %Quit, through the
610 # exit_now is set by a call to %Exit or %Quit, through the
609 # ask_exit callback.
611 # ask_exit callback.
610
612
611 while not self.exit_now:
613 while not self.exit_now:
612 self.hooks.pre_prompt_hook()
614 self.hooks.pre_prompt_hook()
613 if more:
615 if more:
614 try:
616 try:
615 prompt = self.prompt_manager.render('in2')
617 prompt = self.prompt_manager.render('in2')
616 except:
618 except:
617 self.showtraceback()
619 self.showtraceback()
618 if self.autoindent:
620 if self.autoindent:
619 self.rl_do_indent = True
621 self.rl_do_indent = True
620
622
621 else:
623 else:
622 try:
624 try:
623 prompt = self.separate_in + self.prompt_manager.render('in')
625 prompt = self.separate_in + self.prompt_manager.render('in')
624 except:
626 except:
625 self.showtraceback()
627 self.showtraceback()
626 try:
628 try:
627 line = self.raw_input(prompt)
629 line = self.raw_input(prompt)
628 if self.exit_now:
630 if self.exit_now:
629 # quick exit on sys.std[in|out] close
631 # quick exit on sys.std[in|out] close
630 break
632 break
631 if self.autoindent:
633 if self.autoindent:
632 self.rl_do_indent = False
634 self.rl_do_indent = False
633
635
634 except KeyboardInterrupt:
636 except KeyboardInterrupt:
635 #double-guard against keyboardinterrupts during kbdint handling
637 #double-guard against keyboardinterrupts during kbdint handling
636 try:
638 try:
637 self.write('\n' + self.get_exception_only())
639 self.write('\n' + self.get_exception_only())
638 source_raw = self.input_splitter.raw_reset()
640 source_raw = self.input_splitter.raw_reset()
639 hlen_b4_cell = \
641 hlen_b4_cell = \
640 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
642 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
641 more = False
643 more = False
642 except KeyboardInterrupt:
644 except KeyboardInterrupt:
643 pass
645 pass
644 except EOFError:
646 except EOFError:
645 if self.autoindent:
647 if self.autoindent:
646 self.rl_do_indent = False
648 self.rl_do_indent = False
647 if self.has_readline:
649 if self.has_readline:
648 self.readline_startup_hook(None)
650 self.readline_startup_hook(None)
649 self.write('\n')
651 self.write('\n')
650 self.exit()
652 self.exit()
651 except bdb.BdbQuit:
653 except bdb.BdbQuit:
652 warn('The Python debugger has exited with a BdbQuit exception.\n'
654 warn('The Python debugger has exited with a BdbQuit exception.\n'
653 'Because of how pdb handles the stack, it is impossible\n'
655 'Because of how pdb handles the stack, it is impossible\n'
654 'for IPython to properly format this particular exception.\n'
656 'for IPython to properly format this particular exception.\n'
655 'IPython will resume normal operation.')
657 'IPython will resume normal operation.')
656 except:
658 except:
657 # exceptions here are VERY RARE, but they can be triggered
659 # exceptions here are VERY RARE, but they can be triggered
658 # asynchronously by signal handlers, for example.
660 # asynchronously by signal handlers, for example.
659 self.showtraceback()
661 self.showtraceback()
660 else:
662 else:
661 try:
663 try:
662 self.input_splitter.push(line)
664 self.input_splitter.push(line)
663 more = self.input_splitter.push_accepts_more()
665 more = self.input_splitter.push_accepts_more()
664 except SyntaxError:
666 except SyntaxError:
665 # Run the code directly - run_cell takes care of displaying
667 # Run the code directly - run_cell takes care of displaying
666 # the exception.
668 # the exception.
667 more = False
669 more = False
668 if (self.SyntaxTB.last_syntax_error and
670 if (self.SyntaxTB.last_syntax_error and
669 self.autoedit_syntax):
671 self.autoedit_syntax):
670 self.edit_syntax_error()
672 self.edit_syntax_error()
671 if not more:
673 if not more:
672 source_raw = self.input_splitter.raw_reset()
674 source_raw = self.input_splitter.raw_reset()
673 self.run_cell(source_raw, store_history=True)
675 self.run_cell(source_raw, store_history=True)
674 hlen_b4_cell = \
676 hlen_b4_cell = \
675 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
677 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
676
678
677 # Turn off the exit flag, so the mainloop can be restarted if desired
679 # Turn off the exit flag, so the mainloop can be restarted if desired
678 self.exit_now = False
680 self.exit_now = False
679
681
680 def raw_input(self, prompt=''):
682 def raw_input(self, prompt=''):
681 """Write a prompt and read a line.
683 """Write a prompt and read a line.
682
684
683 The returned line does not include the trailing newline.
685 The returned line does not include the trailing newline.
684 When the user enters the EOF key sequence, EOFError is raised.
686 When the user enters the EOF key sequence, EOFError is raised.
685
687
686 Parameters
688 Parameters
687 ----------
689 ----------
688
690
689 prompt : str, optional
691 prompt : str, optional
690 A string to be printed to prompt the user.
692 A string to be printed to prompt the user.
691 """
693 """
692 # raw_input expects str, but we pass it unicode sometimes
694 # raw_input expects str, but we pass it unicode sometimes
693 prompt = py3compat.cast_bytes_py2(prompt)
695 prompt = py3compat.cast_bytes_py2(prompt)
694
696
695 try:
697 try:
696 line = py3compat.cast_unicode_py2(self.raw_input_original(prompt))
698 line = py3compat.cast_unicode_py2(self.raw_input_original(prompt))
697 except ValueError:
699 except ValueError:
698 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
700 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
699 " or sys.stdout.close()!\nExiting IPython!\n")
701 " or sys.stdout.close()!\nExiting IPython!\n")
700 self.ask_exit()
702 self.ask_exit()
701 return ""
703 return ""
702
704
703 # Try to be reasonably smart about not re-indenting pasted input more
705 # Try to be reasonably smart about not re-indenting pasted input more
704 # than necessary. We do this by trimming out the auto-indent initial
706 # than necessary. We do this by trimming out the auto-indent initial
705 # spaces, if the user's actual input started itself with whitespace.
707 # spaces, if the user's actual input started itself with whitespace.
706 if self.autoindent:
708 if self.autoindent:
707 if num_ini_spaces(line) > self.indent_current_nsp:
709 if num_ini_spaces(line) > self.indent_current_nsp:
708 line = line[self.indent_current_nsp:]
710 line = line[self.indent_current_nsp:]
709 self.indent_current_nsp = 0
711 self.indent_current_nsp = 0
710
712
711 return line
713 return line
712
714
713 #-------------------------------------------------------------------------
715 #-------------------------------------------------------------------------
714 # Methods to support auto-editing of SyntaxErrors.
716 # Methods to support auto-editing of SyntaxErrors.
715 #-------------------------------------------------------------------------
717 #-------------------------------------------------------------------------
716
718
717 def edit_syntax_error(self):
719 def edit_syntax_error(self):
718 """The bottom half of the syntax error handler called in the main loop.
720 """The bottom half of the syntax error handler called in the main loop.
719
721
720 Loop until syntax error is fixed or user cancels.
722 Loop until syntax error is fixed or user cancels.
721 """
723 """
722
724
723 while self.SyntaxTB.last_syntax_error:
725 while self.SyntaxTB.last_syntax_error:
724 # copy and clear last_syntax_error
726 # copy and clear last_syntax_error
725 err = self.SyntaxTB.clear_err_state()
727 err = self.SyntaxTB.clear_err_state()
726 if not self._should_recompile(err):
728 if not self._should_recompile(err):
727 return
729 return
728 try:
730 try:
729 # may set last_syntax_error again if a SyntaxError is raised
731 # may set last_syntax_error again if a SyntaxError is raised
730 self.safe_execfile(err.filename,self.user_ns)
732 self.safe_execfile(err.filename,self.user_ns)
731 except:
733 except:
732 self.showtraceback()
734 self.showtraceback()
733 else:
735 else:
734 try:
736 try:
735 f = open(err.filename)
737 f = open(err.filename)
736 try:
738 try:
737 # This should be inside a display_trap block and I
739 # This should be inside a display_trap block and I
738 # think it is.
740 # think it is.
739 sys.displayhook(f.read())
741 sys.displayhook(f.read())
740 finally:
742 finally:
741 f.close()
743 f.close()
742 except:
744 except:
743 self.showtraceback()
745 self.showtraceback()
744
746
745 def _should_recompile(self,e):
747 def _should_recompile(self,e):
746 """Utility routine for edit_syntax_error"""
748 """Utility routine for edit_syntax_error"""
747
749
748 if e.filename in ('<ipython console>','<input>','<string>',
750 if e.filename in ('<ipython console>','<input>','<string>',
749 '<console>','<BackgroundJob compilation>',
751 '<console>','<BackgroundJob compilation>',
750 None):
752 None):
751
753
752 return False
754 return False
753 try:
755 try:
754 if (self.autoedit_syntax and
756 if (self.autoedit_syntax and
755 not self.ask_yes_no('Return to editor to correct syntax error? '
757 not self.ask_yes_no('Return to editor to correct syntax error? '
756 '[Y/n] ','y')):
758 '[Y/n] ','y')):
757 return False
759 return False
758 except EOFError:
760 except EOFError:
759 return False
761 return False
760
762
761 def int0(x):
763 def int0(x):
762 try:
764 try:
763 return int(x)
765 return int(x)
764 except TypeError:
766 except TypeError:
765 return 0
767 return 0
766 # always pass integer line and offset values to editor hook
768 # always pass integer line and offset values to editor hook
767 try:
769 try:
768 self.hooks.fix_error_editor(e.filename,
770 self.hooks.fix_error_editor(e.filename,
769 int0(e.lineno),int0(e.offset),e.msg)
771 int0(e.lineno),int0(e.offset),e.msg)
770 except TryNext:
772 except TryNext:
771 warn('Could not open editor')
773 warn('Could not open editor')
772 return False
774 return False
773 return True
775 return True
774
776
775 #-------------------------------------------------------------------------
777 #-------------------------------------------------------------------------
776 # Things related to exiting
778 # Things related to exiting
777 #-------------------------------------------------------------------------
779 #-------------------------------------------------------------------------
778
780
779 def ask_exit(self):
781 def ask_exit(self):
780 """ Ask the shell to exit. Can be overiden and used as a callback. """
782 """ Ask the shell to exit. Can be overiden and used as a callback. """
781 self.exit_now = True
783 self.exit_now = True
782
784
783 def exit(self):
785 def exit(self):
784 """Handle interactive exit.
786 """Handle interactive exit.
785
787
786 This method calls the ask_exit callback."""
788 This method calls the ask_exit callback."""
787 if self.confirm_exit:
789 if self.confirm_exit:
788 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
790 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
789 self.ask_exit()
791 self.ask_exit()
790 else:
792 else:
791 self.ask_exit()
793 self.ask_exit()
792
794
793 #-------------------------------------------------------------------------
795 #-------------------------------------------------------------------------
794 # Things related to magics
796 # Things related to magics
795 #-------------------------------------------------------------------------
797 #-------------------------------------------------------------------------
796
798
797 def init_magics(self):
799 def init_magics(self):
798 super(TerminalInteractiveShell, self).init_magics()
800 super(TerminalInteractiveShell, self).init_magics()
799 self.register_magics(TerminalMagics)
801 self.register_magics(TerminalMagics)
800
802
801 def showindentationerror(self):
803 def showindentationerror(self):
802 super(TerminalInteractiveShell, self).showindentationerror()
804 super(TerminalInteractiveShell, self).showindentationerror()
803 if not self.using_paste_magics:
805 if not self.using_paste_magics:
804 print("If you want to paste code into IPython, try the "
806 print("If you want to paste code into IPython, try the "
805 "%paste and %cpaste magic functions.")
807 "%paste and %cpaste magic functions.")
806
808
807
809
808 InteractiveShellABC.register(TerminalInteractiveShell)
810 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now