##// END OF EJS Templates
Merge branch 'newkernel' of git://github.com/ellisonbg/ipython into qtfrontend
epatters -
r2834:9b315618 merge
parent child Browse files
Show More
@@ -0,0 +1,50 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A payload based version of page.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2010 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 from IPython.core.interactiveshell import InteractiveShell
24
25 #-----------------------------------------------------------------------------
26 # Classes and functions
27 #-----------------------------------------------------------------------------
28
29 def page(strng, start=0, screen_lines=0, pager_cmd=None):
30 """Print a string, piping through a pager.
31
32 This version ignores the screen_lines and pager_cmd arguments and uses
33 IPython's payload system instead.
34 """
35
36 # Some routines may auto-compute start offsets incorrectly and pass a
37 # negative value. Offset to 0 for robustness.
38 start = max(0, start)
39 shell = InteractiveShell.instance()
40 payload = dict(
41 source='IPython.zmq.page.page',
42 data=strng,
43 start_line_number=start
44 )
45 shell.payload_manager.write_payload(payload)
46
47 def install_payload_page():
48 """Install this version of page as IPython.core.page.page."""
49 from IPython.core import page as corepage
50 corepage.page = page
@@ -1901,9 +1901,6 b' class InteractiveShell(Configurable, Magic):'
1901 - 1: an error occurred.
1901 - 1: an error occurred.
1902 """
1902 """
1903
1903
1904 # Clear the payload before executing new code.
1905 self.payload_manager.clear_payload()
1906
1907 # Set our own excepthook in case the user code tries to call it
1904 # Set our own excepthook in case the user code tries to call it
1908 # directly, so that the IPython crash handler doesn't get triggered
1905 # directly, so that the IPython crash handler doesn't get triggered
1909 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1906 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
@@ -52,7 +52,7 b' from IPython.core.error import TryNext'
52 from IPython.core.error import UsageError
52 from IPython.core.error import UsageError
53 from IPython.core.fakemodule import FakeModule
53 from IPython.core.fakemodule import FakeModule
54 from IPython.core.macro import Macro
54 from IPython.core.macro import Macro
55 from IPython.core.page import page
55 from IPython.core import page
56 from IPython.core.prefilter import ESC_MAGIC
56 from IPython.core.prefilter import ESC_MAGIC
57 from IPython.lib.pylabtools import mpl_runner
57 from IPython.lib.pylabtools import mpl_runner
58 from IPython.lib.inputhook import enable_gui
58 from IPython.lib.inputhook import enable_gui
@@ -514,7 +514,7 b' Currently the magic system has the following functions:\\n"""'
514 (' '+mesc).join(self.lsmagic()),
514 (' '+mesc).join(self.lsmagic()),
515 Magic.auto_status[self.shell.automagic] ) )
515 Magic.auto_status[self.shell.automagic] ) )
516
516
517 page(outmsg,screen_lines=self.shell.usable_screen_length)
517 page.page(outmsg,screen_lines=self.shell.usable_screen_length)
518
518
519
519
520 def magic_autoindent(self, parameter_s = ''):
520 def magic_autoindent(self, parameter_s = ''):
@@ -656,7 +656,7 b' Currently the magic system has the following functions:\\n"""'
656 info = self._ofind(oname)
656 info = self._ofind(oname)
657 if info['found']:
657 if info['found']:
658 txt = (raw and str or pformat)( info['obj'] )
658 txt = (raw and str or pformat)( info['obj'] )
659 page(txt)
659 page.page(txt)
660 else:
660 else:
661 print 'Object `%s` not found' % oname
661 print 'Object `%s` not found' % oname
662
662
@@ -727,7 +727,7 b' Currently the magic system has the following functions:\\n"""'
727 except IOError,msg:
727 except IOError,msg:
728 print msg
728 print msg
729 return
729 return
730 page(self.shell.inspector.format(file(filename).read()))
730 page.page(self.shell.inspector.format(file(filename).read()))
731
731
732 def _inspect(self,meth,oname,namespaces=None,**kw):
732 def _inspect(self,meth,oname,namespaces=None,**kw):
733 """Generic interface to the inspector system.
733 """Generic interface to the inspector system.
@@ -1520,7 +1520,7 b' Currently the magic system has the following functions:\\n"""'
1520 output = stdout_trap.getvalue()
1520 output = stdout_trap.getvalue()
1521 output = output.rstrip()
1521 output = output.rstrip()
1522
1522
1523 page(output,screen_lines=self.shell.usable_screen_length)
1523 page.page(output,screen_lines=self.shell.usable_screen_length)
1524 print sys_exit,
1524 print sys_exit,
1525
1525
1526 dump_file = opts.D[0]
1526 dump_file = opts.D[0]
@@ -3256,7 +3256,7 b' Defaulting color scheme to \'NoColor\'"""'
3256 print "Error: no such file or variable"
3256 print "Error: no such file or variable"
3257 return
3257 return
3258
3258
3259 page(self.shell.pycolorize(cont),
3259 page.page(self.shell.pycolorize(cont),
3260 screen_lines=self.shell.usable_screen_length)
3260 screen_lines=self.shell.usable_screen_length)
3261
3261
3262 def _rerun_pasted(self):
3262 def _rerun_pasted(self):
@@ -3413,7 +3413,7 b' Defaulting color scheme to \'NoColor\'"""'
3413 import IPython.core.usage
3413 import IPython.core.usage
3414 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3414 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3415
3415
3416 page(qr)
3416 page.page(qr)
3417
3417
3418 def magic_doctest_mode(self,parameter_s=''):
3418 def magic_doctest_mode(self,parameter_s=''):
3419 """Toggle doctest mode on and off.
3419 """Toggle doctest mode on and off.
@@ -27,7 +27,7 b' import sys'
27 import types
27 import types
28
28
29 # IPython's own
29 # IPython's own
30 from IPython.core.page import page
30 from IPython.core import page
31 from IPython.external.Itpl import itpl
31 from IPython.external.Itpl import itpl
32 from IPython.utils import PyColorize
32 from IPython.utils import PyColorize
33 import IPython.utils.io
33 import IPython.utils.io
@@ -281,7 +281,7 b' class Inspector:'
281 if output is None:
281 if output is None:
282 self.noinfo('documentation',oname)
282 self.noinfo('documentation',oname)
283 return
283 return
284 page(output)
284 page.page(output)
285
285
286 def psource(self,obj,oname=''):
286 def psource(self,obj,oname=''):
287 """Print the source code for an object."""
287 """Print the source code for an object."""
@@ -293,7 +293,7 b' class Inspector:'
293 except:
293 except:
294 self.noinfo('source',oname)
294 self.noinfo('source',oname)
295 else:
295 else:
296 page(self.format(src))
296 page.page(self.format(src))
297
297
298 def pfile(self,obj,oname=''):
298 def pfile(self,obj,oname=''):
299 """Show the whole file where an object was defined."""
299 """Show the whole file where an object was defined."""
@@ -325,7 +325,7 b' class Inspector:'
325 # Print only text files, not extension binaries. Note that
325 # Print only text files, not extension binaries. Note that
326 # getsourcelines returns lineno with 1-offset and page() uses
326 # getsourcelines returns lineno with 1-offset and page() uses
327 # 0-offset, so we must adjust.
327 # 0-offset, so we must adjust.
328 page(self.format(open(ofile).read()),lineno-1)
328 page.page(self.format(open(ofile).read()),lineno-1)
329
329
330 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
330 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
331 """Show detailed information about an object.
331 """Show detailed information about an object.
@@ -548,7 +548,7 b' class Inspector:'
548 # Finally send to printer/pager
548 # Finally send to printer/pager
549 output = out.getvalue()
549 output = out.getvalue()
550 if output:
550 if output:
551 page(output)
551 page.page(output)
552 # end pinfo
552 # end pinfo
553
553
554 def psearch(self,pattern,ns_table,ns_search=[],
554 def psearch(self,pattern,ns_table,ns_search=[],
@@ -606,4 +606,4 b' class Inspector:'
606 search_result.extend(tmp_res)
606 search_result.extend(tmp_res)
607 search_result.sort()
607 search_result.sort()
608
608
609 page('\n'.join(search_result))
609 page.page('\n'.join(search_result))
@@ -33,7 +33,7 b' from IPython.core.alias import AliasManager'
33 from IPython.core.autocall import IPyAutocall
33 from IPython.core.autocall import IPyAutocall
34 from IPython.config.configurable import Configurable
34 from IPython.config.configurable import Configurable
35 from IPython.core.splitinput import split_user_input
35 from IPython.core.splitinput import split_user_input
36 from IPython.core.page import page
36 from IPython.core import page
37
37
38 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool, Instance
38 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool, Instance
39 import IPython.utils.io
39 import IPython.utils.io
@@ -960,7 +960,7 b' class HelpHandler(PrefilterHandler):'
960 #print 'line:<%r>' % line # dbg
960 #print 'line:<%r>' % line # dbg
961 self.shell.magic_pinfo(line)
961 self.shell.magic_pinfo(line)
962 else:
962 else:
963 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
963 page.page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
964 return '' # Empty string is needed here!
964 return '' # Empty string is needed here!
965 except:
965 except:
966 raise
966 raise
@@ -17,7 +17,7 b" __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot',"
17
17
18 import IPython.GnuplotRuntime as GRun
18 import IPython.GnuplotRuntime as GRun
19 from IPython.utils.genutils import warn
19 from IPython.utils.genutils import warn
20 from IPython.core.page import page
20 from IPython.core import page
21
21
22 # Set global names for interactive use
22 # Set global names for interactive use
23 Gnuplot = GRun.Gnuplot
23 Gnuplot = GRun.Gnuplot
@@ -1,3 +1,5 b''
1 import os
2
1 # System library imports
3 # System library imports
2 from PyQt4 import QtCore, QtGui
4 from PyQt4 import QtCore, QtGui
3
5
@@ -61,7 +63,7 b' class RichIPythonWidget(IPythonWidget):'
61 """
63 """
62 payload = msg['content']['payload']
64 payload = msg['content']['payload']
63 for item in payload:
65 for item in payload:
64 if item['type'] == 'plot':
66 if item['source'] == 'IPython.zmq.pylab.backend_payload.add_plot_payload':
65 if item['format'] == 'svg':
67 if item['format'] == 'svg':
66 svg = item['data']
68 svg = item['data']
67 try:
69 try:
@@ -78,6 +80,28 b' class RichIPythonWidget(IPythonWidget):'
78 else:
80 else:
79 # Add other plot formats here!
81 # Add other plot formats here!
80 pass
82 pass
83 elif item['source'] == 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic':
84 # TODO: I have implmented the logic for TextMate on the Mac.
85 # But, we need to allow payload handlers on the non-rich
86 # text IPython widget as well. Furthermore, we should probably
87 # move these handlers to separate methods. But, we need to
88 # be very careful to process the payload list in order. Thus,
89 # we will probably need a _handle_payload method of the
90 # base class that dispatches to the separate handler methods
91 # for each payload source. If a particular subclass doesn't
92 # have a handler for a payload source, it should at least
93 # print a nice message.
94 filename = item['filename']
95 line_number = item['line_number']
96 if line_number is None:
97 cmd = 'mate %s' % filename
98 else:
99 cmd = 'mate -l %s %s' % (line_number, filename)
100 os.system(cmd)
101 elif item['source'] == 'IPython.zmq.page.page':
102 # TODO: This is probably a good place to start, but Evan can
103 # add better paging capabilities.
104 self._append_plain_text(item['data'])
81 else:
105 else:
82 # Add other payload types here!
106 # Add other payload types here!
83 pass
107 pass
@@ -19,5 +19,8 b' def add_plot_payload(format, data, metadata={}):'
19 metadata : dict, optional [default empty]
19 metadata : dict, optional [default empty]
20 Allows for specification of additional information about the plot data.
20 Allows for specification of additional information about the plot data.
21 """
21 """
22 payload = dict(type='plot', format=format, data=data, metadata=metadata)
22 payload = dict(
23 source='IPython.zmq.pylab.backend_payload.add_plot_payload',
24 format=format, data=data, metadata=metadata
25 )
23 InteractiveShell.instance().payload_manager.write_payload(payload)
26 InteractiveShell.instance().payload_manager.write_payload(payload)
@@ -1,3 +1,5 b''
1 import inspect
2 import re
1 import sys
3 import sys
2 from subprocess import Popen, PIPE
4 from subprocess import Popen, PIPE
3
5
@@ -5,8 +7,17 b' from IPython.core.interactiveshell import ('
5 InteractiveShell, InteractiveShellABC
7 InteractiveShell, InteractiveShellABC
6 )
8 )
7 from IPython.core.displayhook import DisplayHook
9 from IPython.core.displayhook import DisplayHook
10 from IPython.core.macro import Macro
11 from IPython.utils.path import get_py_filename
12 from IPython.utils.text import StringTypes
8 from IPython.utils.traitlets import Instance, Type, Dict
13 from IPython.utils.traitlets import Instance, Type, Dict
14 from IPython.utils.warn import warn
9 from IPython.zmq.session import extract_header
15 from IPython.zmq.session import extract_header
16 from IPython.core.payloadpage import install_payload_page
17
18
19 # Install the payload version of page.
20 install_payload_page()
10
21
11
22
12 class ZMQDisplayHook(DisplayHook):
23 class ZMQDisplayHook(DisplayHook):
@@ -66,6 +77,282 b' class ZMQInteractiveShell(InteractiveShell):'
66 Term = IPython.utils.io.IOTerm()
77 Term = IPython.utils.io.IOTerm()
67 IPython.utils.io.Term = Term
78 IPython.utils.io.Term = Term
68
79
80 def magic_edit(self,parameter_s='',last_call=['','']):
81 """Bring up an editor and execute the resulting code.
82
83 Usage:
84 %edit [options] [args]
85
86 %edit runs IPython's editor hook. The default version of this hook is
87 set to call the __IPYTHON__.rc.editor command. This is read from your
88 environment variable $EDITOR. If this isn't found, it will default to
89 vi under Linux/Unix and to notepad under Windows. See the end of this
90 docstring for how to change the editor hook.
91
92 You can also set the value of this editor via the command line option
93 '-editor' or in your ipythonrc file. This is useful if you wish to use
94 specifically for IPython an editor different from your typical default
95 (and for Windows users who typically don't set environment variables).
96
97 This command allows you to conveniently edit multi-line code right in
98 your IPython session.
99
100 If called without arguments, %edit opens up an empty editor with a
101 temporary file and will execute the contents of this file when you
102 close it (don't forget to save it!).
103
104
105 Options:
106
107 -n <number>: open the editor at a specified line number. By default,
108 the IPython editor hook uses the unix syntax 'editor +N filename', but
109 you can configure this by providing your own modified hook if your
110 favorite editor supports line-number specifications with a different
111 syntax.
112
113 -p: this will call the editor with the same data as the previous time
114 it was used, regardless of how long ago (in your current session) it
115 was.
116
117 -r: use 'raw' input. This option only applies to input taken from the
118 user's history. By default, the 'processed' history is used, so that
119 magics are loaded in their transformed version to valid Python. If
120 this option is given, the raw input as typed as the command line is
121 used instead. When you exit the editor, it will be executed by
122 IPython's own processor.
123
124 -x: do not execute the edited code immediately upon exit. This is
125 mainly useful if you are editing programs which need to be called with
126 command line arguments, which you can then do using %run.
127
128
129 Arguments:
130
131 If arguments are given, the following possibilites exist:
132
133 - The arguments are numbers or pairs of colon-separated numbers (like
134 1 4:8 9). These are interpreted as lines of previous input to be
135 loaded into the editor. The syntax is the same of the %macro command.
136
137 - If the argument doesn't start with a number, it is evaluated as a
138 variable and its contents loaded into the editor. You can thus edit
139 any string which contains python code (including the result of
140 previous edits).
141
142 - If the argument is the name of an object (other than a string),
143 IPython will try to locate the file where it was defined and open the
144 editor at the point where it is defined. You can use `%edit function`
145 to load an editor exactly at the point where 'function' is defined,
146 edit it and have the file be executed automatically.
147
148 If the object is a macro (see %macro for details), this opens up your
149 specified editor with a temporary file containing the macro's data.
150 Upon exit, the macro is reloaded with the contents of the file.
151
152 Note: opening at an exact line is only supported under Unix, and some
153 editors (like kedit and gedit up to Gnome 2.8) do not understand the
154 '+NUMBER' parameter necessary for this feature. Good editors like
155 (X)Emacs, vi, jed, pico and joe all do.
156
157 - If the argument is not found as a variable, IPython will look for a
158 file with that name (adding .py if necessary) and load it into the
159 editor. It will execute its contents with execfile() when you exit,
160 loading any code in the file into your interactive namespace.
161
162 After executing your code, %edit will return as output the code you
163 typed in the editor (except when it was an existing file). This way
164 you can reload the code in further invocations of %edit as a variable,
165 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
166 the output.
167
168 Note that %edit is also available through the alias %ed.
169
170 This is an example of creating a simple function inside the editor and
171 then modifying it. First, start up the editor:
172
173 In [1]: ed
174 Editing... done. Executing edited code...
175 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
176
177 We can then call the function foo():
178
179 In [2]: foo()
180 foo() was defined in an editing session
181
182 Now we edit foo. IPython automatically loads the editor with the
183 (temporary) file where foo() was previously defined:
184
185 In [3]: ed foo
186 Editing... done. Executing edited code...
187
188 And if we call foo() again we get the modified version:
189
190 In [4]: foo()
191 foo() has now been changed!
192
193 Here is an example of how to edit a code snippet successive
194 times. First we call the editor:
195
196 In [5]: ed
197 Editing... done. Executing edited code...
198 hello
199 Out[5]: "print 'hello'n"
200
201 Now we call it again with the previous output (stored in _):
202
203 In [6]: ed _
204 Editing... done. Executing edited code...
205 hello world
206 Out[6]: "print 'hello world'n"
207
208 Now we call it with the output #8 (stored in _8, also as Out[8]):
209
210 In [7]: ed _8
211 Editing... done. Executing edited code...
212 hello again
213 Out[7]: "print 'hello again'n"
214
215
216 Changing the default editor hook:
217
218 If you wish to write your own editor hook, you can put it in a
219 configuration file which you load at startup time. The default hook
220 is defined in the IPython.core.hooks module, and you can use that as a
221 starting example for further modifications. That file also has
222 general instructions on how to set a new hook for use once you've
223 defined it."""
224
225 # FIXME: This function has become a convoluted mess. It needs a
226 # ground-up rewrite with clean, simple logic.
227
228 def make_filename(arg):
229 "Make a filename from the given args"
230 try:
231 filename = get_py_filename(arg)
232 except IOError:
233 if args.endswith('.py'):
234 filename = arg
235 else:
236 filename = None
237 return filename
238
239 # custom exceptions
240 class DataIsObject(Exception): pass
241
242 opts,args = self.parse_options(parameter_s,'prn:')
243 # Set a few locals from the options for convenience:
244 opts_p = opts.has_key('p')
245 opts_r = opts.has_key('r')
246
247 # Default line number value
248 lineno = opts.get('n',None)
249
250 if opts_p:
251 args = '_%s' % last_call[0]
252 if not self.shell.user_ns.has_key(args):
253 args = last_call[1]
254
255 # use last_call to remember the state of the previous call, but don't
256 # let it be clobbered by successive '-p' calls.
257 try:
258 last_call[0] = self.shell.displayhook.prompt_count
259 if not opts_p:
260 last_call[1] = parameter_s
261 except:
262 pass
263
264 # by default this is done with temp files, except when the given
265 # arg is a filename
266 use_temp = 1
267
268 if re.match(r'\d',args):
269 # Mode where user specifies ranges of lines, like in %macro.
270 # This means that you can't edit files whose names begin with
271 # numbers this way. Tough.
272 ranges = args.split()
273 data = ''.join(self.extract_input_slices(ranges,opts_r))
274 elif args.endswith('.py'):
275 filename = make_filename(args)
276 data = ''
277 use_temp = 0
278 elif args:
279 try:
280 # Load the parameter given as a variable. If not a string,
281 # process it as an object instead (below)
282
283 #print '*** args',args,'type',type(args) # dbg
284 data = eval(args,self.shell.user_ns)
285 if not type(data) in StringTypes:
286 raise DataIsObject
287
288 except (NameError,SyntaxError):
289 # given argument is not a variable, try as a filename
290 filename = make_filename(args)
291 if filename is None:
292 warn("Argument given (%s) can't be found as a variable "
293 "or as a filename." % args)
294 return
295
296 data = ''
297 use_temp = 0
298 except DataIsObject:
299
300 # macros have a special edit function
301 if isinstance(data,Macro):
302 self._edit_macro(args,data)
303 return
304
305 # For objects, try to edit the file where they are defined
306 try:
307 filename = inspect.getabsfile(data)
308 if 'fakemodule' in filename.lower() and inspect.isclass(data):
309 # class created by %edit? Try to find source
310 # by looking for method definitions instead, the
311 # __module__ in those classes is FakeModule.
312 attrs = [getattr(data, aname) for aname in dir(data)]
313 for attr in attrs:
314 if not inspect.ismethod(attr):
315 continue
316 filename = inspect.getabsfile(attr)
317 if filename and 'fakemodule' not in filename.lower():
318 # change the attribute to be the edit target instead
319 data = attr
320 break
321
322 datafile = 1
323 except TypeError:
324 filename = make_filename(args)
325 datafile = 1
326 warn('Could not find file where `%s` is defined.\n'
327 'Opening a file named `%s`' % (args,filename))
328 # Now, make sure we can actually read the source (if it was in
329 # a temp file it's gone by now).
330 if datafile:
331 try:
332 if lineno is None:
333 lineno = inspect.getsourcelines(data)[1]
334 except IOError:
335 filename = make_filename(args)
336 if filename is None:
337 warn('The file `%s` where `%s` was defined cannot '
338 'be read.' % (filename,data))
339 return
340 use_temp = 0
341 else:
342 data = ''
343
344 if use_temp:
345 filename = self.shell.mktempfile(data)
346 print 'IPython will make a temporary file named:',filename
347
348 payload = {
349 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
350 'filename' : filename,
351 'line_number' : lineno
352 }
353 self.payload_manager.write_payload(payload)
354
355
69 InteractiveShellABC.register(ZMQInteractiveShell)
356 InteractiveShellABC.register(ZMQInteractiveShell)
70
357
71
358
General Comments 0
You need to be logged in to leave comments. Login now