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