1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#!/usr/bin/env python
"""
A simple example of a calculator program.
This could be used as inspiration for a REPL.
"""
from prompt_toolkit.application import Application
from prompt_toolkit.document import Document
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.layout.containers import HSplit, Window
from prompt_toolkit.layout.layout import Layout
from prompt_toolkit.styles import Style
from prompt_toolkit.widgets import SearchToolbar, TextArea
help_text = """
Type any expression (e.g. "4 + 4") followed by enter to execute.
Press Control-C to exit.
"""
def main():
# The layout.
search_field = SearchToolbar() # For reverse search.
output_field = TextArea(style="class:output-field", text=help_text)
input_field = TextArea(
height=1,
prompt=">>> ",
style="class:input-field",
multiline=False,
wrap_lines=False,
search_field=search_field,
)
container = HSplit(
[
output_field,
Window(height=1, char="-", style="class:line"),
input_field,
search_field,
]
)
# Attach accept handler to the input field. We do this by assigning the
# handler to the `TextArea` that we created earlier. it is also possible to
# pass it to the constructor of `TextArea`.
# NOTE: It's better to assign an `accept_handler`, rather then adding a
# custom ENTER key binding. This will automatically reset the input
# field and add the strings to the history.
def accept(buff):
# Evaluate "calculator" expression.
try:
output = f"\n\nIn: {input_field.text}\nOut: {eval(input_field.text)}" # Don't do 'eval' in real code!
except BaseException as e:
output = f"\n\n{e}"
new_text = output_field.text + output
# Add text to output buffer.
output_field.buffer.document = Document(
text=new_text, cursor_position=len(new_text)
)
input_field.accept_handler = accept
# The key bindings.
kb = KeyBindings()
@kb.add("c-c")
@kb.add("c-q")
def _(event):
"Pressing Ctrl-Q or Ctrl-C will exit the user interface."
event.app.exit()
# Style.
style = Style(
[
("output-field", "bg:#000044 #ffffff"),
("input-field", "bg:#000000 #ffffff"),
("line", "#004400"),
]
)
# Run application.
application = Application(
layout=Layout(container, focused_element=input_field),
key_bindings=kb,
style=style,
mouse_support=True,
full_screen=True,
)
application.run()
if __name__ == "__main__":
main()
|