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