Open Datamance opened 4 years ago
Absolutely, I think something like this should do the job:
#!/usr/bin/env python
from prompt_toolkit.application import Application, get_app
from prompt_toolkit.document import Document
from prompt_toolkit.filters import has_focus
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
def main():
output_field = TextArea(style="class:output-field")
input_field = TextArea(
height=1,
prompt=">>> ",
style="class:input-field",
multiline=False,
wrap_lines=False,
)
container = HSplit(
[
input_field,
Window(height=1, char="-", style="class:line"),
output_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):
output_field.text = ''
get_app().exit(result=buff.text)
input_field.accept_handler = accept
def input_field_changed(_):
output_field.text += 'some output...\n' #·
input_field.buffer.on_text_changed += input_field_changed
# 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.from_dict({
"output-field": "#888888",
"input-field": "bold",
"line": "#004400",
})
# Run application.
application = Application(
layout=Layout(container, focused_element=input_field),
key_bindings=kb,
style=style,
full_screen=False,
)
result = application.run()
print('Got result:', result)
if __name__ == "__main__":
main()
Probably, you also want to use the always_use_tty
option, so that we can still read input from the terminal when other data is piped in:
from prompt_toolkit.input.defaults import create_input
...
application = Application(
...
input=create_input(always_prefer_tty=True)
)
...
Hi there,
I've started building something in the vein of jq/jiq, but for HTML, and you can see a demo of it in this asciicast: .
Right now, I'm doing the input processing and display parts with raw ANSI codes and mostly leveraging termios/tty/os. This has proven quite fiddly; and prompt_toolkit seems pretty mature/has a whole other bunch of nice things, but I would need this one critical feature of character-by-character reading from stdin.
Does prompt_toolkit support this?