Welcome, guest | Sign In | My Account | Store | Cart

Here's a function that lets you use Python to wrap calls to an external editor. The editor can be an command line editor, like venerable old "ed", or something more powerful like nano, vim or emacs, and even GUI editors. After the editor quits, the text you typed in the editor is returned by the function.

A simple example, using the (rather cryptic) 'ed' editor on Linux. For the benefit of those unfamiliar with 'ed', I have annotated the editor session with comments.

>>> status, text = edit('ed')
0                        ## ed prints the initial number of lines
a                        ## start "append" mode
Hello World!
Goodbye now
.                        ## stop appending
w                        ## write the file to disk
25                       ## ed prints the number of bytes written
q                        ## quit ed and return to Python
>>> status
0
>>> print text
Hello World!
Goodbye now
Python, 14 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import os, tempfile

def edit(editor, content=''):
    f = tempfile.NamedTemporaryFile(mode='w+')
    if content:
        f.write(content)
        f.flush()
    command = editor + " " + f.name
    status = os.system(command)
    f.seek(0, 0)
    text = f.read()
    f.close()
    assert not os.path.exists(f.name)
    return (status, text)

The edit function takes two arguments, the first is the mandatory editor, the second is an optional string used as the initial text in the editor.

edit returns a tuple with two values:

  • the exit status of the call to the editor;

  • the text in the editor as it was saved by the user.

A non-zero exit status often (but not always) indicates that something went wrong and the editor could not be called, e.g. the editor doesn't exist, or the file couldn't be saved. Consult the documentation for the editor to understand the meaning of any specific exit status. If the user exits the editor without saving, their edits will naturally be lost.

Tested successfully on Linux with ed, nano, vim, emacs and kwrite. This should work on any editor which writes directly to the file it is given. May not work with all editors: for example, it fails to pick up the newly edited text in Gnome gedit 2.16.0. I'm not entirely sure why, but my guess is that gedit doesn't actually write directly to the file given, instead it writes to a different file, then renames the second file over the top of the original.

1 comment

Steven D'Aprano (author) 7 years, 3 months ago  # | flag

By the way, I thought it went without saying, but an acquaintance insists it needs to be said: don't get the name of the editor from an untrusted source.