diff --git a/src/dbg_tui.py b/src/dbg_tui.py index 4bd6294..d81190d 100644 --- a/src/dbg_tui.py +++ b/src/dbg_tui.py @@ -1,12 +1,10 @@ from dpdebugger import Debugger 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 py_cui +import py_cui.keys +import re +import shlex @dataclass class SourceLines: @@ -14,12 +12,6 @@ class SourceLines: begining_number: int lines: list[str] -@dataclass -class RichedSourceLines: - active: int - begining_number: int - lines: list[Text] - def _get_source_lines( srcline: int, lines: list[str], @@ -49,61 +41,67 @@ def _get_source_lines( lines=list(lines[start_bound-1:end_bound]) ) -def _source_lines_to_rich(srclines: SourceLines) -> RichedSourceLines: - riched_lines = RichedSourceLines( - active=srclines.active, - begining_number=srclines.begining_number, - lines=list(map(Text, srclines.lines)) - ) - active_index = srclines.active - srclines.begining_number - active_line = riched_lines.lines[active_index] - active_line.stylize('bold red') - return riched_lines +class DebuggerUI: + ACTIVE_LINE_POINTER = "~> " + def __init__(self, master: py_cui.PyCUI, debugger: Debugger, src: str): + self.master = master + self.dbg = debugger + self.src = src + self.srclines = src.split('\n')[:-1] + self.source_panel = self.master.add_text_block( + "Source code", 0, 0 + ) + + self.prompt_panel = self.master.add_text_box("Prompt", + 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 _join_riched_lines(rl: RichedSourceLines) -> Text: - return Text("\n").join(rl.lines) + def _process_prompt(self): + user_input = self.prompt_panel.get() + if user_input == "exit": + exit() + self.prompt_panel.clear() + dbg_output = self.dbg.do_command(user_input.split()) + self.terminal_panel.write(dbg_output) + self._display_source_lines() -def _generate_source_lines( - debugger: Debugger, - srcfile: str, - size: int - ) -> Panel: - sl = _get_source_lines( - lines=srcfile.split('\n')[:-1], - max_height=size, - srcline=debugger.get_current_source_line_number() - ) - rl = _source_lines_to_rich(sl) - full = _join_riched_lines(rl) - return Panel(full) + def _display_source_lines(self): + active_line = self.dbg.get_current_source_line_number() + lines = _get_source_lines( + 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): - SRC_WIN_HEIGHT = 10 - layout = Layout() - layout.split_column( - Layout( - _generate_source_lines(debugger, srcfile, SRC_WIN_HEIGHT), - 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)) - + root = py_cui.PyCUI(3, 1) + root.set_title("Stupid DP32 debugger") + root.set_status_bar_text("") + DebuggerUI(root, debugger, srcfile) + root.start()