feat: заменен фреймворк для написания TUI, написана первая рабочая версия TUI

This commit is contained in:
ElectronixTM
2025-04-01 16:24:56 +03:00
parent 13f244d118
commit 8f63f4d09f

View File

@ -1,12 +1,10 @@
from dpdebugger import Debugger from dpdebugger import Debugger
from dataclasses import dataclass from dataclasses import dataclass
from rich import print as rprint
from rich.layout import Layout
from rich.prompt import Prompt
from rich.panel import Panel
from rich.text import Text
from rich.console import Console
import math import math
import py_cui
import py_cui.keys
import re
import shlex
@dataclass @dataclass
class SourceLines: class SourceLines:
@ -14,12 +12,6 @@ class SourceLines:
begining_number: int begining_number: int
lines: list[str] lines: list[str]
@dataclass
class RichedSourceLines:
active: int
begining_number: int
lines: list[Text]
def _get_source_lines( def _get_source_lines(
srcline: int, srcline: int,
lines: list[str], lines: list[str],
@ -49,61 +41,67 @@ def _get_source_lines(
lines=list(lines[start_bound-1:end_bound]) lines=list(lines[start_bound-1:end_bound])
) )
def _source_lines_to_rich(srclines: SourceLines) -> RichedSourceLines: class DebuggerUI:
riched_lines = RichedSourceLines( ACTIVE_LINE_POINTER = "~> "
active=srclines.active, def __init__(self, master: py_cui.PyCUI, debugger: Debugger, src: str):
begining_number=srclines.begining_number, self.master = master
lines=list(map(Text, srclines.lines)) self.dbg = debugger
) self.src = src
active_index = srclines.active - srclines.begining_number self.srclines = src.split('\n')[:-1]
active_line = riched_lines.lines[active_index] self.source_panel = self.master.add_text_block(
active_line.stylize('bold red') "Source code", 0, 0
return riched_lines )
def _join_riched_lines(rl: RichedSourceLines) -> Text: self.prompt_panel = self.master.add_text_box("Prompt",
return Text("\n").join(rl.lines) 1, 0,
row_span=1
)
self.prompt_panel.add_key_command(py_cui.keys.KEY_ENTER, self._process_prompt)
self.terminal_panel = self.master.add_text_block("Debugger Console",
2, 0,
initial_text="to exit type in \"exit\""
)
self.master.move_focus(self.prompt_panel)
self.master.add_key_command(
py_cui.keys.KEY_ENTER,
lambda: self.master.move_focus(self.prompt_panel)
)
self._display_source_lines()
def _generate_source_lines( def _process_prompt(self):
debugger: Debugger, user_input = self.prompt_panel.get()
srcfile: str, if user_input == "exit":
size: int exit()
) -> Panel: self.prompt_panel.clear()
sl = _get_source_lines( dbg_output = self.dbg.do_command(user_input.split())
lines=srcfile.split('\n')[:-1], self.terminal_panel.write(dbg_output)
max_height=size, self._display_source_lines()
srcline=debugger.get_current_source_line_number()
) def _display_source_lines(self):
rl = _source_lines_to_rich(sl) active_line = self.dbg.get_current_source_line_number()
full = _join_riched_lines(rl) lines = _get_source_lines(
return Panel(full) srcline=active_line,
lines=self.srclines,
max_height=self.source_panel.get_viewport_height()
)
# emplace line lumbers
linenos = [lines.begining_number + i
for i in range(len(lines.lines))]
lines_with_linenos: list[str] =[]
# длина самого большого числа для вычисления выравнивания
align_with = len(str(linenos[-1]))
for lineno, line in zip(linenos, lines.lines):
if lineno == lines.active:
padding = len(line) - len(stripped := line.lstrip(" "))
line = self.ACTIVE_LINE_POINTER.rjust(padding) + stripped
lines_with_linenos.append(
f"{str(lineno).rjust(align_with)}. {line}"
)
self.source_panel.set_text("\n".join(lines_with_linenos))
def main(debugger: Debugger, srcfile: str): def main(debugger: Debugger, srcfile: str):
SRC_WIN_HEIGHT = 10 root = py_cui.PyCUI(3, 1)
layout = Layout() root.set_title("Stupid DP32 debugger")
layout.split_column( root.set_status_bar_text("")
Layout( DebuggerUI(root, debugger, srcfile)
_generate_source_lines(debugger, srcfile, SRC_WIN_HEIGHT), root.start()
size=SRC_WIN_HEIGHT,
name="source"),
Layout(name="terminal")
)
layout["source"].update(_generate_source_lines(
debugger=debugger,
srcfile=srcfile,
size=SRC_WIN_HEIGHT
))
print()
rprint(layout)
if __name__ == "__main__":
console = Console()
with open("test.dasm", 'r') as f:
lines = f.read().split('\n')[:-1]
srclines = _get_source_lines(22, lines, 7)
riched = _source_lines_to_rich(srclines)
print(f"focus: {srclines.active}; start: {srclines.begining_number}")
print("_"*20)
# rprint(*riched.lines, sep="\n")
rprint(_join_riched_lines(riched))