Skip to content

Instantly share code, notes, and snippets.

@1st1
Last active December 17, 2015 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1st1/5569467 to your computer and use it in GitHub Desktop.
Save 1st1/5569467 to your computer and use it in GitHub Desktop.
An extension for python REPL, inspired by PostgreSQL shell. Write '\e' to open an external editor for commands, '\r' to reset the buffer.
##
# Copyright 2013 Yury Selivanov <yselivanov@sprymix.com>
# License: MIT
##
import code
import subprocess
import os
import sys
import tempfile
try:
import readline
except ImportError:
readline = None
class Console(code.InteractiveConsole):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.editor = os.environ.get('EDITOR', 'vim')
self.tmp = None
self.new_buffer()
def show_editor(self):
subprocess.call([self.editor, self.tmp.name])
def new_buffer(self, text=None):
if self.tmp:
self.tmp.close()
self.tmp = tempfile.NamedTemporaryFile('w+t', suffix=".py")
if text:
self.tmp.write(text)
self.tmp.flush()
def push(self, line):
self.buffer.append(line)
source = "\n".join(self.buffer)
more = self.runsource(source, self.filename)
if not more:
if source.strip():
self.new_buffer(text=source)
self.resetbuffer()
return more
def raw_input(self, prompt=''):
line = input(prompt)
if line.count('\n') > 0:
self.new_buffer(text=line)
self.runsource(line, self.filename, 'exec')
return ''
if line == r'\e':
self.show_editor()
with open(self.tmp.name, 'rt') as buffer:
lines = buffer.read().strip('\n')
if readline:
readline.add_history(lines)
print(lines)
self.runsource(lines, self.filename, 'exec')
return ''
if line == r'\r':
self.new_buffer()
return ''
if line == r'\?':
print(r'\e', ' ' * 10, 'edit the console buffer with external editor')
print(r'\r', ' ' * 10, 'reset (clear) the buffer')
return ''
return line
def __enter__(self):
return self
def __exit__(self, *exc):
if self.tmp:
self.tmp.close()
if __name__ == '__main__':
with Console() as console:
console.interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment