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