##// END OF EJS Templates
Started %edit magic.
Brian Granger -
Show More
@@ -66,6 +66,319 b' class ZMQInteractiveShell(InteractiveShell):'
66 Term = IPython.utils.io.IOTerm()
66 Term = IPython.utils.io.IOTerm()
67 IPython.utils.io.Term = Term
67 IPython.utils.io.Term = Term
68
68
69 def magic_edit(self,parameter_s='',last_call=['','']):
70 """Bring up an editor and execute the resulting code.
71
72 Usage:
73 %edit [options] [args]
74
75 %edit runs IPython's editor hook. The default version of this hook is
76 set to call the __IPYTHON__.rc.editor command. This is read from your
77 environment variable $EDITOR. If this isn't found, it will default to
78 vi under Linux/Unix and to notepad under Windows. See the end of this
79 docstring for how to change the editor hook.
80
81 You can also set the value of this editor via the command line option
82 '-editor' or in your ipythonrc file. This is useful if you wish to use
83 specifically for IPython an editor different from your typical default
84 (and for Windows users who typically don't set environment variables).
85
86 This command allows you to conveniently edit multi-line code right in
87 your IPython session.
88
89 If called without arguments, %edit opens up an empty editor with a
90 temporary file and will execute the contents of this file when you
91 close it (don't forget to save it!).
92
93
94 Options:
95
96 -n <number>: open the editor at a specified line number. By default,
97 the IPython editor hook uses the unix syntax 'editor +N filename', but
98 you can configure this by providing your own modified hook if your
99 favorite editor supports line-number specifications with a different
100 syntax.
101
102 -p: this will call the editor with the same data as the previous time
103 it was used, regardless of how long ago (in your current session) it
104 was.
105
106 -r: use 'raw' input. This option only applies to input taken from the
107 user's history. By default, the 'processed' history is used, so that
108 magics are loaded in their transformed version to valid Python. If
109 this option is given, the raw input as typed as the command line is
110 used instead. When you exit the editor, it will be executed by
111 IPython's own processor.
112
113 -x: do not execute the edited code immediately upon exit. This is
114 mainly useful if you are editing programs which need to be called with
115 command line arguments, which you can then do using %run.
116
117
118 Arguments:
119
120 If arguments are given, the following possibilites exist:
121
122 - The arguments are numbers or pairs of colon-separated numbers (like
123 1 4:8 9). These are interpreted as lines of previous input to be
124 loaded into the editor. The syntax is the same of the %macro command.
125
126 - If the argument doesn't start with a number, it is evaluated as a
127 variable and its contents loaded into the editor. You can thus edit
128 any string which contains python code (including the result of
129 previous edits).
130
131 - If the argument is the name of an object (other than a string),
132 IPython will try to locate the file where it was defined and open the
133 editor at the point where it is defined. You can use `%edit function`
134 to load an editor exactly at the point where 'function' is defined,
135 edit it and have the file be executed automatically.
136
137 If the object is a macro (see %macro for details), this opens up your
138 specified editor with a temporary file containing the macro's data.
139 Upon exit, the macro is reloaded with the contents of the file.
140
141 Note: opening at an exact line is only supported under Unix, and some
142 editors (like kedit and gedit up to Gnome 2.8) do not understand the
143 '+NUMBER' parameter necessary for this feature. Good editors like
144 (X)Emacs, vi, jed, pico and joe all do.
145
146 - If the argument is not found as a variable, IPython will look for a
147 file with that name (adding .py if necessary) and load it into the
148 editor. It will execute its contents with execfile() when you exit,
149 loading any code in the file into your interactive namespace.
150
151 After executing your code, %edit will return as output the code you
152 typed in the editor (except when it was an existing file). This way
153 you can reload the code in further invocations of %edit as a variable,
154 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
155 the output.
156
157 Note that %edit is also available through the alias %ed.
158
159 This is an example of creating a simple function inside the editor and
160 then modifying it. First, start up the editor:
161
162 In [1]: ed
163 Editing... done. Executing edited code...
164 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
165
166 We can then call the function foo():
167
168 In [2]: foo()
169 foo() was defined in an editing session
170
171 Now we edit foo. IPython automatically loads the editor with the
172 (temporary) file where foo() was previously defined:
173
174 In [3]: ed foo
175 Editing... done. Executing edited code...
176
177 And if we call foo() again we get the modified version:
178
179 In [4]: foo()
180 foo() has now been changed!
181
182 Here is an example of how to edit a code snippet successive
183 times. First we call the editor:
184
185 In [5]: ed
186 Editing... done. Executing edited code...
187 hello
188 Out[5]: "print 'hello'n"
189
190 Now we call it again with the previous output (stored in _):
191
192 In [6]: ed _
193 Editing... done. Executing edited code...
194 hello world
195 Out[6]: "print 'hello world'n"
196
197 Now we call it with the output #8 (stored in _8, also as Out[8]):
198
199 In [7]: ed _8
200 Editing... done. Executing edited code...
201 hello again
202 Out[7]: "print 'hello again'n"
203
204
205 Changing the default editor hook:
206
207 If you wish to write your own editor hook, you can put it in a
208 configuration file which you load at startup time. The default hook
209 is defined in the IPython.core.hooks module, and you can use that as a
210 starting example for further modifications. That file also has
211 general instructions on how to set a new hook for use once you've
212 defined it."""
213
214 # FIXME: This function has become a convoluted mess. It needs a
215 # ground-up rewrite with clean, simple logic.
216
217 def make_filename(arg):
218 "Make a filename from the given args"
219 try:
220 filename = get_py_filename(arg)
221 except IOError:
222 if args.endswith('.py'):
223 filename = arg
224 else:
225 filename = None
226 return filename
227
228 # custom exceptions
229 class DataIsObject(Exception): pass
230
231 opts,args = self.parse_options(parameter_s,'prn:')
232 # Set a few locals from the options for convenience:
233 opts_p = opts.has_key('p')
234 opts_r = opts.has_key('r')
235
236 # Default line number value
237 lineno = opts.get('n',None)
238
239 if opts_p:
240 args = '_%s' % last_call[0]
241 if not self.shell.user_ns.has_key(args):
242 args = last_call[1]
243
244 # use last_call to remember the state of the previous call, but don't
245 # let it be clobbered by successive '-p' calls.
246 try:
247 last_call[0] = self.shell.displayhook.prompt_count
248 if not opts_p:
249 last_call[1] = parameter_s
250 except:
251 pass
252
253 # by default this is done with temp files, except when the given
254 # arg is a filename
255 use_temp = 1
256
257 if re.match(r'\d',args):
258 # Mode where user specifies ranges of lines, like in %macro.
259 # This means that you can't edit files whose names begin with
260 # numbers this way. Tough.
261 ranges = args.split()
262 data = ''.join(self.extract_input_slices(ranges,opts_r))
263 elif args.endswith('.py'):
264 filename = make_filename(args)
265 data = ''
266 use_temp = 0
267 elif args:
268 try:
269 # Load the parameter given as a variable. If not a string,
270 # process it as an object instead (below)
271
272 #print '*** args',args,'type',type(args) # dbg
273 data = eval(args,self.shell.user_ns)
274 if not type(data) in StringTypes:
275 raise DataIsObject
276
277 except (NameError,SyntaxError):
278 # given argument is not a variable, try as a filename
279 filename = make_filename(args)
280 if filename is None:
281 warn("Argument given (%s) can't be found as a variable "
282 "or as a filename." % args)
283 return
284
285 data = ''
286 use_temp = 0
287 except DataIsObject:
288
289 # macros have a special edit function
290 if isinstance(data,Macro):
291 self._edit_macro(args,data)
292 return
293
294 # For objects, try to edit the file where they are defined
295 try:
296 filename = inspect.getabsfile(data)
297 if 'fakemodule' in filename.lower() and inspect.isclass(data):
298 # class created by %edit? Try to find source
299 # by looking for method definitions instead, the
300 # __module__ in those classes is FakeModule.
301 attrs = [getattr(data, aname) for aname in dir(data)]
302 for attr in attrs:
303 if not inspect.ismethod(attr):
304 continue
305 filename = inspect.getabsfile(attr)
306 if filename and 'fakemodule' not in filename.lower():
307 # change the attribute to be the edit target instead
308 data = attr
309 break
310
311 datafile = 1
312 except TypeError:
313 filename = make_filename(args)
314 datafile = 1
315 warn('Could not find file where `%s` is defined.\n'
316 'Opening a file named `%s`' % (args,filename))
317 # Now, make sure we can actually read the source (if it was in
318 # a temp file it's gone by now).
319 if datafile:
320 try:
321 if lineno is None:
322 lineno = inspect.getsourcelines(data)[1]
323 except IOError:
324 filename = make_filename(args)
325 if filename is None:
326 warn('The file `%s` where `%s` was defined cannot '
327 'be read.' % (filename,data))
328 return
329 use_temp = 0
330 else:
331 data = ''
332
333 if use_temp:
334 filename = self.shell.mktempfile(data)
335 print 'IPython will make a temporary file named:',filename
336
337 payload = {
338 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
339 'filename' : filename,
340 'line_number' : lineno
341 }
342 self.payload_manager.write_payload(payload)
343
344 # # do actual editing here
345 # print 'Editing...',
346 # sys.stdout.flush()
347 # try:
348 # # Quote filenames that may have spaces in them
349 # if ' ' in filename:
350 # filename = "%s" % filename
351 # self.shell.hooks.editor(filename,lineno)
352 # except TryNext:
353 # warn('Could not open editor')
354 # return
355 #
356 # # XXX TODO: should this be generalized for all string vars?
357 # # For now, this is special-cased to blocks created by cpaste
358 # if args.strip() == 'pasted_block':
359 # self.shell.user_ns['pasted_block'] = file_read(filename)
360 #
361 # if opts.has_key('x'): # -x prevents actual execution
362 # print
363 # else:
364 # print 'done. Executing edited code...'
365 # if opts_r:
366 # self.shell.runlines(file_read(filename))
367 # else:
368 # self.shell.safe_execfile(filename,self.shell.user_ns,
369 # self.shell.user_ns)
370 #
371 #
372 # if use_temp:
373 # try:
374 # return open(filename).read()
375 # except IOError,msg:
376 # if msg.filename == filename:
377 # warn('File not found. Did you forget to save?')
378 # return
379 # else:
380 # self.shell.showtraceback()
381
69 InteractiveShellABC.register(ZMQInteractiveShell)
382 InteractiveShellABC.register(ZMQInteractiveShell)
70
383
71
384
General Comments 0
You need to be logged in to leave comments. Login now