Scott Frazer
Scott Frazer

Reputation: 2185

Opening vi from Python

I want to replicate the functionality that happens when you do something like 'git commit'. It opens up your editor and you type some stuff and then save/exit to hand off that file back to the script that launched the editor.

How would I implement this functionality in Python?

EDIT:

Thanks for the suggestions, here's a working example based on the answers:

import os, subprocess, tempfile

(fd, path) = tempfile.mkstemp()
fp = os.fdopen(fd, 'w')
fp.write('default')
fp.close()

editor = os.getenv('EDITOR', 'vi')
print(editor, path)
subprocess.call('%s %s' % (editor, path), shell=True)

with open(path, 'r') as f:
  print(f.read())

os.unlink(path)

Upvotes: 5

Views: 7715

Answers (5)

mensi
mensi

Reputation: 9826

The usual case is to:

  1. Create a temporary file, write default contents to it
  2. Launch the command stored in the environment variable "EDITOR". This usually is a shell command, so it might contain arguments -> run it thourgh the shell or parse it accordingly
  3. Once the process terminates, read back temporary file
  4. Remove temporary file

So something like this:

import os, subprocess, tempfile
f, fname = tempfile.mkstemp()
f.write('default')
f.close()
cmd = os.environ.get('EDITOR', 'vi') + ' ' + fname
subprocess.call(cmd, shell=True)
with open(fname, 'r') as f:
    #read file
os.unlink(fname)

Upvotes: 4

jsbueno
jsbueno

Reputation: 110458

Save the text data you intend to be modified to a temporary file, open the editor (vi) as an external process pointing to that file, using os.system - or subprocess.Popen if you need more control over it, and read the temporary file back.

I'd advise you to open vi by default, but respect the contents of the "VISUAL" environment variable.

import os

name = os.tmpnam()
editor = "vi" if not ["VISUAL"] in os.environ else os.environ["VISUAL"]
os.system("%s %s" % (editor, name))
data = open(name).read()
os.unlink(name)

Upvotes: 1

angusiguess
angusiguess

Reputation: 639

One way to implement this is using subprocess. The code would looks something like this:

import subprocess
subprocess.call(['vi', 'filename.txt'])

The return from this will give the return status of vi.

Upvotes: 0

Doug Harris
Doug Harris

Reputation: 3379

Install ipython and look at the %ed command. See also other suggestions in this similar question

Upvotes: 0

Joran Beasley
Joran Beasley

Reputation: 114018

os.system("\bin\vi %s"%filename)

ftxt = open(filename,"r").read()

Upvotes: 0

Related Questions