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