Last active
August 2, 2017 01:39
-
-
Save alice1017/1a87bd6792d027a5ef2b06708d22ca71 to your computer and use it in GitHub Desktop.
Enhanced Python Interpreter supported keybind, history, autosuggestion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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