From a0a9d00310f94a834ff3d5acd7407b8a7198e9ff Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 7 Mar 2026 14:57:52 -0500 Subject: [PATCH] feat(gui): Implement @symbol regex parser for on-demand definition lookup --- conductor/tracks.md | 2 +- .../on_demand_def_lookup_20260306/plan.md | 4 +-- src/app_controller.py | 8 ++++++ tests/test_symbol_lookup.py | 27 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 tests/test_symbol_lookup.py diff --git a/conductor/tracks.md b/conductor/tracks.md index 4221375..00a82d0 100644 --- a/conductor/tracks.md +++ b/conductor/tracks.md @@ -59,7 +59,7 @@ This file tracks all major tracks for the project. Each track has its own detail 12. [x] **Track: Manual Skeleton Context Injection** *Link: [./tracks/manual_skeleton_injection_20260306/](./tracks/manual_skeleton_injection_20260306/)* -13. [ ] **Track: On-Demand Definition Lookup** +13. [~] **Track: On-Demand Definition Lookup** *Link: [./tracks/on_demand_def_lookup_20260306/](./tracks/on_demand_def_lookup_20260306/)* --- diff --git a/conductor/tracks/on_demand_def_lookup_20260306/plan.md b/conductor/tracks/on_demand_def_lookup_20260306/plan.md index fba315e..7ca9e73 100644 --- a/conductor/tracks/on_demand_def_lookup_20260306/plan.md +++ b/conductor/tracks/on_demand_def_lookup_20260306/plan.md @@ -5,8 +5,8 @@ ## Phase 1: Symbol Parsing Focus: Parse @symbol syntax from user input -- [ ] Task 1.1: Initialize MMA Environment -- [ ] Task 1.2: Implement @symbol regex parser +- [x] Task 1.1: Initialize MMA Environment +- [~] Task 1.2: Implement @symbol regex parser - WHERE: `src/gui_2.py` in `_send_callback()` - WHAT: Extract @SymbolName patterns - HOW: diff --git a/src/app_controller.py b/src/app_controller.py index a8924da..e666fbb 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -2,6 +2,7 @@ import threading import time import sys import os +import re from typing import Any, List, Dict, Optional, Callable from pathlib import Path import json @@ -38,6 +39,13 @@ def hide_tk_root() -> Tk: root.wm_attributes("-topmost", True) return root +def parse_symbols(text: str) -> list[str]: + """ + Finds all occurrences of '@SymbolName' in text and returns SymbolName. + SymbolName can be a function, class, or method (e.g. @MyClass, @my_func, @MyClass.my_method). + """ + return re.findall(r"@([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)", text) + class GenerateRequest(BaseModel): prompt: str auto_add_history: bool = True diff --git a/tests/test_symbol_lookup.py b/tests/test_symbol_lookup.py new file mode 100644 index 0000000..94d17f8 --- /dev/null +++ b/tests/test_symbol_lookup.py @@ -0,0 +1,27 @@ +import pytest +from src.app_controller import parse_symbols + +def test_parse_symbols_basic(): + text = "Check @MyClass and @my_func." + symbols = parse_symbols(text) + assert symbols == ["MyClass", "my_func"] + +def test_parse_symbols_methods(): + text = "Calling @MyClass.my_method and @AnotherClass.method_name." + symbols = parse_symbols(text) + assert symbols == ["MyClass.my_method", "AnotherClass.method_name"] + +def test_parse_symbols_no_symbols(): + text = "This string has no symbols." + symbols = parse_symbols(text) + assert symbols == [] + +def test_parse_symbols_mixed(): + text = "Mixed text: @Class1, @func_2, and some text @MyClass.method." + symbols = parse_symbols(text) + assert symbols == ["Class1", "func_2", "MyClass.method"] + +def test_parse_symbols_edge_cases(): + text = "@LeadingSymbol and @SymbolAtEnd" + symbols = parse_symbols(text) + assert symbols == ["LeadingSymbol", "SymbolAtEnd"]