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