##// END OF EJS Templates
Merge pull request #12315 from Carreau/de54...
Merge pull request #12315 from Carreau/de54 Reenable non-text formatter on terminal.

File last commit:

r27291:85c1753b
r27367:cfd87c42 merge
Show More
magics.py
214 lines | 7.5 KiB | text/x-python | PythonLexer
Thomas Kluyver
Remove the readline shell machinery...
r22436 """Extra magics for terminal use."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from logging import error
import os
import sys
from IPython.core.error import TryNext, UsageError
from IPython.core.magic import Magics, magics_class, line_magic
from IPython.lib.clipboard import ClipboardEmpty
Nikita Kniazev
Preserve function/method identity in magic decorators...
r27102 from IPython.testing.skipdoctest import skip_doctest
Thomas Kluyver
Remove the readline shell machinery...
r22436 from IPython.utils.text import SList, strip_email_quotes
from IPython.utils import py3compat
def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
""" Yield pasted lines until the user enters the given sentinel value.
"""
if not quiet:
print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
% sentinel)
prompt = ":"
else:
prompt = ""
while True:
try:
Srinivas Reddy Thatiparthy
remove redundant function call
r23053 l = l_input(prompt)
Thomas Kluyver
Remove the readline shell machinery...
r22436 if l == sentinel:
return
else:
yield l
except EOFError:
print('<EOF>')
return
@magics_class
class TerminalMagics(Magics):
def __init__(self, shell):
super(TerminalMagics, self).__init__(shell)
def store_or_execute(self, block, name):
""" Execute a block, or store it in a variable, per the user's request.
"""
if name:
# If storing it for further editing
self.shell.user_ns[name] = SList(block.splitlines())
print("Block assigned to '%s'" % name)
else:
b = self.preclean_input(block)
self.shell.user_ns['pasted_block'] = b
self.shell.using_paste_magics = True
try:
self.shell.run_cell(b)
finally:
self.shell.using_paste_magics = False
def preclean_input(self, block):
lines = block.splitlines()
while lines and not lines[0].strip():
lines = lines[1:]
return strip_email_quotes('\n'.join(lines))
def rerun_pasted(self, name='pasted_block'):
""" Rerun a previously pasted command.
"""
b = self.shell.user_ns.get(name)
# Sanity checks
if b is None:
raise UsageError('No previous pasted block available')
Srinivas Reddy Thatiparthy
convert string_types to str
r23037 if not isinstance(b, str):
Thomas Kluyver
Remove the readline shell machinery...
r22436 raise UsageError(
"Variable 'pasted_block' is not a string, can't execute")
print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
self.shell.run_cell(b)
@line_magic
def autoindent(self, parameter_s = ''):
Thomas Kluyver
Deprecate %autoindent...
r23209 """Toggle autoindent on/off (deprecated)"""
Thomas Kluyver
Remove the readline shell machinery...
r22436 self.shell.set_autoindent()
print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
Nikita Kniazev
Preserve function/method identity in magic decorators...
r27102 @skip_doctest
Thomas Kluyver
Remove the readline shell machinery...
r22436 @line_magic
def cpaste(self, parameter_s=''):
"""Paste & execute a pre-formatted code block from clipboard.
You must terminate the block with '--' (two minus-signs) or Ctrl-D
alone on the line. You can also provide your own sentinel with '%paste
-s %%' ('%%' is the new sentinel for this operation).
The block is dedented prior to execution to enable execution of method
definitions. '>' and '+' characters at the beginning of a line are
ignored, to allow pasting directly from e-mails, diff files and
doctests (the '...' continuation prompt is also stripped). The
executed block is also assigned to variable named 'pasted_block' for
later editing with '%edit pasted_block'.
You can also pass a variable name as an argument, e.g. '%cpaste foo'.
This assigns the pasted block to variable 'foo' as string, without
dedenting or executing it (preceding >>> and + is still stripped)
'%cpaste -r' re-executes the block previously entered by cpaste.
'%cpaste -q' suppresses any additional output messages.
Do not be alarmed by garbled output on Windows (it's a readline bug).
Just press enter and type -- (and press enter again) and the block
will be what was just pasted.
Samuel Gaist
Fix cpaste documentation...
r26821 Shell escapes are not supported (yet).
Thomas Kluyver
Remove the readline shell machinery...
r22436
Matthias Bussonnier
reformat terminal
r27291 See Also
Thomas Kluyver
Remove the readline shell machinery...
r22436 --------
Matthias Bussonnier
reformat terminal
r27291 paste : automatically pull code from clipboard.
Thomas Kluyver
Remove the readline shell machinery...
r22436
Examples
--------
::
In [8]: %cpaste
Pasting code; enter '--' alone on the line to stop.
:>>> a = ["world!", "Hello"]
Samuel Gaist
Fix cpaste documentation...
r26821 :>>> print(" ".join(sorted(a)))
Thomas Kluyver
Remove the readline shell machinery...
r22436 :--
Hello world!
Samuel Gaist
Fix cpaste documentation...
r26821
::
In [8]: %cpaste
Pasting code; enter '--' alone on the line to stop.
:>>> %alias_magic t timeit
:>>> %t -n1 pass
:--
Created `%t` as an alias for `%timeit`.
Created `%%t` as an alias for `%%timeit`.
354 ns ± 224 ns per loop (mean ± std. dev. of 7 runs, 1 loop each)
Thomas Kluyver
Remove the readline shell machinery...
r22436 """
opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
if 'r' in opts:
self.rerun_pasted()
return
quiet = ('q' in opts)
sentinel = opts.get('s', u'--')
block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
self.store_or_execute(block, name)
@line_magic
def paste(self, parameter_s=''):
"""Paste & execute a pre-formatted code block from clipboard.
The text is pulled directly from the clipboard without user
intervention and printed back on the screen before execution (unless
the -q flag is given to force quiet mode).
The block is dedented prior to execution to enable execution of method
definitions. '>' and '+' characters at the beginning of a line are
ignored, to allow pasting directly from e-mails, diff files and
doctests (the '...' continuation prompt is also stripped). The
executed block is also assigned to variable named 'pasted_block' for
later editing with '%edit pasted_block'.
You can also pass a variable name as an argument, e.g. '%paste foo'.
This assigns the pasted block to variable 'foo' as string, without
executing it (preceding >>> and + is still stripped).
Options:
-r: re-executes the block previously entered by cpaste.
-q: quiet mode: do not echo the pasted text back to the terminal.
IPython statements (magics, shell escapes) are not supported (yet).
Matthias Bussonnier
reformat terminal
r27291 See Also
Thomas Kluyver
Remove the readline shell machinery...
r22436 --------
Matthias Bussonnier
reformat terminal
r27291 cpaste : manually paste code into terminal until you mark its end.
Thomas Kluyver
Remove the readline shell machinery...
r22436 """
opts, name = self.parse_options(parameter_s, 'rq', mode='string')
if 'r' in opts:
self.rerun_pasted()
return
try:
block = self.shell.hooks.clipboard_get()
except TryNext as clipboard_exc:
message = getattr(clipboard_exc, 'args')
if message:
error(message[0])
else:
error('Could not get text from the clipboard.')
return
Ram Rachum
Fix exception causes all over the codebase
r25833 except ClipboardEmpty as e:
raise UsageError("The clipboard appears to be empty") from e
Thomas Kluyver
Remove the readline shell machinery...
r22436
# By default, echo back to terminal unless quiet mode is requested
if 'q' not in opts:
Matthias Bussonnier
remove code deprecated since at least IPython 5.0
r27205 sys.stdout.write(self.shell.pycolorize(block))
if not block.endswith("\n"):
sys.stdout.write("\n")
sys.stdout.write("## -- End pasted text --\n")
Thomas Kluyver
Remove the readline shell machinery...
r22436
self.store_or_execute(block, name)
# Class-level: add a '%cls' magic only on Windows
if sys.platform == 'win32':
@line_magic
def cls(self, s):
"""Clear screen.
"""
os.system("cls")