Skip to content

Instantly share code, notes, and snippets.

@alice1017
Last active August 2, 2017 01:39
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 alice1017/1a87bd6792d027a5ef2b06708d22ca71 to your computer and use it in GitHub Desktop.
Save alice1017/1a87bd6792d027a5ef2b06708d22ca71 to your computer and use it in GitHub Desktop.
Enhanced Python Interpreter supported keybind, history, autosuggestion
#!/usr/bin/env python
# coding: utf-8
from __future__ import unicode_literals
import sys
import click
from code import InteractiveConsole
from pygments.lexers import PythonLexer
from pygments.styles.monokai import MonokaiStyle
from prompt_toolkit import prompt as input_console
from prompt_toolkit.keys import Keys
from prompt_toolkit.styles import style_from_pygments
from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.layout.lexers import PygmentsLexer
from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
def make_keybind_registry():
registry = load_key_bindings_for_prompt()
@registry.add_binding(Keys.Tab)
def indent(event):
event.cli.current_buffer.insert_text(" ")
@registry.add_binding(Keys.ControlD)
def bye(event):
event.cli.current_buffer.insert_text("\nBye.")
sys.exit(0)
@registry.add_binding(Keys.ControlE)
def edit(event):
codes = click.edit(extension=".py")
event.cli.current_buffer.insert_text(codes)
return registry
class EnhancedPythonConsole(InteractiveConsole):
def interact(self, banner=None):
"""Closely emulate the interactive Python console.
The optional banner argument specify the banner to print
before the first interaction; by default it prints a banner
similar to the one printed by the real Python interpreter,
followed by the current class name in parentheses (so as not
to confuse this with the real interpreter -- since it's so
close!).
"""
desc = """Key bindings:
* Exit(<Ctrl-D>)
* Tab Space(<Tab>)
* History(<Up>, <Down>)
* Reset Terminal(<Ctrl-L>)
* Edit Code by your editor(<Ctrl-E>)"""
if banner is None:
msg = "Enhanced Python\n"
msg += "Based on {version}\n"
msg += "{desc}\n"
self.write(msg.format(
version=sys.version, platform=sys.platform, desc=desc))
else:
self.write("%s\n" % str(banner))
sys.ps1 = ">>> "
sys.ps2 = "... "
more = 0
history = InMemoryHistory()
while 1:
try:
prompt = sys.ps2 if more else sys.ps1
try:
line = input_console(
prompt, lexer=PygmentsLexer(PythonLexer),
history=history,
auto_suggest=AutoSuggestFromHistory(),
key_bindings_registry=make_keybind_registry(),
style=style_from_pygments(MonokaiStyle)
)
# Can be None if sys.stdin was redefined
encoding = getattr(sys.stdin, "encoding", None)
if encoding and not isinstance(line, unicode):
line = line.decode(encoding)
except EOFError:
self.write("\n")
break
else:
more = self.push(line)
except KeyboardInterrupt:
self.write("\nKeyboardInterrupt\n")
self.resetbuffer()
more = 0
if __name__ == "__main__":
console = EnhancedPythonConsole()
console.interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment