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