Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/idd/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from idd.ui.header import Header
from idd.ui.scrollable_area import TextScrollView

import os
import time


class DiffDebug(App):
CSS_PATH = "layout.tcss"
Expand All @@ -29,6 +32,19 @@ class DiffDebug(App):
base_args = ""
regression_args = ""

# Terminal-specific selection tips
# VSCode : Paste this in user settings: "terminal.integrated.macOptionClickForcesSelection": true
SELECTION_TIPS = {
"Terminal.app": "Option(⌥)+Click to select text OR Cmd(⌘)+R and select",
"iTerm2": "Cmd(⌘)+Shift+C: Copy mode | Option(⌥)+Click: Selection",
"Warp": "Shift+Click to select text",
"vscode": "Option(⌥)+Click",
"default": "Use terminal's selection mechanism to copy text (Maybe Shift+Click)"
}

# Track if we've shown the tip for this panel
tip_shown = False

diff_area1 = TextScrollView(title="Base Diff", component_id="diff-area1")
diff_area2 = TextScrollView(title="Regression Diff", component_id = "diff-area2")
diff_frames1 = TextScrollView(title="Base Stackframe", component_id = "diff-frames1")
Expand Down Expand Up @@ -60,6 +76,10 @@ def __init__(self, disable_asm=False, disable_registers=False, only_base=False):
self.base_history_index = 0
self.regressed_history = [""]
self.regressed_history_index = 0
self._hover_start = 0
self._clicked = False
terminal = self._get_terminal_type()
self.tip = self.SELECTION_TIPS.get(terminal, self.SELECTION_TIPS["default"])

async def set_command_result(self, version) -> None:
state = Debugger.get_state(version)
Expand Down Expand Up @@ -426,6 +446,48 @@ async def on_key(self, event: events.Key) -> None:
self.regressed_command_bar.value = self.regressed_history[self.regressed_history_index]


def _get_terminal_type(self):
"""Try to detect terminal type from environment variables."""
term_program = os.environ.get("TERM_PROGRAM", "")
if "iTerm" in term_program:
return "iTerm2"
elif "Apple_Terminal" in term_program:
return "Terminal.app"
elif "WarpTerminal" in term_program:
return "Warp"
elif "vscode" in term_program:
return "vscode"
return "default"

def on_mouse_down(self, event: events.MouseDown) -> None:
"""Track when the user clicks on the panel."""
self._clicked = True
self._hover_start = time.time() # Start timing from the click

def on_mouse_move(self, event: events.MouseMove) -> None:
"""Show selection tip after clicking and hovering."""
# Only show tip if we've been clicked and haven't shown a tip yet
if self._clicked and not self.tip_shown:
current_time = time.time()
hover_duration = current_time - self._hover_start

# Show tip after 0.1 seconds of hovering after a click
if hover_duration > 0.1:
self.notify(self.tip, severity="information", timeout=3)
self.tip_shown = True

def on_mouse_up(self, event: events.MouseUp) -> None:
"""Reset click state when mouse button is released."""
self._clicked = False
self.tip_shown = False


def on_leave(self, event: events.Leave) -> None:
"""Reset hover timer and click state when mouse leaves the widget."""
self._hover_start = 0
self._clicked = False


Debugger = None
def main() -> None:
global Debugger
Expand Down
2 changes: 1 addition & 1 deletion src/idd/ui/scrollable_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ def append(self, lines: list[str]):

def text(self, lines: list[str]):
self.clear()
self.append(lines)
self.append(lines)