-
Notifications
You must be signed in to change notification settings - Fork 102
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
Idea: Produce intermediate representation from parsing #147
Comments
+1 to this idea. In current pyte implementation, the stream and screen are tightly coupled. It is difficult to inject a customized processor between stream and screen. |
This comment was marked as outdated.
This comment was marked as outdated.
already possible: use a custom # pyte/test_parser.py
# python3 -m pyte.test_parser
# ansi color codes https://gist.github.com/Prakasaka/219fe5695beeb4d6311583e79933a009
#from pyte.screens import Screen, DiffScreen, HistoryScreen, DebugScreen
from .screens import Screen, DiffScreen, HistoryScreen, DebugScreen
#from pyte.streams import Stream, ByteStream
from .streams import Stream, ByteStream
terminal_width = 40
terminal_height = 4
class CustomScreen(Screen):
def draw(self, *args):
print("custom listener: draw", repr(args))
super().draw(*args)
def set_title(self, *args):
print("custom listener: set_title", repr(args))
def select_graphic_rendition(self, *args):
print("custom listener: select_graphic_rendition", repr(args))
screen = CustomScreen(terminal_width, terminal_height)
stream = ByteStream(screen)
stream.feed(b"".join([
b"\x1b", # esc = \e
b"]", # osc
b"2;new title", # params: 2, "new title"
b"\x07", # bel = \a -> end of string
b"\x1b", # esc
b"[", # csi
b"0;31", # params: 0, 31 -> red
b"m", # select_graphic_rendition
b"red", # text
b"\x1b[0;32m", # esc csi green
b"green", # text
b"\x1b[0m", # reset style
b"default", # text
]))
term_lines = screen.display[:] # copy array
for line_idx, line in enumerate(term_lines):
print(f"{line_idx:4d} {line} ¶") output
|
As @milahu points out, this should be doable without any changes to The coupling between |
This was exactly the approach I took at first. It turned out that didn’t give me everything I needed, though. In particular, the information about precisely which bytes were parsed for each call to a |
doable with near-zero overhead https://github.com/milahu/pyte/tree/parser-pass-token-source edit: fixed edgecase where token spans across two data buffers
example useclass CustomScreen(Screen):
last_offset = 0
def draw(self, *args, source=""):
print("custom listener: draw", repr(args)) # source == args[0]
super().draw(*args)
def set_title(self, *args, source=""):
print("custom listener: set_title", repr(args), "source", repr(source))
def select_graphic_rendition(self, *args, source=""):
print("custom listener: select_graphic_rendition", repr(args), "source", repr(source))
screen = CustomScreen(terminal_width, terminal_height)
stream = ByteStream(screen)
# ...
# same code as above output
yepp, for pyte this is just wasted cpu time |
The core of this proposal is to introduce an intermediate form of parsed data between the stream and the screen. Rather than the screen feeding its parsed results directly to the screen, it would generate a stream of objects representing the parsed data, and these could be forwarded to the
Screen
API and potentially other clients. This IR could also be stored, analyzed, replayed, etc.This idea came out of some work I was doing to learn more about control codes. In particular, I borrowed heavily (stole) from pyte's
Stream
class in myParser
implementation. I think this kind of thing could be introduced to pyte with full backwards compatibility, and it would mean I wouldn't need to duplicateStream
. I know this by itself isn't a very compelling argument for modifying pyte, but it might be useful in pyte as well (e.g. I saw some issues related to improving debugging).In any event, I thought I'd float the idea and see what you thought. I should be able to do most of the coding, though of course I'd appreciate any guidance you've got.
The text was updated successfully, but these errors were encountered: