Recipe10.6.Spawning an Editor from a Script


Recipe 10.6. Spawning an Editor from a Script

Credit: Larry Price, Peter Cogolo

Problem

You want users to work with their favorite text-editing programs to edit text files, to provide input to your script.

Solution

Module tempfile lets you create temporary files, and module os has many tools to check the environment and to work with files and external programs, such as text editors. A couple of functions can wrap this functionality into an easy-to-use form:

import sys, os, tempfile def what_editor( ):     editor = os.getenv('VISUAL') or os.getenv('EDITOR')     if not editor:         if sys.platform == 'windows':             editor = 'Notepad.Exe'         else:             editor = 'vi'     return editor def edited_text(starting_text=''):     temp_fd, temp_filename = tempfile.mkstemp(text=True)     os.write(temp_fd, starting_text)     os.close(temp_fd)     editor = what_editor( )     x = os.spawnlp(os.P_WAIT, editor, editor, temp_filename)     if x:         raise RuntimeError, "Can't run %s %s (%s)" % (editor, temp_filename, x)     result = open(temp_filename).read( )     os.unlink(temp_filename)     return result if _ _name_ _=='_ _main_ _':     text = edited_text('''Edit this text a little, go ahead, it's just a demonstration, after all...! ''')     print 'Edited text is:', text

Discussion

Your scripts may often need a substantial amount of textual input from the user. Letting users edit the text with their favorite text editor is an excellent feature for your script to have, and this recipe shows how you can obtain it. I have used variants of this approach for such purposes as adjusting configuration files, writing blog posts, and sending emails.

If your scripts do not need to run on Windows, a more secure and slightly simpler way to code function edited_text is available:

def edited_text(starting_text=''):     temp_file = tempfile.NamedTemporaryFile( )     temp_file.write(starting_text)     temp_file.seek(0)     editor = what_editor( )     x = os.spawnlp(os.P_WAIT, editor, editor, temp_file.name)     if x:         raise RuntimeError, "Can't run %s %s (%s)" % (editor, temp_file.name, x)     return temp_file.read( )

Unfortunately, this alternative relies on the editor we're spawning being able to open and modify the temporary file while we are holding that file open, and this capability is not supported on most versions of Windows. The version of edited_text given in the recipe is more portable.

When you're using this recipe to edit text files that must respect some kind of syntax or other constraints, such as a configuration file, you can make your script simpler and more effective by using a cycle of "input/parse/re-edit in case of errors," providing immediate feedback to users when you can diagnose they've made a mistake in editing the file. Ideally, in such cases, you should reopen the editor already pointing at the line in error, which is possible with most Unix editors by passing them a first argument such as '+23', specifying that they start editing at line 23, before the filename argument. Unfortunately, such an argument would confuse many Windows editors, so you have to make some hard decisions here (if you do need to support Windows).

See Also

Documentation for modules tempfile and os in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net