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