Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a ptpython pane inside another prompt_toolkit UI #450

Closed
AnthonyDiGirolamo opened this issue Apr 6, 2021 · 1 comment · Fixed by #454
Closed

Creating a ptpython pane inside another prompt_toolkit UI #450

AnthonyDiGirolamo opened this issue Apr 6, 2021 · 1 comment · Fixed by #454

Comments

@AnthonyDiGirolamo
Copy link
Contributor

Hi @jonathanslenders I'm hoping you can give me some advice here. We are trying to build a prompt_toolkit app for interacting with devices over pyserial. We'd like it to be a full screen app and have at least two panes: one for displaying log messages from pyserial connected devices and one for an interactive python repl.

Screenshot_2021-04-06_11-26-02
Here's the layout:

self.python_pane = PythonPane()
self.root_container = FloatContainer(
    content=HSplit(
        [
            self.top_toolbar,
            self.log_pane,
            self.split_window,
            self.python_pane.window,
            self.bottom_toolbar,
        ],
    ),
    floats=[
        # Message Echo Area
        Float(bottom=1, left=0, right=0, height=1,
                content=MessageToolbarBar(self)),
        # Floating Help Window
        Float(
            content=HelpWindow(self),
            right=2, top=2,
        ),
    ],
)

To kick off the pt app I have:

async def run(self):
    """Start the prompt_toolkit UI."""
    background_log_task = asyncio.create_task(self.log_forever())
    try:
        unused_result = await self.application.run_async(
            set_exception_handler=True)
    finally:
        background_log_task.cancel()
    print("Quitting event loop. Bye.")

The PythonPane() class is a bunch of stuff copy pasted (for experimentation) from ptpython/repl.py and ptpython/python_input.py but without the bits to create a new a new prompt_toolkit application (from here). I also moved a bunch of logic from run() and eval() here in repl.py and moved it into the _accept_handler here

The goal being to allow embeding into an existing app. Some questions:

  1. Is this a good way to do this? If yes would you accept a pull request to support this use case? I think it would have to refactor the parts that create a new app and layout outside of the PythonInput class and provide an example of how to override the accept_handler.
  2. Am I better off writing my own repl like https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/examples/full-screen/calculator.py
  3. Can ipython support rendering other prompt_toolkit containers in it's UI that are updated asynchronously?

Thanks for any feedback you can provide!

@AnthonyDiGirolamo
Copy link
Contributor Author

AnthonyDiGirolamo commented Apr 19, 2021

Ok so I have this somewhat working with this change: AnthonyDiGirolamo@1e95086

It allows to us to create our own PwPtPythonRepl(repl.PythonRepl) class. Like this: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/41580/9/pw_console/py/pw_console/pw_ptpython_repl.py Which can be part of our prompt_toolkit app.

Currently it just logs the results instead of printing them. I still need to figure out how to make this bit not print to stdout and just return the formatted text instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant