##// END OF EJS Templates
json_clean zmqshell replies...
MinRK -
Show More
@@ -1,441 +1,442 b''
1 """A ZMQ-based subclass of InteractiveShell.
1 """A ZMQ-based subclass of InteractiveShell.
2
2
3 This code is meant to ease the refactoring of the base InteractiveShell into
3 This code is meant to ease the refactoring of the base InteractiveShell into
4 something with a cleaner architecture for 2-process use, without actually
4 something with a cleaner architecture for 2-process use, without actually
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 we subclass and override what we want to fix. Once this is working well, we
6 we subclass and override what we want to fix. Once this is working well, we
7 can go back to the base class and refactor the code for a cleaner inheritance
7 can go back to the base class and refactor the code for a cleaner inheritance
8 implementation that doesn't rely on so much monkeypatching.
8 implementation that doesn't rely on so much monkeypatching.
9
9
10 But this lets us maintain a fully working IPython as we develop the new
10 But this lets us maintain a fully working IPython as we develop the new
11 machinery. This should thus be thought of as scaffolding.
11 machinery. This should thus be thought of as scaffolding.
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 # Stdlib
18 # Stdlib
19 import inspect
19 import inspect
20 import os
20 import os
21
21
22 # Our own
22 # Our own
23 from IPython.core.interactiveshell import (
23 from IPython.core.interactiveshell import (
24 InteractiveShell, InteractiveShellABC
24 InteractiveShell, InteractiveShellABC
25 )
25 )
26 from IPython.core import page
26 from IPython.core import page
27 from IPython.core.autocall import ZMQExitAutocall
27 from IPython.core.autocall import ZMQExitAutocall
28 from IPython.core.displaypub import DisplayPublisher
28 from IPython.core.displaypub import DisplayPublisher
29 from IPython.core.macro import Macro
29 from IPython.core.macro import Macro
30 from IPython.core.magic import MacroToEdit
30 from IPython.core.magic import MacroToEdit
31 from IPython.core.payloadpage import install_payload_page
31 from IPython.core.payloadpage import install_payload_page
32 from IPython.utils import io
32 from IPython.utils import io
33 from IPython.utils.jsonutil import json_clean
33 from IPython.utils.path import get_py_filename
34 from IPython.utils.path import get_py_filename
34 from IPython.utils.traitlets import Instance, Type, Dict, CBool
35 from IPython.utils.traitlets import Instance, Type, Dict, CBool
35 from IPython.utils.warn import warn
36 from IPython.utils.warn import warn
36 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
37 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
37 from IPython.zmq.session import extract_header
38 from IPython.zmq.session import extract_header
38 from session import Session
39 from session import Session
39
40
40 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
41 # Globals and side-effects
42 # Globals and side-effects
42 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
43
44
44 # Install the payload version of page.
45 # Install the payload version of page.
45 install_payload_page()
46 install_payload_page()
46
47
47 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
48 # Functions and classes
49 # Functions and classes
49 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
50
51
51 class ZMQDisplayPublisher(DisplayPublisher):
52 class ZMQDisplayPublisher(DisplayPublisher):
52 """A display publisher that publishes data using a ZeroMQ PUB socket."""
53 """A display publisher that publishes data using a ZeroMQ PUB socket."""
53
54
54 session = Instance(Session)
55 session = Instance(Session)
55 pub_socket = Instance('zmq.Socket')
56 pub_socket = Instance('zmq.Socket')
56 parent_header = Dict({})
57 parent_header = Dict({})
57
58
58 def set_parent(self, parent):
59 def set_parent(self, parent):
59 """Set the parent for outbound messages."""
60 """Set the parent for outbound messages."""
60 self.parent_header = extract_header(parent)
61 self.parent_header = extract_header(parent)
61
62
62 def publish(self, source, data, metadata=None):
63 def publish(self, source, data, metadata=None):
63 if metadata is None:
64 if metadata is None:
64 metadata = {}
65 metadata = {}
65 self._validate_data(source, data, metadata)
66 self._validate_data(source, data, metadata)
66 content = {}
67 content = {}
67 content['source'] = source
68 content['source'] = source
68 _encode_binary(data)
69 _encode_binary(data)
69 content['data'] = data
70 content['data'] = data
70 content['metadata'] = metadata
71 content['metadata'] = metadata
71 self.session.send(
72 self.session.send(
72 self.pub_socket, u'display_data', content,
73 self.pub_socket, u'display_data', json_clean(content),
73 parent=self.parent_header
74 parent=self.parent_header
74 )
75 )
75
76
76
77
77 class ZMQInteractiveShell(InteractiveShell):
78 class ZMQInteractiveShell(InteractiveShell):
78 """A subclass of InteractiveShell for ZMQ."""
79 """A subclass of InteractiveShell for ZMQ."""
79
80
80 displayhook_class = Type(ZMQShellDisplayHook)
81 displayhook_class = Type(ZMQShellDisplayHook)
81 display_pub_class = Type(ZMQDisplayPublisher)
82 display_pub_class = Type(ZMQDisplayPublisher)
82
83
83 # Override the traitlet in the parent class, because there's no point using
84 # Override the traitlet in the parent class, because there's no point using
84 # readline for the kernel. Can be removed when the readline code is moved
85 # readline for the kernel. Can be removed when the readline code is moved
85 # to the terminal frontend.
86 # to the terminal frontend.
86
87
87 # FIXME. This is disabled for now, even though it may cause problems under
88 # FIXME. This is disabled for now, even though it may cause problems under
88 # Windows, because it breaks %run in the Qt console. See gh-617 for more
89 # Windows, because it breaks %run in the Qt console. See gh-617 for more
89 # details. Re-enable once we've fully tested that %run works in the Qt
90 # details. Re-enable once we've fully tested that %run works in the Qt
90 # console with syntax highlighting in tracebacks.
91 # console with syntax highlighting in tracebacks.
91 # readline_use = CBool(False)
92 # readline_use = CBool(False)
92 # /FIXME
93 # /FIXME
93
94
94 exiter = Instance(ZMQExitAutocall)
95 exiter = Instance(ZMQExitAutocall)
95 def _exiter_default(self):
96 def _exiter_default(self):
96 return ZMQExitAutocall(self)
97 return ZMQExitAutocall(self)
97
98
98 keepkernel_on_exit = None
99 keepkernel_on_exit = None
99
100
100 def init_environment(self):
101 def init_environment(self):
101 """Configure the user's environment.
102 """Configure the user's environment.
102
103
103 """
104 """
104 env = os.environ
105 env = os.environ
105 # These two ensure 'ls' produces nice coloring on BSD-derived systems
106 # These two ensure 'ls' produces nice coloring on BSD-derived systems
106 env['TERM'] = 'xterm-color'
107 env['TERM'] = 'xterm-color'
107 env['CLICOLOR'] = '1'
108 env['CLICOLOR'] = '1'
108 # Since normal pagers don't work at all (over pexpect we don't have
109 # Since normal pagers don't work at all (over pexpect we don't have
109 # single-key control of the subprocess), try to disable paging in
110 # single-key control of the subprocess), try to disable paging in
110 # subprocesses as much as possible.
111 # subprocesses as much as possible.
111 env['PAGER'] = 'cat'
112 env['PAGER'] = 'cat'
112 env['GIT_PAGER'] = 'cat'
113 env['GIT_PAGER'] = 'cat'
113
114
114 def auto_rewrite_input(self, cmd):
115 def auto_rewrite_input(self, cmd):
115 """Called to show the auto-rewritten input for autocall and friends.
116 """Called to show the auto-rewritten input for autocall and friends.
116
117
117 FIXME: this payload is currently not correctly processed by the
118 FIXME: this payload is currently not correctly processed by the
118 frontend.
119 frontend.
119 """
120 """
120 new = self.displayhook.prompt1.auto_rewrite() + cmd
121 new = self.displayhook.prompt1.auto_rewrite() + cmd
121 payload = dict(
122 payload = dict(
122 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
123 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
123 transformed_input=new,
124 transformed_input=new,
124 )
125 )
125 self.payload_manager.write_payload(payload)
126 self.payload_manager.write_payload(payload)
126
127
127 def ask_exit(self):
128 def ask_exit(self):
128 """Engage the exit actions."""
129 """Engage the exit actions."""
129 payload = dict(
130 payload = dict(
130 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
131 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
131 exit=True,
132 exit=True,
132 keepkernel=self.keepkernel_on_exit,
133 keepkernel=self.keepkernel_on_exit,
133 )
134 )
134 self.payload_manager.write_payload(payload)
135 self.payload_manager.write_payload(payload)
135
136
136 def _showtraceback(self, etype, evalue, stb):
137 def _showtraceback(self, etype, evalue, stb):
137
138
138 exc_content = {
139 exc_content = {
139 u'traceback' : stb,
140 u'traceback' : stb,
140 u'ename' : unicode(etype.__name__),
141 u'ename' : unicode(etype.__name__),
141 u'evalue' : unicode(evalue)
142 u'evalue' : unicode(evalue)
142 }
143 }
143
144
144 dh = self.displayhook
145 dh = self.displayhook
145 # Send exception info over pub socket for other clients than the caller
146 # Send exception info over pub socket for other clients than the caller
146 # to pick up
147 # to pick up
147 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', exc_content, dh.parent_header)
148 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header)
148
149
149 # FIXME - Hack: store exception info in shell object. Right now, the
150 # FIXME - Hack: store exception info in shell object. Right now, the
150 # caller is reading this info after the fact, we need to fix this logic
151 # caller is reading this info after the fact, we need to fix this logic
151 # to remove this hack. Even uglier, we need to store the error status
152 # to remove this hack. Even uglier, we need to store the error status
152 # here, because in the main loop, the logic that sets it is being
153 # here, because in the main loop, the logic that sets it is being
153 # skipped because runlines swallows the exceptions.
154 # skipped because runlines swallows the exceptions.
154 exc_content[u'status'] = u'error'
155 exc_content[u'status'] = u'error'
155 self._reply_content = exc_content
156 self._reply_content = exc_content
156 # /FIXME
157 # /FIXME
157
158
158 return exc_content
159 return exc_content
159
160
160 #------------------------------------------------------------------------
161 #------------------------------------------------------------------------
161 # Magic overrides
162 # Magic overrides
162 #------------------------------------------------------------------------
163 #------------------------------------------------------------------------
163 # Once the base class stops inheriting from magic, this code needs to be
164 # Once the base class stops inheriting from magic, this code needs to be
164 # moved into a separate machinery as well. For now, at least isolate here
165 # moved into a separate machinery as well. For now, at least isolate here
165 # the magics which this class needs to implement differently from the base
166 # the magics which this class needs to implement differently from the base
166 # class, or that are unique to it.
167 # class, or that are unique to it.
167
168
168 def magic_doctest_mode(self,parameter_s=''):
169 def magic_doctest_mode(self,parameter_s=''):
169 """Toggle doctest mode on and off.
170 """Toggle doctest mode on and off.
170
171
171 This mode is intended to make IPython behave as much as possible like a
172 This mode is intended to make IPython behave as much as possible like a
172 plain Python shell, from the perspective of how its prompts, exceptions
173 plain Python shell, from the perspective of how its prompts, exceptions
173 and output look. This makes it easy to copy and paste parts of a
174 and output look. This makes it easy to copy and paste parts of a
174 session into doctests. It does so by:
175 session into doctests. It does so by:
175
176
176 - Changing the prompts to the classic ``>>>`` ones.
177 - Changing the prompts to the classic ``>>>`` ones.
177 - Changing the exception reporting mode to 'Plain'.
178 - Changing the exception reporting mode to 'Plain'.
178 - Disabling pretty-printing of output.
179 - Disabling pretty-printing of output.
179
180
180 Note that IPython also supports the pasting of code snippets that have
181 Note that IPython also supports the pasting of code snippets that have
181 leading '>>>' and '...' prompts in them. This means that you can paste
182 leading '>>>' and '...' prompts in them. This means that you can paste
182 doctests from files or docstrings (even if they have leading
183 doctests from files or docstrings (even if they have leading
183 whitespace), and the code will execute correctly. You can then use
184 whitespace), and the code will execute correctly. You can then use
184 '%history -t' to see the translated history; this will give you the
185 '%history -t' to see the translated history; this will give you the
185 input after removal of all the leading prompts and whitespace, which
186 input after removal of all the leading prompts and whitespace, which
186 can be pasted back into an editor.
187 can be pasted back into an editor.
187
188
188 With these features, you can switch into this mode easily whenever you
189 With these features, you can switch into this mode easily whenever you
189 need to do testing and changes to doctests, without having to leave
190 need to do testing and changes to doctests, without having to leave
190 your existing IPython session.
191 your existing IPython session.
191 """
192 """
192
193
193 from IPython.utils.ipstruct import Struct
194 from IPython.utils.ipstruct import Struct
194
195
195 # Shorthands
196 # Shorthands
196 shell = self.shell
197 shell = self.shell
197 disp_formatter = self.shell.display_formatter
198 disp_formatter = self.shell.display_formatter
198 ptformatter = disp_formatter.formatters['text/plain']
199 ptformatter = disp_formatter.formatters['text/plain']
199 # dstore is a data store kept in the instance metadata bag to track any
200 # dstore is a data store kept in the instance metadata bag to track any
200 # changes we make, so we can undo them later.
201 # changes we make, so we can undo them later.
201 dstore = shell.meta.setdefault('doctest_mode', Struct())
202 dstore = shell.meta.setdefault('doctest_mode', Struct())
202 save_dstore = dstore.setdefault
203 save_dstore = dstore.setdefault
203
204
204 # save a few values we'll need to recover later
205 # save a few values we'll need to recover later
205 mode = save_dstore('mode', False)
206 mode = save_dstore('mode', False)
206 save_dstore('rc_pprint', ptformatter.pprint)
207 save_dstore('rc_pprint', ptformatter.pprint)
207 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
208 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
208 save_dstore('xmode', shell.InteractiveTB.mode)
209 save_dstore('xmode', shell.InteractiveTB.mode)
209
210
210 if mode == False:
211 if mode == False:
211 # turn on
212 # turn on
212 ptformatter.pprint = False
213 ptformatter.pprint = False
213 disp_formatter.plain_text_only = True
214 disp_formatter.plain_text_only = True
214 shell.magic_xmode('Plain')
215 shell.magic_xmode('Plain')
215 else:
216 else:
216 # turn off
217 # turn off
217 ptformatter.pprint = dstore.rc_pprint
218 ptformatter.pprint = dstore.rc_pprint
218 disp_formatter.plain_text_only = dstore.rc_plain_text_only
219 disp_formatter.plain_text_only = dstore.rc_plain_text_only
219 shell.magic_xmode(dstore.xmode)
220 shell.magic_xmode(dstore.xmode)
220
221
221 # Store new mode and inform on console
222 # Store new mode and inform on console
222 dstore.mode = bool(1-int(mode))
223 dstore.mode = bool(1-int(mode))
223 mode_label = ['OFF','ON'][dstore.mode]
224 mode_label = ['OFF','ON'][dstore.mode]
224 print('Doctest mode is:', mode_label)
225 print('Doctest mode is:', mode_label)
225
226
226 # Send the payload back so that clients can modify their prompt display
227 # Send the payload back so that clients can modify their prompt display
227 payload = dict(
228 payload = dict(
228 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
229 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
229 mode=dstore.mode)
230 mode=dstore.mode)
230 self.payload_manager.write_payload(payload)
231 self.payload_manager.write_payload(payload)
231
232
232 def magic_edit(self,parameter_s='',last_call=['','']):
233 def magic_edit(self,parameter_s='',last_call=['','']):
233 """Bring up an editor and execute the resulting code.
234 """Bring up an editor and execute the resulting code.
234
235
235 Usage:
236 Usage:
236 %edit [options] [args]
237 %edit [options] [args]
237
238
238 %edit runs an external text editor. You will need to set the command for
239 %edit runs an external text editor. You will need to set the command for
239 this editor via the ``TerminalInteractiveShell.editor`` option in your
240 this editor via the ``TerminalInteractiveShell.editor`` option in your
240 configuration file before it will work.
241 configuration file before it will work.
241
242
242 This command allows you to conveniently edit multi-line code right in
243 This command allows you to conveniently edit multi-line code right in
243 your IPython session.
244 your IPython session.
244
245
245 If called without arguments, %edit opens up an empty editor with a
246 If called without arguments, %edit opens up an empty editor with a
246 temporary file and will execute the contents of this file when you
247 temporary file and will execute the contents of this file when you
247 close it (don't forget to save it!).
248 close it (don't forget to save it!).
248
249
249
250
250 Options:
251 Options:
251
252
252 -n <number>: open the editor at a specified line number. By default,
253 -n <number>: open the editor at a specified line number. By default,
253 the IPython editor hook uses the unix syntax 'editor +N filename', but
254 the IPython editor hook uses the unix syntax 'editor +N filename', but
254 you can configure this by providing your own modified hook if your
255 you can configure this by providing your own modified hook if your
255 favorite editor supports line-number specifications with a different
256 favorite editor supports line-number specifications with a different
256 syntax.
257 syntax.
257
258
258 -p: this will call the editor with the same data as the previous time
259 -p: this will call the editor with the same data as the previous time
259 it was used, regardless of how long ago (in your current session) it
260 it was used, regardless of how long ago (in your current session) it
260 was.
261 was.
261
262
262 -r: use 'raw' input. This option only applies to input taken from the
263 -r: use 'raw' input. This option only applies to input taken from the
263 user's history. By default, the 'processed' history is used, so that
264 user's history. By default, the 'processed' history is used, so that
264 magics are loaded in their transformed version to valid Python. If
265 magics are loaded in their transformed version to valid Python. If
265 this option is given, the raw input as typed as the command line is
266 this option is given, the raw input as typed as the command line is
266 used instead. When you exit the editor, it will be executed by
267 used instead. When you exit the editor, it will be executed by
267 IPython's own processor.
268 IPython's own processor.
268
269
269 -x: do not execute the edited code immediately upon exit. This is
270 -x: do not execute the edited code immediately upon exit. This is
270 mainly useful if you are editing programs which need to be called with
271 mainly useful if you are editing programs which need to be called with
271 command line arguments, which you can then do using %run.
272 command line arguments, which you can then do using %run.
272
273
273
274
274 Arguments:
275 Arguments:
275
276
276 If arguments are given, the following possibilites exist:
277 If arguments are given, the following possibilites exist:
277
278
278 - The arguments are numbers or pairs of colon-separated numbers (like
279 - The arguments are numbers or pairs of colon-separated numbers (like
279 1 4:8 9). These are interpreted as lines of previous input to be
280 1 4:8 9). These are interpreted as lines of previous input to be
280 loaded into the editor. The syntax is the same of the %macro command.
281 loaded into the editor. The syntax is the same of the %macro command.
281
282
282 - If the argument doesn't start with a number, it is evaluated as a
283 - If the argument doesn't start with a number, it is evaluated as a
283 variable and its contents loaded into the editor. You can thus edit
284 variable and its contents loaded into the editor. You can thus edit
284 any string which contains python code (including the result of
285 any string which contains python code (including the result of
285 previous edits).
286 previous edits).
286
287
287 - If the argument is the name of an object (other than a string),
288 - If the argument is the name of an object (other than a string),
288 IPython will try to locate the file where it was defined and open the
289 IPython will try to locate the file where it was defined and open the
289 editor at the point where it is defined. You can use `%edit function`
290 editor at the point where it is defined. You can use `%edit function`
290 to load an editor exactly at the point where 'function' is defined,
291 to load an editor exactly at the point where 'function' is defined,
291 edit it and have the file be executed automatically.
292 edit it and have the file be executed automatically.
292
293
293 If the object is a macro (see %macro for details), this opens up your
294 If the object is a macro (see %macro for details), this opens up your
294 specified editor with a temporary file containing the macro's data.
295 specified editor with a temporary file containing the macro's data.
295 Upon exit, the macro is reloaded with the contents of the file.
296 Upon exit, the macro is reloaded with the contents of the file.
296
297
297 Note: opening at an exact line is only supported under Unix, and some
298 Note: opening at an exact line is only supported under Unix, and some
298 editors (like kedit and gedit up to Gnome 2.8) do not understand the
299 editors (like kedit and gedit up to Gnome 2.8) do not understand the
299 '+NUMBER' parameter necessary for this feature. Good editors like
300 '+NUMBER' parameter necessary for this feature. Good editors like
300 (X)Emacs, vi, jed, pico and joe all do.
301 (X)Emacs, vi, jed, pico and joe all do.
301
302
302 - If the argument is not found as a variable, IPython will look for a
303 - If the argument is not found as a variable, IPython will look for a
303 file with that name (adding .py if necessary) and load it into the
304 file with that name (adding .py if necessary) and load it into the
304 editor. It will execute its contents with execfile() when you exit,
305 editor. It will execute its contents with execfile() when you exit,
305 loading any code in the file into your interactive namespace.
306 loading any code in the file into your interactive namespace.
306
307
307 After executing your code, %edit will return as output the code you
308 After executing your code, %edit will return as output the code you
308 typed in the editor (except when it was an existing file). This way
309 typed in the editor (except when it was an existing file). This way
309 you can reload the code in further invocations of %edit as a variable,
310 you can reload the code in further invocations of %edit as a variable,
310 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
311 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
311 the output.
312 the output.
312
313
313 Note that %edit is also available through the alias %ed.
314 Note that %edit is also available through the alias %ed.
314
315
315 This is an example of creating a simple function inside the editor and
316 This is an example of creating a simple function inside the editor and
316 then modifying it. First, start up the editor:
317 then modifying it. First, start up the editor:
317
318
318 In [1]: ed
319 In [1]: ed
319 Editing... done. Executing edited code...
320 Editing... done. Executing edited code...
320 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
321 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
321
322
322 We can then call the function foo():
323 We can then call the function foo():
323
324
324 In [2]: foo()
325 In [2]: foo()
325 foo() was defined in an editing session
326 foo() was defined in an editing session
326
327
327 Now we edit foo. IPython automatically loads the editor with the
328 Now we edit foo. IPython automatically loads the editor with the
328 (temporary) file where foo() was previously defined:
329 (temporary) file where foo() was previously defined:
329
330
330 In [3]: ed foo
331 In [3]: ed foo
331 Editing... done. Executing edited code...
332 Editing... done. Executing edited code...
332
333
333 And if we call foo() again we get the modified version:
334 And if we call foo() again we get the modified version:
334
335
335 In [4]: foo()
336 In [4]: foo()
336 foo() has now been changed!
337 foo() has now been changed!
337
338
338 Here is an example of how to edit a code snippet successive
339 Here is an example of how to edit a code snippet successive
339 times. First we call the editor:
340 times. First we call the editor:
340
341
341 In [5]: ed
342 In [5]: ed
342 Editing... done. Executing edited code...
343 Editing... done. Executing edited code...
343 hello
344 hello
344 Out[5]: "print 'hello'n"
345 Out[5]: "print 'hello'n"
345
346
346 Now we call it again with the previous output (stored in _):
347 Now we call it again with the previous output (stored in _):
347
348
348 In [6]: ed _
349 In [6]: ed _
349 Editing... done. Executing edited code...
350 Editing... done. Executing edited code...
350 hello world
351 hello world
351 Out[6]: "print 'hello world'n"
352 Out[6]: "print 'hello world'n"
352
353
353 Now we call it with the output #8 (stored in _8, also as Out[8]):
354 Now we call it with the output #8 (stored in _8, also as Out[8]):
354
355
355 In [7]: ed _8
356 In [7]: ed _8
356 Editing... done. Executing edited code...
357 Editing... done. Executing edited code...
357 hello again
358 hello again
358 Out[7]: "print 'hello again'n"
359 Out[7]: "print 'hello again'n"
359 """
360 """
360
361
361 opts,args = self.parse_options(parameter_s,'prn:')
362 opts,args = self.parse_options(parameter_s,'prn:')
362
363
363 try:
364 try:
364 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
365 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
365 except MacroToEdit as e:
366 except MacroToEdit as e:
366 # TODO: Implement macro editing over 2 processes.
367 # TODO: Implement macro editing over 2 processes.
367 print("Macro editing not yet implemented in 2-process model.")
368 print("Macro editing not yet implemented in 2-process model.")
368 return
369 return
369
370
370 # Make sure we send to the client an absolute path, in case the working
371 # Make sure we send to the client an absolute path, in case the working
371 # directory of client and kernel don't match
372 # directory of client and kernel don't match
372 filename = os.path.abspath(filename)
373 filename = os.path.abspath(filename)
373
374
374 payload = {
375 payload = {
375 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
376 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
376 'filename' : filename,
377 'filename' : filename,
377 'line_number' : lineno
378 'line_number' : lineno
378 }
379 }
379 self.payload_manager.write_payload(payload)
380 self.payload_manager.write_payload(payload)
380
381
381 def magic_gui(self, *args, **kwargs):
382 def magic_gui(self, *args, **kwargs):
382 raise NotImplementedError(
383 raise NotImplementedError(
383 'Kernel GUI support is not implemented yet, except for --pylab.')
384 'Kernel GUI support is not implemented yet, except for --pylab.')
384
385
385 def magic_pylab(self, *args, **kwargs):
386 def magic_pylab(self, *args, **kwargs):
386 raise NotImplementedError(
387 raise NotImplementedError(
387 'pylab support must be enabled in command line options.')
388 'pylab support must be enabled in command line options.')
388
389
389 # A few magics that are adapted to the specifics of using pexpect and a
390 # A few magics that are adapted to the specifics of using pexpect and a
390 # remote terminal
391 # remote terminal
391
392
392 def magic_clear(self, arg_s):
393 def magic_clear(self, arg_s):
393 """Clear the terminal."""
394 """Clear the terminal."""
394 if os.name == 'posix':
395 if os.name == 'posix':
395 self.shell.system("clear")
396 self.shell.system("clear")
396 else:
397 else:
397 self.shell.system("cls")
398 self.shell.system("cls")
398
399
399 if os.name == 'nt':
400 if os.name == 'nt':
400 # This is the usual name in windows
401 # This is the usual name in windows
401 magic_cls = magic_clear
402 magic_cls = magic_clear
402
403
403 # Terminal pagers won't work over pexpect, but we do have our own pager
404 # Terminal pagers won't work over pexpect, but we do have our own pager
404
405
405 def magic_less(self, arg_s):
406 def magic_less(self, arg_s):
406 """Show a file through the pager.
407 """Show a file through the pager.
407
408
408 Files ending in .py are syntax-highlighted."""
409 Files ending in .py are syntax-highlighted."""
409 cont = open(arg_s).read()
410 cont = open(arg_s).read()
410 if arg_s.endswith('.py'):
411 if arg_s.endswith('.py'):
411 cont = self.shell.pycolorize(cont)
412 cont = self.shell.pycolorize(cont)
412 page.page(cont)
413 page.page(cont)
413
414
414 magic_more = magic_less
415 magic_more = magic_less
415
416
416 # Man calls a pager, so we also need to redefine it
417 # Man calls a pager, so we also need to redefine it
417 if os.name == 'posix':
418 if os.name == 'posix':
418 def magic_man(self, arg_s):
419 def magic_man(self, arg_s):
419 """Find the man page for the given command and display in pager."""
420 """Find the man page for the given command and display in pager."""
420 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
421 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
421 split=False))
422 split=False))
422
423
423 # FIXME: this is specific to the GUI, so we should let the gui app load
424 # FIXME: this is specific to the GUI, so we should let the gui app load
424 # magics at startup that are only for the gui. Once the gui app has proper
425 # magics at startup that are only for the gui. Once the gui app has proper
425 # profile and configuration management, we can have it initialize a kernel
426 # profile and configuration management, we can have it initialize a kernel
426 # with a special config file that provides these.
427 # with a special config file that provides these.
427 def magic_guiref(self, arg_s):
428 def magic_guiref(self, arg_s):
428 """Show a basic reference about the GUI console."""
429 """Show a basic reference about the GUI console."""
429 from IPython.core.usage import gui_reference
430 from IPython.core.usage import gui_reference
430 page.page(gui_reference, auto_html=True)
431 page.page(gui_reference, auto_html=True)
431
432
432 def set_next_input(self, text):
433 def set_next_input(self, text):
433 """Send the specified text to the frontend to be presented at the next
434 """Send the specified text to the frontend to be presented at the next
434 input cell."""
435 input cell."""
435 payload = dict(
436 payload = dict(
436 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
437 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
437 text=text
438 text=text
438 )
439 )
439 self.payload_manager.write_payload(payload)
440 self.payload_manager.write_payload(payload)
440
441
441 InteractiveShellABC.register(ZMQInteractiveShell)
442 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now