title: Python raw_input() replacement that uses a configurable text editor
body: <p>I'm trying to implement a replacement for raw_input() that would use a configurable text editor like vim as the interface to to the user.</p>
  
  <p>The ideal workflow would be like this:</p>
  
  <ol>
  <li>Your python script is running, and makes a call to my_raw_input().</li>
  <li>Vim (or emacs, or gedit, or any other text editor) opens w/ a blank document</li>
  <li>You type some text into the document, then save and exit</li>
  <li>The python script resumes running, with the contents of the file as the return value of my_raw_input().</li>
  </ol>
  
  <p>If you're familiar with git, this is the experience when using <code>git commit</code>, where the editor is configured via <a href="http://git-scm.com/book/en/Customizing-Git-Git-Configuration" rel="nofollow">core.editor</a>. Other utilities like <code>crontab -e</code> also do this.</p>
  
  <p>Ultimately, I would like this my_raw_input() function to also take an optional string w/ the default input contents, which the user could then edit.</p>
  
  <h1>Research so far</h1>
  
  <ul>
  <li><a href="http://docs.python.org/2/library/os.html#os.execl" rel="nofollow">os.exec</a> replaces the current process with the editor command, but does not return. Ie, your python script exits when vim starts.</li>
  <li><a href="http://docs.python.org/2/library/subprocess.html" rel="nofollow">popen</a> does not start the child process interactively, there is no user interface displayed.</li>
  <li>vim has a <code>-</code> command-line parameter to read from stdin, but nothing to write to stdout with <code>:w</code>.</li>
  <li>I took a look at the <a href="https://github.com/git/git/blob/master/run-command.c" rel="nofollow">code for git</a>, which I can't follow at all. </li>
  </ul>
  
  <p>Is this possible?</p>
  
  <h1>Edit</h1>
  
  <p>Good answers so far. I also found the <a href="http://selenic.com/repo/hg-stable/file/2770d03ae49f/mercurial/ui.py" rel="nofollow">mecurial code</a> that's doing the same thing. I also came up with an example that works from looking at the <a href="http://www.opensource.apple.com/source/cron/cron-35/crontab/crontab.c" rel="nofollow">crontab code</a>, but it looks like it's needlessly complicated compared to some of the responses.</p>
  
  <pre><code>#!/usr/bin/python
  import os
  import tempfile
  
  
  def raw_input_editor(default=None, editor=None):
      ''' like the built-in raw_input(), except that it uses a visual
      text editor for ease of editing. Unline raw_input() it can also
      take a default value. '''
  
      editor = editor or get_editor()
  
      with tempfile.NamedTemporaryFile(mode='r+') as tmpfile:
  
          if default:
              tmpfile.write(default)
              tmpfile.flush()
  
          child_pid = os.fork()
          is_child = child_pid == 0
  
          if is_child:
              os.execvp(editor, [editor, tmpfile.name])
          else:
              os.waitpid(child_pid, 0)
              tmpfile.seek(0)
              return tmpfile.read().strip()
  
  
  def get_editor():
      return (os.environ.get('VISUAL')
          or os.environ.get('EDITOR')
          or 'vi')
  
  
  if __name__ == "__main__":
      print raw_input_editor('this is a test')
  </code></pre>