tr
This commit is contained in:
@@ -37,6 +37,8 @@ if str(SRC_DIR) not in sys.path:
|
||||
|
||||
from cli_renderers import Renderer # noqa: E402
|
||||
from tarot import Card, Tarot, Tree, Cube # noqa: E402
|
||||
import tarot.ui as ui_mod # noqa: E402
|
||||
from tarot.ui import SpreadDisplay, display_cards as ui_display_cards # noqa: E402
|
||||
|
||||
|
||||
app = typer.Typer(add_completion=True, help="CLI playground for the Tarot API.")
|
||||
@@ -56,6 +58,7 @@ SAFE_ROOTS: Dict[str, Any] = {
|
||||
"tree": Tree,
|
||||
"cube": Cube,
|
||||
"letter": letter_ns,
|
||||
"ui": ui_mod,
|
||||
}
|
||||
|
||||
_MISSING_DOCS: Set[str] = set()
|
||||
@@ -69,6 +72,8 @@ ROOT_COMMANDS = [
|
||||
"tree",
|
||||
"cube",
|
||||
"letter",
|
||||
"display-cards",
|
||||
"display-spread",
|
||||
"help",
|
||||
"quit",
|
||||
"exit",
|
||||
@@ -186,6 +191,10 @@ def _periodic_symbols() -> List[str]:
|
||||
return list(periodic.keys()) if isinstance(periodic, dict) else []
|
||||
|
||||
|
||||
def _spread_names() -> List[str]:
|
||||
return list(SpreadDisplay.LAYOUTS.keys())
|
||||
|
||||
|
||||
def _current_fragment(text: str) -> str:
|
||||
stripped = text.rstrip()
|
||||
if not stripped:
|
||||
@@ -269,6 +278,9 @@ def _completion_candidates(text: str) -> List[str]:
|
||||
if len(tokens) == 3 and tokens[1].lower() == "periodic":
|
||||
return [s for s in _periodic_symbols() if s.lower().startswith(fragment)]
|
||||
|
||||
if cmd == "display-spread":
|
||||
return [name for name in _spread_names() if name.lower().startswith(fragment)]
|
||||
|
||||
if cmd == "search":
|
||||
# Simple heuristics: suggest option flags or option values based on prior flag
|
||||
if last_token.startswith("-"):
|
||||
@@ -399,6 +411,9 @@ def _print_structure_table() -> None:
|
||||
"Draw a spread with random cards",
|
||||
"tarot.deck.card.spread('Celtic Cross')",
|
||||
),
|
||||
("ui.display_cards([card1, card2])", "Open GUI to view cards", "ui.display_cards([tarot.deck.card(1)])"),
|
||||
("display-spread 'Celtic Cross'", "CLI: draw + show spread", "python typer-test.py display-spread 'Celtic Cross'"),
|
||||
("display-cards 1 2 3", "CLI: show specific cards", "python typer-test.py display-cards 1 2 3"),
|
||||
("tarot.planet()", "Planet correspondences as dict", "tarot.planet()['Venus']"),
|
||||
("tarot.hexagram()", "I Ching hexagrams as dict", "tarot.hexagram()[1]"),
|
||||
("tree.sephera(n)", "Kabbalistic sephiroth", "tree.sephera(1)"),
|
||||
@@ -784,6 +799,39 @@ def _handle_repl_command(parts: List[str], raw_line: str = "") -> bool:
|
||||
console.print("No cards matched that filter.")
|
||||
else:
|
||||
_print_cards_table(cards)
|
||||
|
||||
|
||||
@app.command("display-cards")
|
||||
def display_cards_cmd(
|
||||
numbers: List[int] = typer.Argument(..., help="Card numbers to display"),
|
||||
deck_name: str = typer.Option("default", help="Deck name for UI display"),
|
||||
) -> None:
|
||||
"""Open a GUI window showing the given card numbers."""
|
||||
|
||||
_ensure_deck()
|
||||
cards: List[Card] = []
|
||||
for num in numbers:
|
||||
card = Tarot.deck.card(num) # type: ignore[attr-defined]
|
||||
if card is None:
|
||||
typer.echo(f"Card {num} not found.")
|
||||
raise typer.Exit(code=1)
|
||||
cards.append(card)
|
||||
ui_display_cards(cards, deck_name)
|
||||
|
||||
|
||||
@app.command("display-spread")
|
||||
def display_spread_cmd(
|
||||
spread_name: str = typer.Argument("Celtic Cross", help="Spread name (e.g., 'Celtic Cross')"),
|
||||
deck_name: str = typer.Option("default", help="Deck name for UI display"),
|
||||
) -> None:
|
||||
"""Draw a spread and open the GUI display for it."""
|
||||
|
||||
_ensure_deck()
|
||||
reading = Tarot.deck.card.spread(spread_name) # type: ignore[attr-defined]
|
||||
if reading is None:
|
||||
typer.echo(f"Spread '{spread_name}' not found.")
|
||||
raise typer.Exit(code=1)
|
||||
ui_mod.display_spread(reading, deck_name)
|
||||
return True
|
||||
if cmd == "planet":
|
||||
planet_name = parts[1] if len(parts) > 1 else None
|
||||
@@ -800,6 +848,52 @@ def _handle_repl_command(parts: List[str], raw_line: str = "") -> bool:
|
||||
return True
|
||||
_render_value(planet_obj)
|
||||
return True
|
||||
if cmd == "display-cards":
|
||||
if len(parts) < 2:
|
||||
console.print("Usage: display-cards <card numbers...>")
|
||||
console.print("Examples: display-cards 1 2 3")
|
||||
console.print(" display-cards 2,11,20")
|
||||
return True
|
||||
_ensure_deck()
|
||||
nums: List[int] = []
|
||||
|
||||
# Handle both space-separated and comma-separated numbers
|
||||
tokens = []
|
||||
for tok in parts[1:]:
|
||||
# Split by comma if present
|
||||
if "," in tok:
|
||||
tokens.extend(tok.split(","))
|
||||
else:
|
||||
tokens.append(tok)
|
||||
|
||||
for tok in tokens:
|
||||
tok = tok.strip()
|
||||
if not tok:
|
||||
continue
|
||||
try:
|
||||
nums.append(int(tok))
|
||||
except ValueError:
|
||||
console.print(f"Invalid card number: {tok}")
|
||||
return True
|
||||
|
||||
cards: List[Card] = []
|
||||
for num in nums:
|
||||
card = Tarot.deck.card(num) # type: ignore[attr-defined]
|
||||
if card is None:
|
||||
console.print(f"Card {num} not found.")
|
||||
return True
|
||||
cards.append(card)
|
||||
ui_display_cards(cards)
|
||||
return True
|
||||
if cmd == "display-spread":
|
||||
spread_name = " ".join(parts[1:]) if len(parts) > 1 else "Celtic Cross"
|
||||
_ensure_deck()
|
||||
reading = Tarot.deck.card.spread(spread_name) # type: ignore[attr-defined]
|
||||
if reading is None:
|
||||
console.print(f"Spread '{spread_name}' not found.")
|
||||
return True
|
||||
ui_mod.display_spread(reading)
|
||||
return True
|
||||
if cmd == "hexagram":
|
||||
hex_num = None
|
||||
if len(parts) > 1 and parts[1].isdigit():
|
||||
|
||||
Reference in New Issue
Block a user