##// END OF EJS Templates
Merge pull request #13176 from meeseeksmachine/auto-backport-of-pr-13174-on-7.x...
Matthias Bussonnier -
r26827:f12cb93b merge
parent child Browse files
Show More
@@ -1,203 +1,213 b''
1 1 """Extra magics for terminal use."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6
7 7 from logging import error
8 8 import os
9 9 import sys
10 10
11 11 from IPython.core.error import TryNext, UsageError
12 12 from IPython.core.magic import Magics, magics_class, line_magic
13 13 from IPython.lib.clipboard import ClipboardEmpty
14 14 from IPython.utils.text import SList, strip_email_quotes
15 15 from IPython.utils import py3compat
16 16
17 17 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
18 18 """ Yield pasted lines until the user enters the given sentinel value.
19 19 """
20 20 if not quiet:
21 21 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
22 22 % sentinel)
23 23 prompt = ":"
24 24 else:
25 25 prompt = ""
26 26 while True:
27 27 try:
28 28 l = l_input(prompt)
29 29 if l == sentinel:
30 30 return
31 31 else:
32 32 yield l
33 33 except EOFError:
34 34 print('<EOF>')
35 35 return
36 36
37 37
38 38 @magics_class
39 39 class TerminalMagics(Magics):
40 40 def __init__(self, shell):
41 41 super(TerminalMagics, self).__init__(shell)
42 42
43 43 def store_or_execute(self, block, name):
44 44 """ Execute a block, or store it in a variable, per the user's request.
45 45 """
46 46 if name:
47 47 # If storing it for further editing
48 48 self.shell.user_ns[name] = SList(block.splitlines())
49 49 print("Block assigned to '%s'" % name)
50 50 else:
51 51 b = self.preclean_input(block)
52 52 self.shell.user_ns['pasted_block'] = b
53 53 self.shell.using_paste_magics = True
54 54 try:
55 55 self.shell.run_cell(b)
56 56 finally:
57 57 self.shell.using_paste_magics = False
58 58
59 59 def preclean_input(self, block):
60 60 lines = block.splitlines()
61 61 while lines and not lines[0].strip():
62 62 lines = lines[1:]
63 63 return strip_email_quotes('\n'.join(lines))
64 64
65 65 def rerun_pasted(self, name='pasted_block'):
66 66 """ Rerun a previously pasted command.
67 67 """
68 68 b = self.shell.user_ns.get(name)
69 69
70 70 # Sanity checks
71 71 if b is None:
72 72 raise UsageError('No previous pasted block available')
73 73 if not isinstance(b, str):
74 74 raise UsageError(
75 75 "Variable 'pasted_block' is not a string, can't execute")
76 76
77 77 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
78 78 self.shell.run_cell(b)
79 79
80 80 @line_magic
81 81 def autoindent(self, parameter_s = ''):
82 82 """Toggle autoindent on/off (deprecated)"""
83 83 self.shell.set_autoindent()
84 84 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
85 85
86 86 @line_magic
87 87 def cpaste(self, parameter_s=''):
88 88 """Paste & execute a pre-formatted code block from clipboard.
89 89
90 90 You must terminate the block with '--' (two minus-signs) or Ctrl-D
91 91 alone on the line. You can also provide your own sentinel with '%paste
92 92 -s %%' ('%%' is the new sentinel for this operation).
93 93
94 94 The block is dedented prior to execution to enable execution of method
95 95 definitions. '>' and '+' characters at the beginning of a line are
96 96 ignored, to allow pasting directly from e-mails, diff files and
97 97 doctests (the '...' continuation prompt is also stripped). The
98 98 executed block is also assigned to variable named 'pasted_block' for
99 99 later editing with '%edit pasted_block'.
100 100
101 101 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
102 102 This assigns the pasted block to variable 'foo' as string, without
103 103 dedenting or executing it (preceding >>> and + is still stripped)
104 104
105 105 '%cpaste -r' re-executes the block previously entered by cpaste.
106 106 '%cpaste -q' suppresses any additional output messages.
107 107
108 108 Do not be alarmed by garbled output on Windows (it's a readline bug).
109 109 Just press enter and type -- (and press enter again) and the block
110 110 will be what was just pasted.
111 111
112 IPython statements (magics, shell escapes) are not supported (yet).
112 Shell escapes are not supported (yet).
113 113
114 114 See also
115 115 --------
116 116 paste: automatically pull code from clipboard.
117 117
118 118 Examples
119 119 --------
120 120 ::
121 121
122 122 In [8]: %cpaste
123 123 Pasting code; enter '--' alone on the line to stop.
124 124 :>>> a = ["world!", "Hello"]
125 :>>> print " ".join(sorted(a))
125 :>>> print(" ".join(sorted(a)))
126 126 :--
127 127 Hello world!
128
129 ::
130 In [8]: %cpaste
131 Pasting code; enter '--' alone on the line to stop.
132 :>>> %alias_magic t timeit
133 :>>> %t -n1 pass
134 :--
135 Created `%t` as an alias for `%timeit`.
136 Created `%%t` as an alias for `%%timeit`.
137 354 ns Β± 224 ns per loop (mean Β± std. dev. of 7 runs, 1 loop each)
128 138 """
129 139 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
130 140 if 'r' in opts:
131 141 self.rerun_pasted()
132 142 return
133 143
134 144 quiet = ('q' in opts)
135 145
136 146 sentinel = opts.get('s', u'--')
137 147 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
138 148 self.store_or_execute(block, name)
139 149
140 150 @line_magic
141 151 def paste(self, parameter_s=''):
142 152 """Paste & execute a pre-formatted code block from clipboard.
143 153
144 154 The text is pulled directly from the clipboard without user
145 155 intervention and printed back on the screen before execution (unless
146 156 the -q flag is given to force quiet mode).
147 157
148 158 The block is dedented prior to execution to enable execution of method
149 159 definitions. '>' and '+' characters at the beginning of a line are
150 160 ignored, to allow pasting directly from e-mails, diff files and
151 161 doctests (the '...' continuation prompt is also stripped). The
152 162 executed block is also assigned to variable named 'pasted_block' for
153 163 later editing with '%edit pasted_block'.
154 164
155 165 You can also pass a variable name as an argument, e.g. '%paste foo'.
156 166 This assigns the pasted block to variable 'foo' as string, without
157 167 executing it (preceding >>> and + is still stripped).
158 168
159 169 Options:
160 170
161 171 -r: re-executes the block previously entered by cpaste.
162 172
163 173 -q: quiet mode: do not echo the pasted text back to the terminal.
164 174
165 175 IPython statements (magics, shell escapes) are not supported (yet).
166 176
167 177 See also
168 178 --------
169 179 cpaste: manually paste code into terminal until you mark its end.
170 180 """
171 181 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
172 182 if 'r' in opts:
173 183 self.rerun_pasted()
174 184 return
175 185 try:
176 186 block = self.shell.hooks.clipboard_get()
177 187 except TryNext as clipboard_exc:
178 188 message = getattr(clipboard_exc, 'args')
179 189 if message:
180 190 error(message[0])
181 191 else:
182 192 error('Could not get text from the clipboard.')
183 193 return
184 194 except ClipboardEmpty:
185 195 raise UsageError("The clipboard appears to be empty")
186 196
187 197 # By default, echo back to terminal unless quiet mode is requested
188 198 if 'q' not in opts:
189 199 write = self.shell.write
190 200 write(self.shell.pycolorize(block))
191 201 if not block.endswith('\n'):
192 202 write('\n')
193 203 write("## -- End pasted text --\n")
194 204
195 205 self.store_or_execute(block, name)
196 206
197 207 # Class-level: add a '%cls' magic only on Windows
198 208 if sys.platform == 'win32':
199 209 @line_magic
200 210 def cls(self, s):
201 211 """Clear screen.
202 212 """
203 213 os.system("cls")
General Comments 0
You need to be logged in to leave comments. Login now