##// END OF EJS Templates
Remove outdated colors_force attribute
Thomas Kluyver -
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,599 +1,584 b''
1 1 """Implementation of basic magic functions."""
2 2
3 3 from __future__ import print_function
4 4 from __future__ import absolute_import
5 5
6 6 import io
7 7 import sys
8 8 from pprint import pformat
9 9
10 10 from IPython.core import magic_arguments, page
11 11 from IPython.core.error import UsageError
12 12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
13 13 from IPython.utils.text import format_screen, dedent, indent
14 14 from IPython.testing.skipdoctest import skip_doctest
15 15 from IPython.utils.ipstruct import Struct
16 16 from IPython.utils.py3compat import unicode_type
17 17 from warnings import warn
18 18 from logging import error
19 19
20 20
21 21 class MagicsDisplay(object):
22 22 def __init__(self, magics_manager):
23 23 self.magics_manager = magics_manager
24 24
25 25 def _lsmagic(self):
26 26 """The main implementation of the %lsmagic"""
27 27 mesc = magic_escapes['line']
28 28 cesc = magic_escapes['cell']
29 29 mman = self.magics_manager
30 30 magics = mman.lsmagic()
31 31 out = ['Available line magics:',
32 32 mesc + (' '+mesc).join(sorted(magics['line'])),
33 33 '',
34 34 'Available cell magics:',
35 35 cesc + (' '+cesc).join(sorted(magics['cell'])),
36 36 '',
37 37 mman.auto_status()]
38 38 return '\n'.join(out)
39 39
40 40 def _repr_pretty_(self, p, cycle):
41 41 p.text(self._lsmagic())
42 42
43 43 def __str__(self):
44 44 return self._lsmagic()
45 45
46 46 def _jsonable(self):
47 47 """turn magics dict into jsonable dict of the same structure
48 48
49 49 replaces object instances with their class names as strings
50 50 """
51 51 magic_dict = {}
52 52 mman = self.magics_manager
53 53 magics = mman.lsmagic()
54 54 for key, subdict in magics.items():
55 55 d = {}
56 56 magic_dict[key] = d
57 57 for name, obj in subdict.items():
58 58 try:
59 59 classname = obj.__self__.__class__.__name__
60 60 except AttributeError:
61 61 classname = 'Other'
62 62
63 63 d[name] = classname
64 64 return magic_dict
65 65
66 66 def _repr_json_(self):
67 67 return self._jsonable()
68 68
69 69
70 70 @magics_class
71 71 class BasicMagics(Magics):
72 72 """Magics that provide central IPython functionality.
73 73
74 74 These are various magics that don't fit into specific categories but that
75 75 are all part of the base 'IPython experience'."""
76 76
77 77 @magic_arguments.magic_arguments()
78 78 @magic_arguments.argument(
79 79 '-l', '--line', action='store_true',
80 80 help="""Create a line magic alias."""
81 81 )
82 82 @magic_arguments.argument(
83 83 '-c', '--cell', action='store_true',
84 84 help="""Create a cell magic alias."""
85 85 )
86 86 @magic_arguments.argument(
87 87 'name',
88 88 help="""Name of the magic to be created."""
89 89 )
90 90 @magic_arguments.argument(
91 91 'target',
92 92 help="""Name of the existing line or cell magic."""
93 93 )
94 94 @line_magic
95 95 def alias_magic(self, line=''):
96 96 """Create an alias for an existing line or cell magic.
97 97
98 98 Examples
99 99 --------
100 100 ::
101 101
102 102 In [1]: %alias_magic t timeit
103 103 Created `%t` as an alias for `%timeit`.
104 104 Created `%%t` as an alias for `%%timeit`.
105 105
106 106 In [2]: %t -n1 pass
107 107 1 loops, best of 3: 954 ns per loop
108 108
109 109 In [3]: %%t -n1
110 110 ...: pass
111 111 ...:
112 112 1 loops, best of 3: 954 ns per loop
113 113
114 114 In [4]: %alias_magic --cell whereami pwd
115 115 UsageError: Cell magic function `%%pwd` not found.
116 116 In [5]: %alias_magic --line whereami pwd
117 117 Created `%whereami` as an alias for `%pwd`.
118 118
119 119 In [6]: %whereami
120 120 Out[6]: u'/home/testuser'
121 121 """
122 122 args = magic_arguments.parse_argstring(self.alias_magic, line)
123 123 shell = self.shell
124 124 mman = self.shell.magics_manager
125 125 escs = ''.join(magic_escapes.values())
126 126
127 127 target = args.target.lstrip(escs)
128 128 name = args.name.lstrip(escs)
129 129
130 130 # Find the requested magics.
131 131 m_line = shell.find_magic(target, 'line')
132 132 m_cell = shell.find_magic(target, 'cell')
133 133 if args.line and m_line is None:
134 134 raise UsageError('Line magic function `%s%s` not found.' %
135 135 (magic_escapes['line'], target))
136 136 if args.cell and m_cell is None:
137 137 raise UsageError('Cell magic function `%s%s` not found.' %
138 138 (magic_escapes['cell'], target))
139 139
140 140 # If --line and --cell are not specified, default to the ones
141 141 # that are available.
142 142 if not args.line and not args.cell:
143 143 if not m_line and not m_cell:
144 144 raise UsageError(
145 145 'No line or cell magic with name `%s` found.' % target
146 146 )
147 147 args.line = bool(m_line)
148 148 args.cell = bool(m_cell)
149 149
150 150 if args.line:
151 151 mman.register_alias(name, target, 'line')
152 152 print('Created `%s%s` as an alias for `%s%s`.' % (
153 153 magic_escapes['line'], name,
154 154 magic_escapes['line'], target))
155 155
156 156 if args.cell:
157 157 mman.register_alias(name, target, 'cell')
158 158 print('Created `%s%s` as an alias for `%s%s`.' % (
159 159 magic_escapes['cell'], name,
160 160 magic_escapes['cell'], target))
161 161
162 162 @line_magic
163 163 def lsmagic(self, parameter_s=''):
164 164 """List currently available magic functions."""
165 165 return MagicsDisplay(self.shell.magics_manager)
166 166
167 167 def _magic_docs(self, brief=False, rest=False):
168 168 """Return docstrings from magic functions."""
169 169 mman = self.shell.magics_manager
170 170 docs = mman.lsmagic_docs(brief, missing='No documentation')
171 171
172 172 if rest:
173 173 format_string = '**%s%s**::\n\n%s\n\n'
174 174 else:
175 175 format_string = '%s%s:\n%s\n'
176 176
177 177 return ''.join(
178 178 [format_string % (magic_escapes['line'], fname,
179 179 indent(dedent(fndoc)))
180 180 for fname, fndoc in sorted(docs['line'].items())]
181 181 +
182 182 [format_string % (magic_escapes['cell'], fname,
183 183 indent(dedent(fndoc)))
184 184 for fname, fndoc in sorted(docs['cell'].items())]
185 185 )
186 186
187 187 @line_magic
188 188 def magic(self, parameter_s=''):
189 189 """Print information about the magic function system.
190 190
191 191 Supported formats: -latex, -brief, -rest
192 192 """
193 193
194 194 mode = ''
195 195 try:
196 196 mode = parameter_s.split()[0][1:]
197 197 except IndexError:
198 198 pass
199 199
200 200 brief = (mode == 'brief')
201 201 rest = (mode == 'rest')
202 202 magic_docs = self._magic_docs(brief, rest)
203 203
204 204 if mode == 'latex':
205 205 print(self.format_latex(magic_docs))
206 206 return
207 207 else:
208 208 magic_docs = format_screen(magic_docs)
209 209
210 210 out = ["""
211 211 IPython's 'magic' functions
212 212 ===========================
213 213
214 214 The magic function system provides a series of functions which allow you to
215 215 control the behavior of IPython itself, plus a lot of system-type
216 216 features. There are two kinds of magics, line-oriented and cell-oriented.
217 217
218 218 Line magics are prefixed with the % character and work much like OS
219 219 command-line calls: they get as an argument the rest of the line, where
220 220 arguments are passed without parentheses or quotes. For example, this will
221 221 time the given statement::
222 222
223 223 %timeit range(1000)
224 224
225 225 Cell magics are prefixed with a double %%, and they are functions that get as
226 226 an argument not only the rest of the line, but also the lines below it in a
227 227 separate argument. These magics are called with two arguments: the rest of the
228 228 call line and the body of the cell, consisting of the lines below the first.
229 229 For example::
230 230
231 231 %%timeit x = numpy.random.randn((100, 100))
232 232 numpy.linalg.svd(x)
233 233
234 234 will time the execution of the numpy svd routine, running the assignment of x
235 235 as part of the setup phase, which is not timed.
236 236
237 237 In a line-oriented client (the terminal or Qt console IPython), starting a new
238 238 input with %% will automatically enter cell mode, and IPython will continue
239 239 reading input until a blank line is given. In the notebook, simply type the
240 240 whole cell as one entity, but keep in mind that the %% escape can only be at
241 241 the very start of the cell.
242 242
243 243 NOTE: If you have 'automagic' enabled (via the command line option or with the
244 244 %automagic function), you don't need to type in the % explicitly for line
245 245 magics; cell magics always require an explicit '%%' escape. By default,
246 246 IPython ships with automagic on, so you should only rarely need the % escape.
247 247
248 248 Example: typing '%cd mydir' (without the quotes) changes your working directory
249 249 to 'mydir', if it exists.
250 250
251 251 For a list of the available magic functions, use %lsmagic. For a description
252 252 of any of them, type %magic_name?, e.g. '%cd?'.
253 253
254 254 Currently the magic system has the following functions:""",
255 255 magic_docs,
256 256 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
257 257 str(self.lsmagic()),
258 258 ]
259 259 page.page('\n'.join(out))
260 260
261 261
262 262 @line_magic
263 263 def page(self, parameter_s=''):
264 264 """Pretty print the object and display it through a pager.
265 265
266 266 %page [options] OBJECT
267 267
268 268 If no object is given, use _ (last output).
269 269
270 270 Options:
271 271
272 272 -r: page str(object), don't pretty-print it."""
273 273
274 274 # After a function contributed by Olivier Aubert, slightly modified.
275 275
276 276 # Process options/args
277 277 opts, args = self.parse_options(parameter_s, 'r')
278 278 raw = 'r' in opts
279 279
280 280 oname = args and args or '_'
281 281 info = self.shell._ofind(oname)
282 282 if info['found']:
283 283 txt = (raw and str or pformat)( info['obj'] )
284 284 page.page(txt)
285 285 else:
286 286 print('Object `%s` not found' % oname)
287 287
288 288 @line_magic
289 289 def profile(self, parameter_s=''):
290 290 """Print your currently active IPython profile.
291 291
292 292 See Also
293 293 --------
294 294 prun : run code using the Python profiler
295 295 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
296 296 """
297 297 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
298 298 from IPython.core.application import BaseIPythonApplication
299 299 if BaseIPythonApplication.initialized():
300 300 print(BaseIPythonApplication.instance().profile)
301 301 else:
302 302 error("profile is an application-level value, but you don't appear to be in an IPython application")
303 303
304 304 @line_magic
305 305 def pprint(self, parameter_s=''):
306 306 """Toggle pretty printing on/off."""
307 307 ptformatter = self.shell.display_formatter.formatters['text/plain']
308 308 ptformatter.pprint = bool(1 - ptformatter.pprint)
309 309 print('Pretty printing has been turned',
310 310 ['OFF','ON'][ptformatter.pprint])
311 311
312 312 @line_magic
313 313 def colors(self, parameter_s=''):
314 314 """Switch color scheme for prompts, info system and exception handlers.
315 315
316 316 Currently implemented schemes: NoColor, Linux, LightBG.
317 317
318 318 Color scheme names are not case-sensitive.
319 319
320 320 Examples
321 321 --------
322 322 To get a plain black and white terminal::
323 323
324 324 %colors nocolor
325 325 """
326 326 def color_switch_err(name):
327 327 warn('Error changing %s color schemes.\n%s' %
328 328 (name, sys.exc_info()[1]))
329 329
330 330
331 331 new_scheme = parameter_s.strip()
332 332 if not new_scheme:
333 333 raise UsageError(
334 334 "%colors: you must specify a color scheme. See '%colors?'")
335 335 # local shortcut
336 336 shell = self.shell
337 337
338
339
340 if not shell.colors_force:
341 if sys.platform in {'win32', 'cli'}:
342 import IPython.utils.rlineimpl as readline
343 if not readline.have_readline:
344 msg = """\
345 Proper color support under MS Windows requires the pyreadline library.
346 You can find it at:
347 http://ipython.org/pyreadline.html
348
349 Defaulting color scheme to 'NoColor'"""
350 new_scheme = 'NoColor'
351 warn(msg)
352
353 elif not shell.has_readline:
354 # Coloured prompts get messed up without readline
355 # Will remove this check after switching to prompt_toolkit
356 new_scheme = 'NoColor'
338 # Set shell colour scheme
339 try:
340 shell.colors = new_scheme
341 shell.refresh_style()
342 except:
343 color_switch_err('shell')
357 344
358 345 # Set exception colors
359 346 try:
360 347 shell.InteractiveTB.set_colors(scheme = new_scheme)
361 shell.colors = new_scheme
362 shell.refresh_style()
363 348 shell.SyntaxTB.set_colors(scheme = new_scheme)
364 349 except:
365 350 color_switch_err('exception')
366 351
367 352 # Set info (for 'object?') colors
368 353 if shell.color_info:
369 354 try:
370 355 shell.inspector.set_active_scheme(new_scheme)
371 356 except:
372 357 color_switch_err('object inspector')
373 358 else:
374 359 shell.inspector.set_active_scheme('NoColor')
375 360
376 361 @line_magic
377 362 def xmode(self, parameter_s=''):
378 363 """Switch modes for the exception handlers.
379 364
380 365 Valid modes: Plain, Context and Verbose.
381 366
382 367 If called without arguments, acts as a toggle."""
383 368
384 369 def xmode_switch_err(name):
385 370 warn('Error changing %s exception modes.\n%s' %
386 371 (name,sys.exc_info()[1]))
387 372
388 373 shell = self.shell
389 374 new_mode = parameter_s.strip().capitalize()
390 375 try:
391 376 shell.InteractiveTB.set_mode(mode=new_mode)
392 377 print('Exception reporting mode:',shell.InteractiveTB.mode)
393 378 except:
394 379 xmode_switch_err('user')
395 380
396 381 @line_magic
397 382 def quickref(self,arg):
398 383 """ Show a quick reference sheet """
399 384 from IPython.core.usage import quick_reference
400 385 qr = quick_reference + self._magic_docs(brief=True)
401 386 page.page(qr)
402 387
403 388 @line_magic
404 389 def doctest_mode(self, parameter_s=''):
405 390 """Toggle doctest mode on and off.
406 391
407 392 This mode is intended to make IPython behave as much as possible like a
408 393 plain Python shell, from the perspective of how its prompts, exceptions
409 394 and output look. This makes it easy to copy and paste parts of a
410 395 session into doctests. It does so by:
411 396
412 397 - Changing the prompts to the classic ``>>>`` ones.
413 398 - Changing the exception reporting mode to 'Plain'.
414 399 - Disabling pretty-printing of output.
415 400
416 401 Note that IPython also supports the pasting of code snippets that have
417 402 leading '>>>' and '...' prompts in them. This means that you can paste
418 403 doctests from files or docstrings (even if they have leading
419 404 whitespace), and the code will execute correctly. You can then use
420 405 '%history -t' to see the translated history; this will give you the
421 406 input after removal of all the leading prompts and whitespace, which
422 407 can be pasted back into an editor.
423 408
424 409 With these features, you can switch into this mode easily whenever you
425 410 need to do testing and changes to doctests, without having to leave
426 411 your existing IPython session.
427 412 """
428 413
429 414 # Shorthands
430 415 shell = self.shell
431 416 meta = shell.meta
432 417 disp_formatter = self.shell.display_formatter
433 418 ptformatter = disp_formatter.formatters['text/plain']
434 419 # dstore is a data store kept in the instance metadata bag to track any
435 420 # changes we make, so we can undo them later.
436 421 dstore = meta.setdefault('doctest_mode',Struct())
437 422 save_dstore = dstore.setdefault
438 423
439 424 # save a few values we'll need to recover later
440 425 mode = save_dstore('mode',False)
441 426 save_dstore('rc_pprint',ptformatter.pprint)
442 427 save_dstore('xmode',shell.InteractiveTB.mode)
443 428 save_dstore('rc_separate_out',shell.separate_out)
444 429 save_dstore('rc_separate_out2',shell.separate_out2)
445 430 save_dstore('rc_separate_in',shell.separate_in)
446 431 save_dstore('rc_active_types',disp_formatter.active_types)
447 432
448 433 if not mode:
449 434 # turn on
450 435
451 436 # Prompt separators like plain python
452 437 shell.separate_in = ''
453 438 shell.separate_out = ''
454 439 shell.separate_out2 = ''
455 440
456 441
457 442 ptformatter.pprint = False
458 443 disp_formatter.active_types = ['text/plain']
459 444
460 445 shell.magic('xmode Plain')
461 446 else:
462 447 # turn off
463 448 shell.separate_in = dstore.rc_separate_in
464 449
465 450 shell.separate_out = dstore.rc_separate_out
466 451 shell.separate_out2 = dstore.rc_separate_out2
467 452
468 453 ptformatter.pprint = dstore.rc_pprint
469 454 disp_formatter.active_types = dstore.rc_active_types
470 455
471 456 shell.magic('xmode ' + dstore.xmode)
472 457
473 458 # mode here is the state before we switch; switch_doctest_mode takes
474 459 # the mode we're switching to.
475 460 shell.switch_doctest_mode(not mode)
476 461
477 462 # Store new mode and inform
478 463 dstore.mode = bool(not mode)
479 464 mode_label = ['OFF','ON'][dstore.mode]
480 465 print('Doctest mode is:', mode_label)
481 466
482 467 @line_magic
483 468 def gui(self, parameter_s=''):
484 469 """Enable or disable IPython GUI event loop integration.
485 470
486 471 %gui [GUINAME]
487 472
488 473 This magic replaces IPython's threaded shells that were activated
489 474 using the (pylab/wthread/etc.) command line flags. GUI toolkits
490 475 can now be enabled at runtime and keyboard
491 476 interrupts should work without any problems. The following toolkits
492 477 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
493 478
494 479 %gui wx # enable wxPython event loop integration
495 480 %gui qt4|qt # enable PyQt4 event loop integration
496 481 %gui qt5 # enable PyQt5 event loop integration
497 482 %gui gtk # enable PyGTK event loop integration
498 483 %gui gtk3 # enable Gtk3 event loop integration
499 484 %gui tk # enable Tk event loop integration
500 485 %gui osx # enable Cocoa event loop integration
501 486 # (requires %matplotlib 1.1)
502 487 %gui # disable all event loop integration
503 488
504 489 WARNING: after any of these has been called you can simply create
505 490 an application object, but DO NOT start the event loop yourself, as
506 491 we have already handled that.
507 492 """
508 493 opts, arg = self.parse_options(parameter_s, '')
509 494 if arg=='': arg = None
510 495 try:
511 496 return self.shell.enable_gui(arg)
512 497 except Exception as e:
513 498 # print simple error message, rather than traceback if we can't
514 499 # hook up the GUI
515 500 error(str(e))
516 501
517 502 @skip_doctest
518 503 @line_magic
519 504 def precision(self, s=''):
520 505 """Set floating point precision for pretty printing.
521 506
522 507 Can set either integer precision or a format string.
523 508
524 509 If numpy has been imported and precision is an int,
525 510 numpy display precision will also be set, via ``numpy.set_printoptions``.
526 511
527 512 If no argument is given, defaults will be restored.
528 513
529 514 Examples
530 515 --------
531 516 ::
532 517
533 518 In [1]: from math import pi
534 519
535 520 In [2]: %precision 3
536 521 Out[2]: u'%.3f'
537 522
538 523 In [3]: pi
539 524 Out[3]: 3.142
540 525
541 526 In [4]: %precision %i
542 527 Out[4]: u'%i'
543 528
544 529 In [5]: pi
545 530 Out[5]: 3
546 531
547 532 In [6]: %precision %e
548 533 Out[6]: u'%e'
549 534
550 535 In [7]: pi**10
551 536 Out[7]: 9.364805e+04
552 537
553 538 In [8]: %precision
554 539 Out[8]: u'%r'
555 540
556 541 In [9]: pi**10
557 542 Out[9]: 93648.047476082982
558 543 """
559 544 ptformatter = self.shell.display_formatter.formatters['text/plain']
560 545 ptformatter.float_precision = s
561 546 return ptformatter.float_format
562 547
563 548 @magic_arguments.magic_arguments()
564 549 @magic_arguments.argument(
565 550 '-e', '--export', action='store_true', default=False,
566 551 help='Export IPython history as a notebook. The filename argument '
567 552 'is used to specify the notebook name and format. For example '
568 553 'a filename of notebook.ipynb will result in a notebook name '
569 554 'of "notebook" and a format of "json". Likewise using a ".py" '
570 555 'file extension will write the notebook as a Python script'
571 556 )
572 557 @magic_arguments.argument(
573 558 'filename', type=unicode_type,
574 559 help='Notebook name or filename'
575 560 )
576 561 @line_magic
577 562 def notebook(self, s):
578 563 """Export and convert IPython notebooks.
579 564
580 565 This function can export the current IPython history to a notebook file.
581 566 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
582 567 To export the history to "foo.py" do "%notebook -e foo.py".
583 568 """
584 569 args = magic_arguments.parse_argstring(self.notebook, s)
585 570
586 571 from nbformat import write, v4
587 572 if args.export:
588 573 cells = []
589 574 hist = list(self.shell.history_manager.get_range())
590 575 if(len(hist)<=1):
591 576 raise ValueError('History is empty, cannot export')
592 577 for session, execution_count, source in hist[:-1]:
593 578 cells.append(v4.new_code_cell(
594 579 execution_count=execution_count,
595 580 source=source
596 581 ))
597 582 nb = v4.new_notebook(cells=cells)
598 583 with io.open(args.filename, 'w', encoding='utf-8') as f:
599 584 write(nb, f, version=4)
@@ -1,571 +1,569 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2 from __future__ import print_function
3 3
4 4 import os
5 5 import sys
6 6 import signal
7 7 from warnings import warn
8 8
9 9 from IPython.core.error import TryNext
10 10 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
11 11 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
12 12 from IPython.utils.terminal import toggle_set_term_title, set_term_title
13 13 from IPython.utils.process import abbrev_cwd
14 14 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum
15 15
16 16 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode
17 17 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
18 18 ViInsertMode, EmacsInsertMode, IsDone, HasCompletions)
19 19 from prompt_toolkit.filters.cli import ViMode
20 20 from prompt_toolkit.history import InMemoryHistory
21 21 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
22 22 from prompt_toolkit.interface import CommandLineInterface
23 23 from prompt_toolkit.key_binding.manager import KeyBindingManager
24 24 from prompt_toolkit.keys import Keys
25 25 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
26 26 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
27 27 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
28 28
29 29 from pygments.styles import get_style_by_name, get_all_styles
30 30 from pygments.token import Token
31 31
32 32 from .debugger import TerminalPdb, Pdb
33 33 from .magics import TerminalMagics
34 34 from .pt_inputhooks import get_inputhook_func
35 35 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
36 36 from .ptutils import IPythonPTCompleter, IPythonPTLexer
37 37
38 38 DISPLAY_BANNER_DEPRECATED = object()
39 39
40 40
41 41 from pygments.style import Style
42 42
43 43 class _NoStyle(Style): pass
44 44
45 45
46 46
47 47 _style_overrides_light_bg = {
48 48 Token.Prompt: '#0000ff',
49 49 Token.PromptNum: '#0000ee bold',
50 50 Token.OutPrompt: '#cc0000',
51 51 Token.OutPromptNum: '#bb0000 bold',
52 52 }
53 53
54 54 _style_overrides_linux = {
55 55 Token.Prompt: '#00cc00',
56 56 Token.PromptNum: '#00bb00 bold',
57 57 Token.OutPrompt: '#cc0000',
58 58 Token.OutPromptNum: '#bb0000 bold',
59 59 }
60 60
61 61
62 62
63 63 def get_default_editor():
64 64 try:
65 65 ed = os.environ['EDITOR']
66 66 if not PY3:
67 67 ed = ed.decode()
68 68 return ed
69 69 except KeyError:
70 70 pass
71 71 except UnicodeError:
72 72 warn("$EDITOR environment variable is not pure ASCII. Using platform "
73 73 "default editor.")
74 74
75 75 if os.name == 'posix':
76 76 return 'vi' # the only one guaranteed to be there!
77 77 else:
78 78 return 'notepad' # same in Windows!
79 79
80 80
81 81 if sys.stdin and sys.stdout and sys.stderr:
82 82 _is_tty = (sys.stdin.isatty()) and (sys.stdout.isatty()) and (sys.stderr.isatty())
83 83 else:
84 84 _is_tty = False
85 85
86 86
87 87 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
88 88
89 89 class TerminalInteractiveShell(InteractiveShell):
90 colors_force = True
91
92 90 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
93 91 'to reserve for the completion menu'
94 92 ).tag(config=True)
95 93
96 94 def _space_for_menu_changed(self, old, new):
97 95 self._update_layout()
98 96
99 97 pt_cli = None
100 98 debugger_history = None
101 99
102 100 simple_prompt = Bool(_use_simple_prompt,
103 101 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
104 102
105 103 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
106 104 IPython own testing machinery, and emacs inferior-shell integration through elpy.
107 105
108 106 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
109 107 environment variable is set, or the current terminal is not a tty.
110 108
111 109 """
112 110 ).tag(config=True)
113 111
114 112 @property
115 113 def debugger_cls(self):
116 114 return Pdb if self.simple_prompt else TerminalPdb
117 115
118 116 confirm_exit = Bool(True,
119 117 help="""
120 118 Set to confirm when you try to exit IPython with an EOF (Control-D
121 119 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
122 120 you can force a direct exit without any confirmation.""",
123 121 ).tag(config=True)
124 122
125 123 editing_mode = Unicode('emacs',
126 124 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
127 125 ).tag(config=True)
128 126
129 127 mouse_support = Bool(False,
130 128 help="Enable mouse support in the prompt"
131 129 ).tag(config=True)
132 130
133 131 highlighting_style = Unicode('legacy',
134 132 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
135 133 ).tag(config=True)
136 134
137 135
138 136 @observe('highlighting_style')
139 137 @observe('colors')
140 138 def _highlighting_style_changed(self, change):
141 139 self.refresh_style()
142 140
143 141 def refresh_style(self):
144 142 self._style = self._make_style_from_name(self.highlighting_style)
145 143
146 144
147 145 highlighting_style_overrides = Dict(
148 146 help="Override highlighting format for specific tokens"
149 147 ).tag(config=True)
150 148
151 149 editor = Unicode(get_default_editor(),
152 150 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
153 151 ).tag(config=True)
154 152
155 153 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
156 154
157 155 prompts = Instance(Prompts)
158 156
159 157 @default('prompts')
160 158 def _prompts_default(self):
161 159 return self.prompts_class(self)
162 160
163 161 @observe('prompts')
164 162 def _(self, change):
165 163 self._update_layout()
166 164
167 165 @default('displayhook_class')
168 166 def _displayhook_class_default(self):
169 167 return RichPromptDisplayHook
170 168
171 169 term_title = Bool(True,
172 170 help="Automatically set the terminal title"
173 171 ).tag(config=True)
174 172
175 173 # Leaving that for beta/rc tester, shoudl remove for 5.0.0 final.
176 174 display_completions_in_columns = Bool(None,
177 175 help="DEPRECATED", allow_none=True
178 176 ).tag(config=True)
179 177
180 178 @observe('display_completions_in_columns')
181 179 def _display_completions_in_columns_changed(self, new):
182 180 raise DeprecationWarning("The `display_completions_in_columns` Boolean has been replaced by the enum `display_completions`"
183 181 "with the following acceptable value: 'column', 'multicolumn','readlinelike'. ")
184 182
185 183 display_completions = Enum(('column', 'multicolumn','readlinelike'), default_value='multicolumn').tag(config=True)
186 184
187 185 highlight_matching_brackets = Bool(True,
188 186 help="Highlight matching brackets .",
189 187 ).tag(config=True)
190 188
191 189 @observe('term_title')
192 190 def init_term_title(self, change=None):
193 191 # Enable or disable the terminal title.
194 192 if self.term_title:
195 193 toggle_set_term_title(True)
196 194 set_term_title('IPython: ' + abbrev_cwd())
197 195 else:
198 196 toggle_set_term_title(False)
199 197
200 198 def init_display_formatter(self):
201 199 super(TerminalInteractiveShell, self).init_display_formatter()
202 200 # terminal only supports plain text
203 201 self.display_formatter.active_types = ['text/plain']
204 202
205 203 def init_prompt_toolkit_cli(self):
206 204 self._app = None
207 205 if self.simple_prompt:
208 206 # Fall back to plain non-interactive output for tests.
209 207 # This is very limited, and only accepts a single line.
210 208 def prompt():
211 209 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
212 210 self.prompt_for_code = prompt
213 211 return
214 212
215 213 kbmanager = KeyBindingManager.for_prompt()
216 214 insert_mode = ViInsertMode() | EmacsInsertMode()
217 215 # Ctrl+J == Enter, seemingly
218 216 @kbmanager.registry.add_binding(Keys.ControlJ,
219 217 filter=(HasFocus(DEFAULT_BUFFER)
220 218 & ~HasSelection()
221 219 & insert_mode
222 220 ))
223 221 def _(event):
224 222 b = event.current_buffer
225 223 d = b.document
226 224
227 225 if b.complete_state:
228 226 cc = b.complete_state.current_completion
229 227 if cc:
230 228 b.apply_completion(cc)
231 229 else:
232 230 b.cancel_completion()
233 231 return
234 232
235 233 if not (d.on_last_line or d.cursor_position_row >= d.line_count
236 234 - d.empty_line_count_at_the_end()):
237 235 b.newline()
238 236 return
239 237
240 238 status, indent = self.input_splitter.check_complete(d.text + '\n')
241 239
242 240 if (status != 'incomplete') and b.accept_action.is_returnable:
243 241 b.accept_action.validate_and_handle(event.cli, b)
244 242 else:
245 243 b.insert_text('\n' + (' ' * (indent or 0)))
246 244
247 245 @kbmanager.registry.add_binding(Keys.ControlP, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)))
248 246 def _previous_history_or_previous_completion(event):
249 247 """
250 248 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
251 249
252 250 If completer is open this still select previous completion.
253 251 """
254 252 event.current_buffer.auto_up()
255 253
256 254 @kbmanager.registry.add_binding(Keys.ControlN, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)))
257 255 def _next_history_or_next_completion(event):
258 256 """
259 257 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
260 258
261 259 If completer is open this still select next completion.
262 260 """
263 261 event.current_buffer.auto_down()
264 262
265 263 @kbmanager.registry.add_binding(Keys.ControlG, filter=(
266 264 HasFocus(DEFAULT_BUFFER) & HasCompletions()
267 265 ))
268 266 def _dismiss_completion(event):
269 267 b = event.current_buffer
270 268 if b.complete_state:
271 269 b.cancel_completion()
272 270
273 271 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
274 272 def _reset_buffer(event):
275 273 b = event.current_buffer
276 274 if b.complete_state:
277 275 b.cancel_completion()
278 276 else:
279 277 b.reset()
280 278
281 279 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
282 280 def _reset_search_buffer(event):
283 281 if event.current_buffer.document.text:
284 282 event.current_buffer.reset()
285 283 else:
286 284 event.cli.push_focus(DEFAULT_BUFFER)
287 285
288 286 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
289 287
290 288 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
291 289 def _suspend_to_bg(event):
292 290 event.cli.suspend_to_background()
293 291
294 292 @Condition
295 293 def cursor_in_leading_ws(cli):
296 294 before = cli.application.buffer.document.current_line_before_cursor
297 295 return (not before) or before.isspace()
298 296
299 297 # Ctrl+I == Tab
300 298 @kbmanager.registry.add_binding(Keys.ControlI,
301 299 filter=(HasFocus(DEFAULT_BUFFER)
302 300 & ~HasSelection()
303 301 & insert_mode
304 302 & cursor_in_leading_ws
305 303 ))
306 304 def _indent_buffer(event):
307 305 event.current_buffer.insert_text(' ' * 4)
308 306
309 307
310 308 if self.display_completions == 'readlinelike':
311 309 @kbmanager.registry.add_binding(Keys.ControlI,
312 310 filter=(HasFocus(DEFAULT_BUFFER)
313 311 & ~HasSelection()
314 312 & insert_mode
315 313 & ~cursor_in_leading_ws
316 314 ))
317 315 def _disaply_compl(ev):
318 316 display_completions_like_readline(ev)
319 317
320 318
321 319 if sys.platform == 'win32':
322 320 from IPython.lib.clipboard import (ClipboardEmpty,
323 321 win32_clipboard_get, tkinter_clipboard_get)
324 322 @kbmanager.registry.add_binding(Keys.ControlV,
325 323 filter=(HasFocus(DEFAULT_BUFFER) & ~ViMode()))
326 324 def _paste(event):
327 325 try:
328 326 text = win32_clipboard_get()
329 327 except TryNext:
330 328 try:
331 329 text = tkinter_clipboard_get()
332 330 except (TryNext, ClipboardEmpty):
333 331 return
334 332 except ClipboardEmpty:
335 333 return
336 334 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
337 335
338 336 # Pre-populate history from IPython's history database
339 337 history = InMemoryHistory()
340 338 last_cell = u""
341 339 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
342 340 include_latest=True):
343 341 # Ignore blank lines and consecutive duplicates
344 342 cell = cell.rstrip()
345 343 if cell and (cell != last_cell):
346 344 history.append(cell)
347 345
348 346 self._style = self._make_style_from_name(self.highlighting_style)
349 347 style = DynamicStyle(lambda: self._style)
350 348
351 349 editing_mode = getattr(EditingMode, self.editing_mode.upper())
352 350
353 351 self._app = create_prompt_application(
354 352 editing_mode=editing_mode,
355 353 key_bindings_registry=kbmanager.registry,
356 354 history=history,
357 355 completer=IPythonPTCompleter(self.Completer),
358 356 enable_history_search=True,
359 357 style=style,
360 358 mouse_support=self.mouse_support,
361 359 **self._layout_options()
362 360 )
363 361 self._eventloop = create_eventloop(self.inputhook)
364 362 self.pt_cli = CommandLineInterface(self._app, eventloop=self._eventloop)
365 363
366 364 def _make_style_from_name(self, name):
367 365 """
368 366 Small wrapper that make an IPython compatible style from a style name
369 367
370 368 We need that to add style for prompt ... etc.
371 369 """
372 370 if name == 'legacy':
373 371 legacy = self.colors.lower()
374 372 if legacy == 'linux':
375 373 style_cls = get_style_by_name('monokai')
376 374 style_overrides = _style_overrides_linux
377 375 elif legacy == 'lightbg':
378 376 style_overrides = _style_overrides_light_bg
379 377 style_cls = get_style_by_name('default')
380 378 # The default theme needs to be visible on both a dark background
381 379 # and a light background, because we can't tell what the terminal
382 380 # looks like. These tweaks to the default theme help with that.
383 381 style_overrides.update({
384 382 Token.Number: '#007700',
385 383 Token.Operator: 'noinherit',
386 384 Token.String: '#BB6622',
387 385 Token.Name.Function: '#2080D0',
388 386 Token.Name.Class: 'bold #2080D0',
389 387 Token.Name.Namespace: 'bold #2080D0',
390 388 })
391 389 elif legacy =='nocolor':
392 390 style_cls=_NoStyle
393 391 style_overrides = {}
394 392 else :
395 393 raise ValueError('Got unknown colors: ', legacy)
396 394 else :
397 395 style_cls = get_style_by_name(name)
398 396 style_overrides = {
399 397 Token.Prompt: '#009900',
400 398 Token.PromptNum: '#00ff00 bold',
401 399 Token.OutPrompt: '#990000',
402 400 Token.OutPromptNum: '#ff0000 bold',
403 401 }
404 402 style_overrides.update(self.highlighting_style_overrides)
405 403 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
406 404 style_dict=style_overrides)
407 405
408 406 return style
409 407
410 408 def _layout_options(self):
411 409 """
412 410 Return the current layout option for the current Terminal InteractiveShell
413 411 """
414 412 return {
415 413 'lexer':IPythonPTLexer(),
416 414 'reserve_space_for_menu':self.space_for_menu,
417 415 'get_prompt_tokens':self.prompts.in_prompt_tokens,
418 416 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
419 417 'multiline':True,
420 418 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
421 419
422 420 # Highlight matching brackets, but only when this setting is
423 421 # enabled, and only when the DEFAULT_BUFFER has the focus.
424 422 'extra_input_processors': [ConditionalProcessor(
425 423 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
426 424 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
427 425 Condition(lambda cli: self.highlight_matching_brackets))],
428 426 }
429 427
430 428 def _update_layout(self):
431 429 """
432 430 Ask for a re computation of the application layout, if for example ,
433 431 some configuration options have changed.
434 432 """
435 433 if getattr(self, '._app', None):
436 434 self._app.layout = create_prompt_layout(**self._layout_options())
437 435
438 436 def prompt_for_code(self):
439 437 document = self.pt_cli.run(
440 438 pre_run=self.pre_prompt, reset_current_buffer=True)
441 439 return document.text
442 440
443 441 def init_io(self):
444 442 if sys.platform not in {'win32', 'cli'}:
445 443 return
446 444
447 445 import win_unicode_console
448 446 import colorama
449 447
450 448 win_unicode_console.enable()
451 449 colorama.init()
452 450
453 451 # For some reason we make these wrappers around stdout/stderr.
454 452 # For now, we need to reset them so all output gets coloured.
455 453 # https://github.com/ipython/ipython/issues/8669
456 454 from IPython.utils import io
457 455 io.stdout = io.IOStream(sys.stdout)
458 456 io.stderr = io.IOStream(sys.stderr)
459 457
460 458 def init_magics(self):
461 459 super(TerminalInteractiveShell, self).init_magics()
462 460 self.register_magics(TerminalMagics)
463 461
464 462 def init_alias(self):
465 463 # The parent class defines aliases that can be safely used with any
466 464 # frontend.
467 465 super(TerminalInteractiveShell, self).init_alias()
468 466
469 467 # Now define aliases that only make sense on the terminal, because they
470 468 # need direct access to the console in a way that we can't emulate in
471 469 # GUI or web frontend
472 470 if os.name == 'posix':
473 471 for cmd in ['clear', 'more', 'less', 'man']:
474 472 self.alias_manager.soft_define_alias(cmd, cmd)
475 473
476 474
477 475 def __init__(self, *args, **kwargs):
478 476 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
479 477 self.init_prompt_toolkit_cli()
480 478 self.init_term_title()
481 479 self.keep_running = True
482 480
483 481 self.debugger_history = InMemoryHistory()
484 482
485 483 def ask_exit(self):
486 484 self.keep_running = False
487 485
488 486 rl_next_input = None
489 487
490 488 def pre_prompt(self):
491 489 if self.rl_next_input:
492 490 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
493 491 self.rl_next_input = None
494 492
495 493 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
496 494
497 495 if display_banner is not DISPLAY_BANNER_DEPRECATED:
498 496 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
499 497
500 498 while self.keep_running:
501 499 print(self.separate_in, end='')
502 500
503 501 try:
504 502 code = self.prompt_for_code()
505 503 except EOFError:
506 504 if (not self.confirm_exit) \
507 505 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
508 506 self.ask_exit()
509 507
510 508 else:
511 509 if code:
512 510 self.run_cell(code, store_history=True)
513 511
514 512 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
515 513 # An extra layer of protection in case someone mashing Ctrl-C breaks
516 514 # out of our internal code.
517 515 if display_banner is not DISPLAY_BANNER_DEPRECATED:
518 516 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
519 517 while True:
520 518 try:
521 519 self.interact()
522 520 break
523 521 except KeyboardInterrupt:
524 522 print("\nKeyboardInterrupt escaped interact()\n")
525 523
526 524 if hasattr(self, '_eventloop'):
527 525 self._eventloop.close()
528 526
529 527 _inputhook = None
530 528 def inputhook(self, context):
531 529 if self._inputhook is not None:
532 530 self._inputhook(context)
533 531
534 532 def enable_gui(self, gui=None):
535 533 if gui:
536 534 self._inputhook = get_inputhook_func(gui)
537 535 else:
538 536 self._inputhook = None
539 537
540 538 # Run !system commands directly, not through pipes, so terminal programs
541 539 # work correctly.
542 540 system = InteractiveShell.system_raw
543 541
544 542 def auto_rewrite_input(self, cmd):
545 543 """Overridden from the parent class to use fancy rewriting prompt"""
546 544 if not self.show_rewritten_input:
547 545 return
548 546
549 547 tokens = self.prompts.rewrite_prompt_tokens()
550 548 if self.pt_cli:
551 549 self.pt_cli.print_tokens(tokens)
552 550 print(cmd)
553 551 else:
554 552 prompt = ''.join(s for t, s in tokens)
555 553 print(prompt, cmd, sep='')
556 554
557 555 _prompts_before = None
558 556 def switch_doctest_mode(self, mode):
559 557 """Switch prompts to classic for %doctest_mode"""
560 558 if mode:
561 559 self._prompts_before = self.prompts
562 560 self.prompts = ClassicPrompts(self)
563 561 elif self._prompts_before:
564 562 self.prompts = self._prompts_before
565 563 self._prompts_before = None
566 564
567 565
568 566 InteractiveShellABC.register(TerminalInteractiveShell)
569 567
570 568 if __name__ == '__main__':
571 569 TerminalInteractiveShell.instance().interact()
General Comments 0
You need to be logged in to leave comments. Login now