File size: 2,548 Bytes
daea45b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""Workspace file tree with git status (Rust-backed)."""
from __future__ import annotations

import re
from dataclasses import dataclass

from .rust_session import (
    git_status,
    rust_available,
    workspace_files,
    workspace_tree,
)

_GIT_LINE = re.compile(r"^([ MADRCU?!]{1,2})\s+(.+)$")


@dataclass
class WorkspacePanel:
    tree_md: str
    git_md: str
    file_choices: list[str]
    preview_md: str


def parse_git_dirty(git_status_text: str) -> dict[str, str]:
    """Map repo-relative path to a one-character git status marker."""
    markers: dict[str, str] = {}
    for line in git_status_text.splitlines():
        m = _GIT_LINE.match(line.strip())
        if not m:
            continue
        status, path = m.group(1).strip(), m.group(2).strip()
        if " -> " in path:
            path = path.split(" -> ")[-1].strip()
        mark = status.replace(" ", "")
        markers[path] = mark[-1] if mark else "?"
    return markers


def _preview_md(path: str, content: str) -> str:
    lang = "python" if path.endswith(".py") else ""
    return f"**`{path}`**\n```{lang}\n{content}\n```"


def build_workspace_panel(
    workspace: str,
    selected: str | None = None,
    *,
    depth: int = 3,
    files: dict[str, str] | None = None,
) -> WorkspacePanel:
    """Build git header, ASCII tree, file picker choices, and file preview."""
    if not rust_available():
        return WorkspacePanel(
            tree_md="_smolcode_core not installed_",
            git_md="",
            file_choices=[],
            preview_md="",
        )

    git_text = git_status(workspace)
    git_lines = git_text.splitlines()
    git_md = "\n".join(git_lines[:6]) if git_lines else "_not a git repository_"

    tree_body = workspace_tree(workspace, depth=depth)
    tree_md = f"```\n{tree_body}\n```"

    if files is None:
        files = workspace_files(workspace)

    dirty = parse_git_dirty(git_text)
    file_choices: list[str] = []
    for path in sorted(files):
        mark = dirty.get(path, "")
        label = f"{mark} {path}" if mark else path
        file_choices.append(label)

    preview_md = ""
    if selected:
        clean = selected
        if len(selected) > 2 and selected[1] == " " and selected[0] in "MADRCU?!":
            clean = selected[2:]
        content = files.get(clean, "")
        if content:
            preview_md = _preview_md(clean, content)

    return WorkspacePanel(
        tree_md=tree_md,
        git_md=git_md,
        file_choices=file_choices,
        preview_md=preview_md,
    )