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