##// END OF EJS Templates
Merge pull request #4353 from asmeurer/completion_no-reset...
Fernando Perez -
r13782:ddd15502 merge
parent child Browse files
Show More
@@ -1,697 +1,691 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-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 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 from __future__ import print_function
16 from __future__ import print_function
17
17
18 import bdb
18 import bdb
19 import os
19 import os
20 import sys
20 import sys
21
21
22 from IPython.core.error import TryNext, UsageError
22 from IPython.core.error import TryNext, UsageError
23 from IPython.core.usage import interactive_usage, default_banner
23 from IPython.core.usage import interactive_usage, default_banner
24 from IPython.core.inputsplitter import IPythonInputSplitter
24 from IPython.core.inputsplitter import IPythonInputSplitter
25 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
25 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
26 from IPython.core.magic import Magics, magics_class, line_magic
26 from IPython.core.magic import Magics, magics_class, line_magic
27 from IPython.lib.clipboard import ClipboardEmpty
27 from IPython.lib.clipboard import ClipboardEmpty
28 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.testing.skipdoctest import skip_doctest
29 from IPython.utils.encoding import get_stream_enc
29 from IPython.utils.encoding import get_stream_enc
30 from IPython.utils import py3compat
30 from IPython.utils import py3compat
31 from IPython.utils.terminal import toggle_set_term_title, set_term_title
31 from IPython.utils.terminal import toggle_set_term_title, set_term_title
32 from IPython.utils.process import abbrev_cwd
32 from IPython.utils.process import abbrev_cwd
33 from IPython.utils.warn import warn, error
33 from IPython.utils.warn import warn, error
34 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
34 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
35 from IPython.utils.traitlets import Integer, CBool, Unicode
35 from IPython.utils.traitlets import Integer, CBool, Unicode
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Utilities
38 # Utilities
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 def get_default_editor():
41 def get_default_editor():
42 try:
42 try:
43 ed = os.environ['EDITOR']
43 ed = os.environ['EDITOR']
44 if not py3compat.PY3:
44 if not py3compat.PY3:
45 ed = ed.decode()
45 ed = ed.decode()
46 return ed
46 return ed
47 except KeyError:
47 except KeyError:
48 pass
48 pass
49 except UnicodeError:
49 except UnicodeError:
50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
51 "default editor.")
51 "default editor.")
52
52
53 if os.name == 'posix':
53 if os.name == 'posix':
54 return 'vi' # the only one guaranteed to be there!
54 return 'vi' # the only one guaranteed to be there!
55 else:
55 else:
56 return 'notepad' # same in Windows!
56 return 'notepad' # same in Windows!
57
57
58 def get_pasted_lines(sentinel, l_input=py3compat.input):
58 def get_pasted_lines(sentinel, l_input=py3compat.input):
59 """ Yield pasted lines until the user enters the given sentinel value.
59 """ Yield pasted lines until the user enters the given sentinel value.
60 """
60 """
61 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
61 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
62 % sentinel)
62 % sentinel)
63 while True:
63 while True:
64 try:
64 try:
65 l = l_input(':')
65 l = l_input(':')
66 if l == sentinel:
66 if l == sentinel:
67 return
67 return
68 else:
68 else:
69 yield l
69 yield l
70 except EOFError:
70 except EOFError:
71 print('<EOF>')
71 print('<EOF>')
72 return
72 return
73
73
74
74
75 #------------------------------------------------------------------------
75 #------------------------------------------------------------------------
76 # Terminal-specific magics
76 # Terminal-specific magics
77 #------------------------------------------------------------------------
77 #------------------------------------------------------------------------
78
78
79 @magics_class
79 @magics_class
80 class TerminalMagics(Magics):
80 class TerminalMagics(Magics):
81 def __init__(self, shell):
81 def __init__(self, shell):
82 super(TerminalMagics, self).__init__(shell)
82 super(TerminalMagics, self).__init__(shell)
83 self.input_splitter = IPythonInputSplitter()
83 self.input_splitter = IPythonInputSplitter()
84
84
85 def store_or_execute(self, block, name):
85 def store_or_execute(self, block, name):
86 """ Execute a block, or store it in a variable, per the user's request.
86 """ Execute a block, or store it in a variable, per the user's request.
87 """
87 """
88 if name:
88 if name:
89 # If storing it for further editing
89 # If storing it for further editing
90 self.shell.user_ns[name] = SList(block.splitlines())
90 self.shell.user_ns[name] = SList(block.splitlines())
91 print("Block assigned to '%s'" % name)
91 print("Block assigned to '%s'" % name)
92 else:
92 else:
93 b = self.preclean_input(block)
93 b = self.preclean_input(block)
94 self.shell.user_ns['pasted_block'] = b
94 self.shell.user_ns['pasted_block'] = b
95 self.shell.using_paste_magics = True
95 self.shell.using_paste_magics = True
96 try:
96 try:
97 self.shell.run_cell(b)
97 self.shell.run_cell(b)
98 finally:
98 finally:
99 self.shell.using_paste_magics = False
99 self.shell.using_paste_magics = False
100
100
101 def preclean_input(self, block):
101 def preclean_input(self, block):
102 lines = block.splitlines()
102 lines = block.splitlines()
103 while lines and not lines[0].strip():
103 while lines and not lines[0].strip():
104 lines = lines[1:]
104 lines = lines[1:]
105 return strip_email_quotes('\n'.join(lines))
105 return strip_email_quotes('\n'.join(lines))
106
106
107 def rerun_pasted(self, name='pasted_block'):
107 def rerun_pasted(self, name='pasted_block'):
108 """ Rerun a previously pasted command.
108 """ Rerun a previously pasted command.
109 """
109 """
110 b = self.shell.user_ns.get(name)
110 b = self.shell.user_ns.get(name)
111
111
112 # Sanity checks
112 # Sanity checks
113 if b is None:
113 if b is None:
114 raise UsageError('No previous pasted block available')
114 raise UsageError('No previous pasted block available')
115 if not isinstance(b, py3compat.string_types):
115 if not isinstance(b, py3compat.string_types):
116 raise UsageError(
116 raise UsageError(
117 "Variable 'pasted_block' is not a string, can't execute")
117 "Variable 'pasted_block' is not a string, can't execute")
118
118
119 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
119 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
120 self.shell.run_cell(b)
120 self.shell.run_cell(b)
121
121
122 @line_magic
122 @line_magic
123 def autoindent(self, parameter_s = ''):
123 def autoindent(self, parameter_s = ''):
124 """Toggle autoindent on/off (if available)."""
124 """Toggle autoindent on/off (if available)."""
125
125
126 self.shell.set_autoindent()
126 self.shell.set_autoindent()
127 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
127 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
128
128
129 @skip_doctest
129 @skip_doctest
130 @line_magic
130 @line_magic
131 def cpaste(self, parameter_s=''):
131 def cpaste(self, parameter_s=''):
132 """Paste & execute a pre-formatted code block from clipboard.
132 """Paste & execute a pre-formatted code block from clipboard.
133
133
134 You must terminate the block with '--' (two minus-signs) or Ctrl-D
134 You must terminate the block with '--' (two minus-signs) or Ctrl-D
135 alone on the line. You can also provide your own sentinel with '%paste
135 alone on the line. You can also provide your own sentinel with '%paste
136 -s %%' ('%%' is the new sentinel for this operation)
136 -s %%' ('%%' is the new sentinel for this operation)
137
137
138 The block is dedented prior to execution to enable execution of method
138 The block is dedented prior to execution to enable execution of method
139 definitions. '>' and '+' characters at the beginning of a line are
139 definitions. '>' and '+' characters at the beginning of a line are
140 ignored, to allow pasting directly from e-mails, diff files and
140 ignored, to allow pasting directly from e-mails, diff files and
141 doctests (the '...' continuation prompt is also stripped). The
141 doctests (the '...' continuation prompt is also stripped). The
142 executed block is also assigned to variable named 'pasted_block' for
142 executed block is also assigned to variable named 'pasted_block' for
143 later editing with '%edit pasted_block'.
143 later editing with '%edit pasted_block'.
144
144
145 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
145 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
146 This assigns the pasted block to variable 'foo' as string, without
146 This assigns the pasted block to variable 'foo' as string, without
147 dedenting or executing it (preceding >>> and + is still stripped)
147 dedenting or executing it (preceding >>> and + is still stripped)
148
148
149 '%cpaste -r' re-executes the block previously entered by cpaste.
149 '%cpaste -r' re-executes the block previously entered by cpaste.
150
150
151 Do not be alarmed by garbled output on Windows (it's a readline bug).
151 Do not be alarmed by garbled output on Windows (it's a readline bug).
152 Just press enter and type -- (and press enter again) and the block
152 Just press enter and type -- (and press enter again) and the block
153 will be what was just pasted.
153 will be what was just pasted.
154
154
155 IPython statements (magics, shell escapes) are not supported (yet).
155 IPython statements (magics, shell escapes) are not supported (yet).
156
156
157 See also
157 See also
158 --------
158 --------
159 paste: automatically pull code from clipboard.
159 paste: automatically pull code from clipboard.
160
160
161 Examples
161 Examples
162 --------
162 --------
163 ::
163 ::
164
164
165 In [8]: %cpaste
165 In [8]: %cpaste
166 Pasting code; enter '--' alone on the line to stop.
166 Pasting code; enter '--' alone on the line to stop.
167 :>>> a = ["world!", "Hello"]
167 :>>> a = ["world!", "Hello"]
168 :>>> print " ".join(sorted(a))
168 :>>> print " ".join(sorted(a))
169 :--
169 :--
170 Hello world!
170 Hello world!
171 """
171 """
172 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
172 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
173 if 'r' in opts:
173 if 'r' in opts:
174 self.rerun_pasted()
174 self.rerun_pasted()
175 return
175 return
176
176
177 sentinel = opts.get('s', '--')
177 sentinel = opts.get('s', '--')
178 block = '\n'.join(get_pasted_lines(sentinel))
178 block = '\n'.join(get_pasted_lines(sentinel))
179 self.store_or_execute(block, name)
179 self.store_or_execute(block, name)
180
180
181 @line_magic
181 @line_magic
182 def paste(self, parameter_s=''):
182 def paste(self, parameter_s=''):
183 """Paste & execute a pre-formatted code block from clipboard.
183 """Paste & execute a pre-formatted code block from clipboard.
184
184
185 The text is pulled directly from the clipboard without user
185 The text is pulled directly from the clipboard without user
186 intervention and printed back on the screen before execution (unless
186 intervention and printed back on the screen before execution (unless
187 the -q flag is given to force quiet mode).
187 the -q flag is given to force quiet mode).
188
188
189 The block is dedented prior to execution to enable execution of method
189 The block is dedented prior to execution to enable execution of method
190 definitions. '>' and '+' characters at the beginning of a line are
190 definitions. '>' and '+' characters at the beginning of a line are
191 ignored, to allow pasting directly from e-mails, diff files and
191 ignored, to allow pasting directly from e-mails, diff files and
192 doctests (the '...' continuation prompt is also stripped). The
192 doctests (the '...' continuation prompt is also stripped). The
193 executed block is also assigned to variable named 'pasted_block' for
193 executed block is also assigned to variable named 'pasted_block' for
194 later editing with '%edit pasted_block'.
194 later editing with '%edit pasted_block'.
195
195
196 You can also pass a variable name as an argument, e.g. '%paste foo'.
196 You can also pass a variable name as an argument, e.g. '%paste foo'.
197 This assigns the pasted block to variable 'foo' as string, without
197 This assigns the pasted block to variable 'foo' as string, without
198 executing it (preceding >>> and + is still stripped).
198 executing it (preceding >>> and + is still stripped).
199
199
200 Options:
200 Options:
201
201
202 -r: re-executes the block previously entered by cpaste.
202 -r: re-executes the block previously entered by cpaste.
203
203
204 -q: quiet mode: do not echo the pasted text back to the terminal.
204 -q: quiet mode: do not echo the pasted text back to the terminal.
205
205
206 IPython statements (magics, shell escapes) are not supported (yet).
206 IPython statements (magics, shell escapes) are not supported (yet).
207
207
208 See also
208 See also
209 --------
209 --------
210 cpaste: manually paste code into terminal until you mark its end.
210 cpaste: manually paste code into terminal until you mark its end.
211 """
211 """
212 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
212 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
213 if 'r' in opts:
213 if 'r' in opts:
214 self.rerun_pasted()
214 self.rerun_pasted()
215 return
215 return
216 try:
216 try:
217 block = self.shell.hooks.clipboard_get()
217 block = self.shell.hooks.clipboard_get()
218 except TryNext as clipboard_exc:
218 except TryNext as clipboard_exc:
219 message = getattr(clipboard_exc, 'args')
219 message = getattr(clipboard_exc, 'args')
220 if message:
220 if message:
221 error(message[0])
221 error(message[0])
222 else:
222 else:
223 error('Could not get text from the clipboard.')
223 error('Could not get text from the clipboard.')
224 return
224 return
225 except ClipboardEmpty:
225 except ClipboardEmpty:
226 raise UsageError("The clipboard appears to be empty")
226 raise UsageError("The clipboard appears to be empty")
227
227
228 # By default, echo back to terminal unless quiet mode is requested
228 # By default, echo back to terminal unless quiet mode is requested
229 if 'q' not in opts:
229 if 'q' not in opts:
230 write = self.shell.write
230 write = self.shell.write
231 write(self.shell.pycolorize(block))
231 write(self.shell.pycolorize(block))
232 if not block.endswith('\n'):
232 if not block.endswith('\n'):
233 write('\n')
233 write('\n')
234 write("## -- End pasted text --\n")
234 write("## -- End pasted text --\n")
235
235
236 self.store_or_execute(block, name)
236 self.store_or_execute(block, name)
237
237
238 # Class-level: add a '%cls' magic only on Windows
238 # Class-level: add a '%cls' magic only on Windows
239 if sys.platform == 'win32':
239 if sys.platform == 'win32':
240 @line_magic
240 @line_magic
241 def cls(self, s):
241 def cls(self, s):
242 """Clear screen.
242 """Clear screen.
243 """
243 """
244 os.system("cls")
244 os.system("cls")
245
245
246 #-----------------------------------------------------------------------------
246 #-----------------------------------------------------------------------------
247 # Main class
247 # Main class
248 #-----------------------------------------------------------------------------
248 #-----------------------------------------------------------------------------
249
249
250 class TerminalInteractiveShell(InteractiveShell):
250 class TerminalInteractiveShell(InteractiveShell):
251
251
252 autoedit_syntax = CBool(False, config=True,
252 autoedit_syntax = CBool(False, config=True,
253 help="auto editing of files with syntax errors.")
253 help="auto editing of files with syntax errors.")
254 banner = Unicode('')
254 banner = Unicode('')
255 banner1 = Unicode(default_banner, config=True,
255 banner1 = Unicode(default_banner, config=True,
256 help="""The part of the banner to be printed before the profile"""
256 help="""The part of the banner to be printed before the profile"""
257 )
257 )
258 banner2 = Unicode('', config=True,
258 banner2 = Unicode('', config=True,
259 help="""The part of the banner to be printed after the profile"""
259 help="""The part of the banner to be printed after the profile"""
260 )
260 )
261 confirm_exit = CBool(True, config=True,
261 confirm_exit = CBool(True, config=True,
262 help="""
262 help="""
263 Set to confirm when you try to exit IPython with an EOF (Control-D
263 Set to confirm when you try to exit IPython with an EOF (Control-D
264 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
264 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
265 you can force a direct exit without any confirmation.""",
265 you can force a direct exit without any confirmation.""",
266 )
266 )
267 # This display_banner only controls whether or not self.show_banner()
267 # This display_banner only controls whether or not self.show_banner()
268 # is called when mainloop/interact are called. The default is False
268 # is called when mainloop/interact are called. The default is False
269 # because for the terminal based application, the banner behavior
269 # because for the terminal based application, the banner behavior
270 # is controlled by Global.display_banner, which IPythonApp looks at
270 # is controlled by Global.display_banner, which IPythonApp looks at
271 # to determine if *it* should call show_banner() by hand or not.
271 # to determine if *it* should call show_banner() by hand or not.
272 display_banner = CBool(False) # This isn't configurable!
272 display_banner = CBool(False) # This isn't configurable!
273 embedded = CBool(False)
273 embedded = CBool(False)
274 embedded_active = CBool(False)
274 embedded_active = CBool(False)
275 editor = Unicode(get_default_editor(), config=True,
275 editor = Unicode(get_default_editor(), config=True,
276 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
276 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
277 )
277 )
278 pager = Unicode('less', config=True,
278 pager = Unicode('less', config=True,
279 help="The shell program to be used for paging.")
279 help="The shell program to be used for paging.")
280
280
281 screen_length = Integer(0, config=True,
281 screen_length = Integer(0, config=True,
282 help=
282 help=
283 """Number of lines of your screen, used to control printing of very
283 """Number of lines of your screen, used to control printing of very
284 long strings. Strings longer than this number of lines will be sent
284 long strings. Strings longer than this number of lines will be sent
285 through a pager instead of directly printed. The default value for
285 through a pager instead of directly printed. The default value for
286 this is 0, which means IPython will auto-detect your screen size every
286 this is 0, which means IPython will auto-detect your screen size every
287 time it needs to print certain potentially long strings (this doesn't
287 time it needs to print certain potentially long strings (this doesn't
288 change the behavior of the 'print' keyword, it's only triggered
288 change the behavior of the 'print' keyword, it's only triggered
289 internally). If for some reason this isn't working well (it needs
289 internally). If for some reason this isn't working well (it needs
290 curses support), specify it yourself. Otherwise don't change the
290 curses support), specify it yourself. Otherwise don't change the
291 default.""",
291 default.""",
292 )
292 )
293 term_title = CBool(False, config=True,
293 term_title = CBool(False, config=True,
294 help="Enable auto setting the terminal title."
294 help="Enable auto setting the terminal title."
295 )
295 )
296
296
297 # This `using_paste_magics` is used to detect whether the code is being
297 # This `using_paste_magics` is used to detect whether the code is being
298 # executed via paste magics functions
298 # executed via paste magics functions
299 using_paste_magics = CBool(False)
299 using_paste_magics = CBool(False)
300
300
301 # In the terminal, GUI control is done via PyOS_InputHook
301 # In the terminal, GUI control is done via PyOS_InputHook
302 @staticmethod
302 @staticmethod
303 def enable_gui(gui=None, app=None):
303 def enable_gui(gui=None, app=None):
304 """Switch amongst GUI input hooks by name.
304 """Switch amongst GUI input hooks by name.
305 """
305 """
306 # Deferred import
306 # Deferred import
307 from IPython.lib.inputhook import enable_gui as real_enable_gui
307 from IPython.lib.inputhook import enable_gui as real_enable_gui
308 try:
308 try:
309 return real_enable_gui(gui, app)
309 return real_enable_gui(gui, app)
310 except ValueError as e:
310 except ValueError as e:
311 raise UsageError("%s" % e)
311 raise UsageError("%s" % e)
312
312
313 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
313 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
314 user_ns=None, user_module=None, custom_exceptions=((),None),
314 user_ns=None, user_module=None, custom_exceptions=((),None),
315 usage=None, banner1=None, banner2=None, display_banner=None,
315 usage=None, banner1=None, banner2=None, display_banner=None,
316 **kwargs):
316 **kwargs):
317
317
318 super(TerminalInteractiveShell, self).__init__(
318 super(TerminalInteractiveShell, self).__init__(
319 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
319 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
320 user_module=user_module, custom_exceptions=custom_exceptions,
320 user_module=user_module, custom_exceptions=custom_exceptions,
321 **kwargs
321 **kwargs
322 )
322 )
323 # use os.system instead of utils.process.system by default,
323 # use os.system instead of utils.process.system by default,
324 # because piped system doesn't make sense in the Terminal:
324 # because piped system doesn't make sense in the Terminal:
325 self.system = self.system_raw
325 self.system = self.system_raw
326
326
327 self.init_term_title()
327 self.init_term_title()
328 self.init_usage(usage)
328 self.init_usage(usage)
329 self.init_banner(banner1, banner2, display_banner)
329 self.init_banner(banner1, banner2, display_banner)
330
330
331 #-------------------------------------------------------------------------
331 #-------------------------------------------------------------------------
332 # Overrides of init stages
332 # Overrides of init stages
333 #-------------------------------------------------------------------------
333 #-------------------------------------------------------------------------
334
334
335 def init_display_formatter(self):
335 def init_display_formatter(self):
336 super(TerminalInteractiveShell, self).init_display_formatter()
336 super(TerminalInteractiveShell, self).init_display_formatter()
337 # terminal only supports plaintext
337 # terminal only supports plaintext
338 self.display_formatter.active_types = ['text/plain']
338 self.display_formatter.active_types = ['text/plain']
339
339
340 #-------------------------------------------------------------------------
340 #-------------------------------------------------------------------------
341 # Things related to the terminal
341 # Things related to the terminal
342 #-------------------------------------------------------------------------
342 #-------------------------------------------------------------------------
343
343
344 @property
344 @property
345 def usable_screen_length(self):
345 def usable_screen_length(self):
346 if self.screen_length == 0:
346 if self.screen_length == 0:
347 return 0
347 return 0
348 else:
348 else:
349 num_lines_bot = self.separate_in.count('\n')+1
349 num_lines_bot = self.separate_in.count('\n')+1
350 return self.screen_length - num_lines_bot
350 return self.screen_length - num_lines_bot
351
351
352 def init_term_title(self):
352 def init_term_title(self):
353 # Enable or disable the terminal title.
353 # Enable or disable the terminal title.
354 if self.term_title:
354 if self.term_title:
355 toggle_set_term_title(True)
355 toggle_set_term_title(True)
356 set_term_title('IPython: ' + abbrev_cwd())
356 set_term_title('IPython: ' + abbrev_cwd())
357 else:
357 else:
358 toggle_set_term_title(False)
358 toggle_set_term_title(False)
359
359
360 #-------------------------------------------------------------------------
360 #-------------------------------------------------------------------------
361 # Things related to aliases
361 # Things related to aliases
362 #-------------------------------------------------------------------------
362 #-------------------------------------------------------------------------
363
363
364 def init_alias(self):
364 def init_alias(self):
365 # The parent class defines aliases that can be safely used with any
365 # The parent class defines aliases that can be safely used with any
366 # frontend.
366 # frontend.
367 super(TerminalInteractiveShell, self).init_alias()
367 super(TerminalInteractiveShell, self).init_alias()
368
368
369 # Now define aliases that only make sense on the terminal, because they
369 # Now define aliases that only make sense on the terminal, because they
370 # need direct access to the console in a way that we can't emulate in
370 # need direct access to the console in a way that we can't emulate in
371 # GUI or web frontend
371 # GUI or web frontend
372 if os.name == 'posix':
372 if os.name == 'posix':
373 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
373 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
374 ('man', 'man')]
374 ('man', 'man')]
375 elif os.name == 'nt':
375 elif os.name == 'nt':
376 aliases = [('cls', 'cls')]
376 aliases = [('cls', 'cls')]
377
377
378
378
379 for name, cmd in aliases:
379 for name, cmd in aliases:
380 self.alias_manager.soft_define_alias(name, cmd)
380 self.alias_manager.soft_define_alias(name, cmd)
381
381
382 #-------------------------------------------------------------------------
382 #-------------------------------------------------------------------------
383 # Things related to the banner and usage
383 # Things related to the banner and usage
384 #-------------------------------------------------------------------------
384 #-------------------------------------------------------------------------
385
385
386 def _banner1_changed(self):
386 def _banner1_changed(self):
387 self.compute_banner()
387 self.compute_banner()
388
388
389 def _banner2_changed(self):
389 def _banner2_changed(self):
390 self.compute_banner()
390 self.compute_banner()
391
391
392 def _term_title_changed(self, name, new_value):
392 def _term_title_changed(self, name, new_value):
393 self.init_term_title()
393 self.init_term_title()
394
394
395 def init_banner(self, banner1, banner2, display_banner):
395 def init_banner(self, banner1, banner2, display_banner):
396 if banner1 is not None:
396 if banner1 is not None:
397 self.banner1 = banner1
397 self.banner1 = banner1
398 if banner2 is not None:
398 if banner2 is not None:
399 self.banner2 = banner2
399 self.banner2 = banner2
400 if display_banner is not None:
400 if display_banner is not None:
401 self.display_banner = display_banner
401 self.display_banner = display_banner
402 self.compute_banner()
402 self.compute_banner()
403
403
404 def show_banner(self, banner=None):
404 def show_banner(self, banner=None):
405 if banner is None:
405 if banner is None:
406 banner = self.banner
406 banner = self.banner
407 self.write(banner)
407 self.write(banner)
408
408
409 def compute_banner(self):
409 def compute_banner(self):
410 self.banner = self.banner1
410 self.banner = self.banner1
411 if self.profile and self.profile != 'default':
411 if self.profile and self.profile != 'default':
412 self.banner += '\nIPython profile: %s\n' % self.profile
412 self.banner += '\nIPython profile: %s\n' % self.profile
413 if self.banner2:
413 if self.banner2:
414 self.banner += '\n' + self.banner2
414 self.banner += '\n' + self.banner2
415
415
416 def init_usage(self, usage=None):
416 def init_usage(self, usage=None):
417 if usage is None:
417 if usage is None:
418 self.usage = interactive_usage
418 self.usage = interactive_usage
419 else:
419 else:
420 self.usage = usage
420 self.usage = usage
421
421
422 #-------------------------------------------------------------------------
422 #-------------------------------------------------------------------------
423 # Mainloop and code execution logic
423 # Mainloop and code execution logic
424 #-------------------------------------------------------------------------
424 #-------------------------------------------------------------------------
425
425
426 def mainloop(self, display_banner=None):
426 def mainloop(self, display_banner=None):
427 """Start the mainloop.
427 """Start the mainloop.
428
428
429 If an optional banner argument is given, it will override the
429 If an optional banner argument is given, it will override the
430 internally created default banner.
430 internally created default banner.
431 """
431 """
432
432
433 with self.builtin_trap, self.display_trap:
433 with self.builtin_trap, self.display_trap:
434
434
435 while 1:
435 while 1:
436 try:
436 try:
437 self.interact(display_banner=display_banner)
437 self.interact(display_banner=display_banner)
438 #self.interact_with_readline()
438 #self.interact_with_readline()
439 # XXX for testing of a readline-decoupled repl loop, call
439 # XXX for testing of a readline-decoupled repl loop, call
440 # interact_with_readline above
440 # interact_with_readline above
441 break
441 break
442 except KeyboardInterrupt:
442 except KeyboardInterrupt:
443 # this should not be necessary, but KeyboardInterrupt
443 # this should not be necessary, but KeyboardInterrupt
444 # handling seems rather unpredictable...
444 # handling seems rather unpredictable...
445 self.write("\nKeyboardInterrupt in interact()\n")
445 self.write("\nKeyboardInterrupt in interact()\n")
446
446
447 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
447 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
448 """Store multiple lines as a single entry in history"""
448 """Store multiple lines as a single entry in history"""
449
449
450 # do nothing without readline or disabled multiline
450 # do nothing without readline or disabled multiline
451 if not self.has_readline or not self.multiline_history:
451 if not self.has_readline or not self.multiline_history:
452 return hlen_before_cell
452 return hlen_before_cell
453
453
454 # windows rl has no remove_history_item
454 # windows rl has no remove_history_item
455 if not hasattr(self.readline, "remove_history_item"):
455 if not hasattr(self.readline, "remove_history_item"):
456 return hlen_before_cell
456 return hlen_before_cell
457
457
458 # skip empty cells
458 # skip empty cells
459 if not source_raw.rstrip():
459 if not source_raw.rstrip():
460 return hlen_before_cell
460 return hlen_before_cell
461
461
462 # nothing changed do nothing, e.g. when rl removes consecutive dups
462 # nothing changed do nothing, e.g. when rl removes consecutive dups
463 hlen = self.readline.get_current_history_length()
463 hlen = self.readline.get_current_history_length()
464 if hlen == hlen_before_cell:
464 if hlen == hlen_before_cell:
465 return hlen_before_cell
465 return hlen_before_cell
466
466
467 for i in range(hlen - hlen_before_cell):
467 for i in range(hlen - hlen_before_cell):
468 self.readline.remove_history_item(hlen - i - 1)
468 self.readline.remove_history_item(hlen - i - 1)
469 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
469 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
470 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
470 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
471 stdin_encoding))
471 stdin_encoding))
472 return self.readline.get_current_history_length()
472 return self.readline.get_current_history_length()
473
473
474 def interact(self, display_banner=None):
474 def interact(self, display_banner=None):
475 """Closely emulate the interactive Python console."""
475 """Closely emulate the interactive Python console."""
476
476
477 # batch run -> do not interact
477 # batch run -> do not interact
478 if self.exit_now:
478 if self.exit_now:
479 return
479 return
480
480
481 if display_banner is None:
481 if display_banner is None:
482 display_banner = self.display_banner
482 display_banner = self.display_banner
483
483
484 if isinstance(display_banner, py3compat.string_types):
484 if isinstance(display_banner, py3compat.string_types):
485 self.show_banner(display_banner)
485 self.show_banner(display_banner)
486 elif display_banner:
486 elif display_banner:
487 self.show_banner()
487 self.show_banner()
488
488
489 more = False
489 more = False
490
490
491 if self.has_readline:
491 if self.has_readline:
492 self.readline_startup_hook(self.pre_readline)
492 self.readline_startup_hook(self.pre_readline)
493 hlen_b4_cell = self.readline.get_current_history_length()
493 hlen_b4_cell = self.readline.get_current_history_length()
494 else:
494 else:
495 hlen_b4_cell = 0
495 hlen_b4_cell = 0
496 # exit_now is set by a call to %Exit or %Quit, through the
496 # exit_now is set by a call to %Exit or %Quit, through the
497 # ask_exit callback.
497 # ask_exit callback.
498
498
499 while not self.exit_now:
499 while not self.exit_now:
500 self.hooks.pre_prompt_hook()
500 self.hooks.pre_prompt_hook()
501 if more:
501 if more:
502 try:
502 try:
503 prompt = self.prompt_manager.render('in2')
503 prompt = self.prompt_manager.render('in2')
504 except:
504 except:
505 self.showtraceback()
505 self.showtraceback()
506 if self.autoindent:
506 if self.autoindent:
507 self.rl_do_indent = True
507 self.rl_do_indent = True
508
508
509 else:
509 else:
510 try:
510 try:
511 prompt = self.separate_in + self.prompt_manager.render('in')
511 prompt = self.separate_in + self.prompt_manager.render('in')
512 except:
512 except:
513 self.showtraceback()
513 self.showtraceback()
514 try:
514 try:
515 line = self.raw_input(prompt)
515 line = self.raw_input(prompt)
516 if self.exit_now:
516 if self.exit_now:
517 # quick exit on sys.std[in|out] close
517 # quick exit on sys.std[in|out] close
518 break
518 break
519 if self.autoindent:
519 if self.autoindent:
520 self.rl_do_indent = False
520 self.rl_do_indent = False
521
521
522 except KeyboardInterrupt:
522 except KeyboardInterrupt:
523 #double-guard against keyboardinterrupts during kbdint handling
523 #double-guard against keyboardinterrupts during kbdint handling
524 try:
524 try:
525 self.write('\nKeyboardInterrupt\n')
525 self.write('\nKeyboardInterrupt\n')
526 source_raw = self.input_splitter.source_raw_reset()[1]
526 source_raw = self.input_splitter.source_raw_reset()[1]
527 hlen_b4_cell = \
527 hlen_b4_cell = \
528 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
528 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
529 more = False
529 more = False
530 except KeyboardInterrupt:
530 except KeyboardInterrupt:
531 pass
531 pass
532 except EOFError:
532 except EOFError:
533 if self.autoindent:
533 if self.autoindent:
534 self.rl_do_indent = False
534 self.rl_do_indent = False
535 if self.has_readline:
535 if self.has_readline:
536 self.readline_startup_hook(None)
536 self.readline_startup_hook(None)
537 self.write('\n')
537 self.write('\n')
538 self.exit()
538 self.exit()
539 except bdb.BdbQuit:
539 except bdb.BdbQuit:
540 warn('The Python debugger has exited with a BdbQuit exception.\n'
540 warn('The Python debugger has exited with a BdbQuit exception.\n'
541 'Because of how pdb handles the stack, it is impossible\n'
541 'Because of how pdb handles the stack, it is impossible\n'
542 'for IPython to properly format this particular exception.\n'
542 'for IPython to properly format this particular exception.\n'
543 'IPython will resume normal operation.')
543 'IPython will resume normal operation.')
544 except:
544 except:
545 # exceptions here are VERY RARE, but they can be triggered
545 # exceptions here are VERY RARE, but they can be triggered
546 # asynchronously by signal handlers, for example.
546 # asynchronously by signal handlers, for example.
547 self.showtraceback()
547 self.showtraceback()
548 else:
548 else:
549 self.input_splitter.push(line)
549 self.input_splitter.push(line)
550 more = self.input_splitter.push_accepts_more()
550 more = self.input_splitter.push_accepts_more()
551 if (self.SyntaxTB.last_syntax_error and
551 if (self.SyntaxTB.last_syntax_error and
552 self.autoedit_syntax):
552 self.autoedit_syntax):
553 self.edit_syntax_error()
553 self.edit_syntax_error()
554 if not more:
554 if not more:
555 source_raw = self.input_splitter.source_raw_reset()[1]
555 source_raw = self.input_splitter.source_raw_reset()[1]
556 self.run_cell(source_raw, store_history=True)
556 self.run_cell(source_raw, store_history=True)
557 hlen_b4_cell = \
557 hlen_b4_cell = \
558 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
558 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
559
559
560 # Turn off the exit flag, so the mainloop can be restarted if desired
560 # Turn off the exit flag, so the mainloop can be restarted if desired
561 self.exit_now = False
561 self.exit_now = False
562
562
563 def raw_input(self, prompt=''):
563 def raw_input(self, prompt=''):
564 """Write a prompt and read a line.
564 """Write a prompt and read a line.
565
565
566 The returned line does not include the trailing newline.
566 The returned line does not include the trailing newline.
567 When the user enters the EOF key sequence, EOFError is raised.
567 When the user enters the EOF key sequence, EOFError is raised.
568
568
569 Parameters
569 Parameters
570 ----------
570 ----------
571
571
572 prompt : str, optional
572 prompt : str, optional
573 A string to be printed to prompt the user.
573 A string to be printed to prompt the user.
574 """
574 """
575 # Code run by the user may have modified the readline completer state.
576 # We must ensure that our completer is back in place.
577
578 if self.has_readline:
579 self.set_readline_completer()
580
581 # raw_input expects str, but we pass it unicode sometimes
575 # raw_input expects str, but we pass it unicode sometimes
582 prompt = py3compat.cast_bytes_py2(prompt)
576 prompt = py3compat.cast_bytes_py2(prompt)
583
577
584 try:
578 try:
585 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
579 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
586 except ValueError:
580 except ValueError:
587 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
581 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
588 " or sys.stdout.close()!\nExiting IPython!\n")
582 " or sys.stdout.close()!\nExiting IPython!\n")
589 self.ask_exit()
583 self.ask_exit()
590 return ""
584 return ""
591
585
592 # Try to be reasonably smart about not re-indenting pasted input more
586 # Try to be reasonably smart about not re-indenting pasted input more
593 # than necessary. We do this by trimming out the auto-indent initial
587 # than necessary. We do this by trimming out the auto-indent initial
594 # spaces, if the user's actual input started itself with whitespace.
588 # spaces, if the user's actual input started itself with whitespace.
595 if self.autoindent:
589 if self.autoindent:
596 if num_ini_spaces(line) > self.indent_current_nsp:
590 if num_ini_spaces(line) > self.indent_current_nsp:
597 line = line[self.indent_current_nsp:]
591 line = line[self.indent_current_nsp:]
598 self.indent_current_nsp = 0
592 self.indent_current_nsp = 0
599
593
600 return line
594 return line
601
595
602 #-------------------------------------------------------------------------
596 #-------------------------------------------------------------------------
603 # Methods to support auto-editing of SyntaxErrors.
597 # Methods to support auto-editing of SyntaxErrors.
604 #-------------------------------------------------------------------------
598 #-------------------------------------------------------------------------
605
599
606 def edit_syntax_error(self):
600 def edit_syntax_error(self):
607 """The bottom half of the syntax error handler called in the main loop.
601 """The bottom half of the syntax error handler called in the main loop.
608
602
609 Loop until syntax error is fixed or user cancels.
603 Loop until syntax error is fixed or user cancels.
610 """
604 """
611
605
612 while self.SyntaxTB.last_syntax_error:
606 while self.SyntaxTB.last_syntax_error:
613 # copy and clear last_syntax_error
607 # copy and clear last_syntax_error
614 err = self.SyntaxTB.clear_err_state()
608 err = self.SyntaxTB.clear_err_state()
615 if not self._should_recompile(err):
609 if not self._should_recompile(err):
616 return
610 return
617 try:
611 try:
618 # may set last_syntax_error again if a SyntaxError is raised
612 # may set last_syntax_error again if a SyntaxError is raised
619 self.safe_execfile(err.filename,self.user_ns)
613 self.safe_execfile(err.filename,self.user_ns)
620 except:
614 except:
621 self.showtraceback()
615 self.showtraceback()
622 else:
616 else:
623 try:
617 try:
624 f = open(err.filename)
618 f = open(err.filename)
625 try:
619 try:
626 # This should be inside a display_trap block and I
620 # This should be inside a display_trap block and I
627 # think it is.
621 # think it is.
628 sys.displayhook(f.read())
622 sys.displayhook(f.read())
629 finally:
623 finally:
630 f.close()
624 f.close()
631 except:
625 except:
632 self.showtraceback()
626 self.showtraceback()
633
627
634 def _should_recompile(self,e):
628 def _should_recompile(self,e):
635 """Utility routine for edit_syntax_error"""
629 """Utility routine for edit_syntax_error"""
636
630
637 if e.filename in ('<ipython console>','<input>','<string>',
631 if e.filename in ('<ipython console>','<input>','<string>',
638 '<console>','<BackgroundJob compilation>',
632 '<console>','<BackgroundJob compilation>',
639 None):
633 None):
640
634
641 return False
635 return False
642 try:
636 try:
643 if (self.autoedit_syntax and
637 if (self.autoedit_syntax and
644 not self.ask_yes_no('Return to editor to correct syntax error? '
638 not self.ask_yes_no('Return to editor to correct syntax error? '
645 '[Y/n] ','y')):
639 '[Y/n] ','y')):
646 return False
640 return False
647 except EOFError:
641 except EOFError:
648 return False
642 return False
649
643
650 def int0(x):
644 def int0(x):
651 try:
645 try:
652 return int(x)
646 return int(x)
653 except TypeError:
647 except TypeError:
654 return 0
648 return 0
655 # always pass integer line and offset values to editor hook
649 # always pass integer line and offset values to editor hook
656 try:
650 try:
657 self.hooks.fix_error_editor(e.filename,
651 self.hooks.fix_error_editor(e.filename,
658 int0(e.lineno),int0(e.offset),e.msg)
652 int0(e.lineno),int0(e.offset),e.msg)
659 except TryNext:
653 except TryNext:
660 warn('Could not open editor')
654 warn('Could not open editor')
661 return False
655 return False
662 return True
656 return True
663
657
664 #-------------------------------------------------------------------------
658 #-------------------------------------------------------------------------
665 # Things related to exiting
659 # Things related to exiting
666 #-------------------------------------------------------------------------
660 #-------------------------------------------------------------------------
667
661
668 def ask_exit(self):
662 def ask_exit(self):
669 """ Ask the shell to exit. Can be overiden and used as a callback. """
663 """ Ask the shell to exit. Can be overiden and used as a callback. """
670 self.exit_now = True
664 self.exit_now = True
671
665
672 def exit(self):
666 def exit(self):
673 """Handle interactive exit.
667 """Handle interactive exit.
674
668
675 This method calls the ask_exit callback."""
669 This method calls the ask_exit callback."""
676 if self.confirm_exit:
670 if self.confirm_exit:
677 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
671 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
678 self.ask_exit()
672 self.ask_exit()
679 else:
673 else:
680 self.ask_exit()
674 self.ask_exit()
681
675
682 #-------------------------------------------------------------------------
676 #-------------------------------------------------------------------------
683 # Things related to magics
677 # Things related to magics
684 #-------------------------------------------------------------------------
678 #-------------------------------------------------------------------------
685
679
686 def init_magics(self):
680 def init_magics(self):
687 super(TerminalInteractiveShell, self).init_magics()
681 super(TerminalInteractiveShell, self).init_magics()
688 self.register_magics(TerminalMagics)
682 self.register_magics(TerminalMagics)
689
683
690 def showindentationerror(self):
684 def showindentationerror(self):
691 super(TerminalInteractiveShell, self).showindentationerror()
685 super(TerminalInteractiveShell, self).showindentationerror()
692 if not self.using_paste_magics:
686 if not self.using_paste_magics:
693 print("If you want to paste code into IPython, try the "
687 print("If you want to paste code into IPython, try the "
694 "%paste and %cpaste magic functions.")
688 "%paste and %cpaste magic functions.")
695
689
696
690
697 InteractiveShellABC.register(TerminalInteractiveShell)
691 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now