joouha / euporie

Jupyter notebooks in the terminal
https://euporie.readthedocs.io
MIT License
1.54k stars 36 forks source link

Contribute to prompt-toolkit? #6

Open davidbrochart opened 3 years ago

davidbrochart commented 3 years ago

I see you have implemented something similar to ScrollablePane in ScrollingContainer (maybe more efficient, or with more features?). Could you tell a bit more about it? Do you think you could contribute upstream in prompt-toolkit?

joouha commented 3 years ago

Yes, absolutely

The ScrollablePane from PT works by rendering all child elements to a virtual screen, then copying only the visible interest to the display. This is not good for performance, especially with a large number of child elements, because every child is redrawn on every refresh.

My ScrollingContainer implementation accepts a list of functions which return child elements, so they can be created on the fly. Instances of child elements are only created for those elements which are currently in view, and only visible children are rendered. When a child is no longer visible, all references to it's instance are dropped, meaning it will be cleaned up by the GC.

Children which are partially visible are drawn by rendering them on a virtual screen, then copying only the visible lines to the display.

The effect of scrolling as achieved by maintaining a reference to the current (selected) child, and it's offset from the top of the available space. Scrolling up or down if done by adjusting this offset. When drawing to the screen, the selected child is drawn first, then the space above and below are then filled with neighbouring children until the available space is full. The child heights are cached to prevent having to render a large number of children just for their heights if the selected child is scrolled a long way off screen.


There are a few things I'm planning to contribute upstream from euporie:

  1. ScrollingContainer - this will need a bit more work to make it more generic, as I built it with the specific use case in mind and I'm not sure how it will work with different types of PT widgets as children

  2. I also implemented clickable scrollbars on the ScrollingContainer (https://github.com/prompt-toolkit/python-prompt-toolkit/issues/773)

  3. I also built on PT's ANSI formatted text parser to allow the conversion of ANSI escape sequences to ZeroWidthEscape sequences. I want to try a different approach to this using regex, which I think might be simpler.

  4. I implemented markdown table rendering in rich using a modified version of CommonMark-py-Extensions (https://github.com/willmcgugan/rich/issues/3)

davidbrochart commented 3 years ago

Thanks for the detailed explanation, this looks great! In nbterm I'm using ScrollablePane and I noticed it doesn't scale well, so I'm really interested in your ScrollingContainer. All these upstream contributions would be really awesome.