Description
Description
After working some times with the ConsoleSectionOutput
and SymfonyStyle
class inside the Console Component i found out that the two of them does not work well together and that even the ConsoleSectionOutput
does not handle a lot of use case.
As an example asking a question in a section is very random in term of output given the order of code declaration. The same goes for using a title inside section (extra new lines at some points, max height clearing too many lines, etc ...)
I clearly saw that writing something like this is not trivial so big up to the existing persons that have worked on this, it work well for a lot of use cases.
However i think that to fix some of the remaining use case, and add a lot of nice features it need to have a different logic than the current one.
This RFC is mainly to propose a new solution and talk about it before writing too many codes that may be not wanted into the console component.
To better handle section i would like to add a Terminal Emulator system.
It would act as an OutputInterface and parse the bytes writed to it to decode and handle escaped terminal sequence (like moving up/down/left/right the cursor, writing colored text, etc ....).
Will doing so it would keep the current state of this terminal (where is the cursor, what is the current text format, what is the visible content with the correct size, the non visible content : so we can handle moving the cursor into a non visible part, etc ....)
There is some sources of inspiration that i have see from other languages :
- https://github.com/hinshun/vt10x
- https://github.com/mlochbaum/st
- https://github.com/wez/wezterm/tree/main/term
The goal is to provide a base for terminal emulation for the 80% use case at first (cursor and formatting as a base would be nice) other things like mouse support or edge case espace terminal sequence can be added in the future.
There would also be a way to render a terminal into another terminal at a specific position, which would allow to have the same behavior as the ConsoleSectionOutput
class.
There would also be helper to automatic size those terminal into the main given there current height (so we can mimic the current maxHeight
property of section)
I think having this would definitely allow the ConsoleSectionOutput
to have a better feeling for end user and would fix a lot of edge case.
Example
In my mind user would have to write something like this :
$mainTerminal = Terminal::fromEnv(); // Create a terminal from current environnement
$virtualTerminal1 = new VirtualTerminal(height: 20, cols: 50);
$virtualTerminal2 = new VirtualTerminal(height: 20, cols: 50);
$virtualTerminal3 = new VirtualTerminal(height: 20, cols: 50);
$mainTerminal->attach($virtualTerminal1, x: 0, y: 0);
$mainTerminal->attach($virtualTerminal2, x: 20, y: 0);
$virtualTerminal2->attach($virtualTerminal3, x: 20, y: 0); // Would render starting x at 40 in the main terminal
$virtualTerminal1->write('Foo');
$virtualTerminal2->write('Bar');
$virtualTerminal3->write('Baz');
// This would output
// Foo -> 19 new lines -> Bar -> 19 new lines -> Baz