Source code for simvx.ide.debug_controller

"""Debug and run controller -- breakpoints, stepping, terminal execution."""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .app import IDERoot

log = logging.getLogger(__name__)


[docs] class DebugController: """Manages run/debug actions for the IDE. Handles launching scripts, breakpoint toggling, and debugger stepping. """ def __init__(self, ide: IDERoot) -> None: self._ide = ide # -- Convenience accessors ------------------------------------------------ @property def _debug_manager(self): return self._ide._debug_manager @property def _bottom_tabs(self): return self._ide._bottom_tabs @property def _terminal_panel(self): return self._ide._terminal_panel @property def state(self): return self._ide.state # -- Run ------------------------------------------------------------------
[docs] def on_run_file(self): if not self.state.active_file: return if self.state.active_file.startswith("untitled"): self.state.status_message.emit("Save file first before running") return # If breakpoints exist and debug manager available, use debugger if self._debug_manager and self.state.get_all_breakpoints(): self._debug_manager.start_debug(self.state.active_file) self._ide._show_bottom_panel() if self._bottom_tabs: tab_controls = [c for c in self._bottom_tabs.children if hasattr(c, "visible")] for i, c in enumerate(tab_controls): if getattr(c, "name", "") == "Debug": self._bottom_tabs.current_tab = i self._bottom_tabs._update_layout() break self.state.status_message.emit("Debugging started...") else: self.state.run_requested.emit(self.state.active_file)
[docs] def on_run_no_debug(self): if self.state.active_file: self._run_in_terminal(self.state.active_file)
[docs] def on_run_requested(self, path: str): self._run_in_terminal(path)
def _run_in_terminal(self, path: str): self._ide._show_bottom_panel() self._ide._switch_to_tab("Terminal") if self._terminal_panel: self._terminal_panel.run_file(path) # -- Breakpoints ----------------------------------------------------------
[docs] def on_toggle_breakpoint(self): if self.state.active_file: self.state.toggle_breakpoint(self.state.active_file, self.state.cursor_line)
# -- Stepping -------------------------------------------------------------
[docs] def on_step_over(self): if self._debug_manager: self._debug_manager.step_over()
[docs] def on_step_into(self): if self._debug_manager: self._debug_manager.step_into()
[docs] def on_step_out(self): if self._debug_manager: self._debug_manager.step_out()
[docs] def on_stop_debug(self): if self._debug_manager: self._debug_manager.stop_debug() self.state.debug_stopped.emit()
[docs] def on_restart_debug(self): if self._debug_manager: path = self.state.active_file self._debug_manager.stop_debug() if path: self._debug_manager.start_debug(path)