chore: python code formatted with ruff, ruff formatter + linter, pyproject.toml now in root
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 18s
Python / lint (pull_request) Failing after 32s
Python / fmt (pull_request) Failing after 37s
Python / test (pull_request) Successful in 52s
C++ / build (pull_request) Successful in 1m56s
Rust / fmt (pull_request) Successful in 1m22s
Rust / build (pull_request) Successful in 2m5s
Python / buildcheck (pull_request) Successful in 2m39s
Rust / clippy (pull_request) Successful in 2m1s
C++ / clang-tidy (pull_request) Successful in 3m46s
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 18s
Python / lint (pull_request) Failing after 32s
Python / fmt (pull_request) Failing after 37s
Python / test (pull_request) Successful in 52s
C++ / build (pull_request) Successful in 1m56s
Rust / fmt (pull_request) Successful in 1m22s
Rust / build (pull_request) Successful in 2m5s
Python / buildcheck (pull_request) Successful in 2m39s
Rust / clippy (pull_request) Successful in 2m1s
C++ / clang-tidy (pull_request) Successful in 3m46s
This commit is contained in:
@@ -10,137 +10,140 @@ ASSETS: Traversable = files("zshell") / "assets" / "schemes"
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemeVariant:
|
||||
id: str
|
||||
name: str
|
||||
modes: frozenset[str]
|
||||
accents: tuple[str, ...] = ()
|
||||
id: str
|
||||
name: str
|
||||
modes: frozenset[str]
|
||||
accents: tuple[str, ...] = ()
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemeMeta:
|
||||
id: str
|
||||
name: str
|
||||
variants: tuple[SchemeVariant, ...]
|
||||
id: str
|
||||
name: str
|
||||
variants: tuple[SchemeVariant, ...]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Palette:
|
||||
colors: dict[str, str]
|
||||
mode: str
|
||||
scheme: str
|
||||
variant: str
|
||||
accent: str | None = None
|
||||
colors: dict[str, str]
|
||||
mode: str
|
||||
scheme: str
|
||||
variant: str
|
||||
accent: str | None = None
|
||||
|
||||
|
||||
def _parse_txt(path: Traversable) -> dict[str, str]:
|
||||
colors: dict[str, str] = {}
|
||||
for line in path.read_text().splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
parts = line.split(None, 1)
|
||||
if len(parts) == 2:
|
||||
key, val = parts
|
||||
colors[key] = f"#{val}" if not val.startswith("#") else val
|
||||
return colors
|
||||
colors: dict[str, str] = {}
|
||||
for line in path.read_text().splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
parts = line.split(None, 1)
|
||||
if len(parts) == 2:
|
||||
key, val = parts
|
||||
colors[key] = f"#{val}" if not val.startswith("#") else val
|
||||
return colors
|
||||
|
||||
|
||||
def _discover_schemes() -> dict[str, SchemeMeta]:
|
||||
schemes: dict[str, SchemeMeta] = {}
|
||||
schemes: dict[str, SchemeMeta] = {}
|
||||
|
||||
for scheme_dir in sorted(ASSETS.iterdir(), key=lambda p: p.name):
|
||||
if not scheme_dir.is_dir() or scheme_dir.name.startswith("."):
|
||||
continue
|
||||
for scheme_dir in sorted(ASSETS.iterdir(), key=lambda p: p.name):
|
||||
if not scheme_dir.is_dir() or scheme_dir.name.startswith("."):
|
||||
continue
|
||||
|
||||
sid = scheme_dir.name
|
||||
display_name = sid.capitalize()
|
||||
sid = scheme_dir.name
|
||||
display_name = sid.capitalize()
|
||||
|
||||
variants: list[SchemeVariant] = []
|
||||
for var_dir in sorted(scheme_dir.iterdir(), key=lambda p: p.name):
|
||||
if not var_dir.is_dir() or var_dir.name.startswith("."):
|
||||
continue
|
||||
variants: list[SchemeVariant] = []
|
||||
for var_dir in sorted(scheme_dir.iterdir(), key=lambda p: p.name):
|
||||
if not var_dir.is_dir() or var_dir.name.startswith("."):
|
||||
continue
|
||||
|
||||
modes: set[str] = set()
|
||||
accents: set[str] = set()
|
||||
modes: set[str] = set()
|
||||
accents: set[str] = set()
|
||||
|
||||
for f in var_dir.iterdir():
|
||||
name = PurePosixPath(f.name)
|
||||
if name.suffix != ".txt":
|
||||
continue
|
||||
stem = name.stem
|
||||
if "-" in stem:
|
||||
maybe_accent, maybe_mode = stem.rsplit("-", 1)
|
||||
if maybe_mode in ("dark", "light"):
|
||||
modes.add(maybe_mode)
|
||||
accents.add(maybe_accent)
|
||||
else:
|
||||
modes.add(stem)
|
||||
else:
|
||||
if stem in ("dark", "light"):
|
||||
modes.add(stem)
|
||||
for f in var_dir.iterdir():
|
||||
name = PurePosixPath(f.name)
|
||||
if name.suffix != ".txt":
|
||||
continue
|
||||
stem = name.stem
|
||||
if "-" in stem:
|
||||
maybe_accent, maybe_mode = stem.rsplit("-", 1)
|
||||
if maybe_mode in ("dark", "light"):
|
||||
modes.add(maybe_mode)
|
||||
accents.add(maybe_accent)
|
||||
else:
|
||||
modes.add(stem)
|
||||
else:
|
||||
if stem in ("dark", "light"):
|
||||
modes.add(stem)
|
||||
|
||||
if modes:
|
||||
vname = var_dir.name.capitalize()
|
||||
variants.append(
|
||||
SchemeVariant(
|
||||
id=var_dir.name,
|
||||
name=vname,
|
||||
modes=frozenset(modes),
|
||||
accents=tuple(sorted(accents)),
|
||||
)
|
||||
)
|
||||
if modes:
|
||||
vname = var_dir.name.capitalize()
|
||||
variants.append(
|
||||
SchemeVariant(
|
||||
id=var_dir.name,
|
||||
name=vname,
|
||||
modes=frozenset(modes),
|
||||
accents=tuple(sorted(accents)),
|
||||
)
|
||||
)
|
||||
|
||||
schemes[sid] = SchemeMeta(
|
||||
id=sid,
|
||||
name=display_name,
|
||||
variants=tuple(variants),
|
||||
)
|
||||
schemes[sid] = SchemeMeta(
|
||||
id=sid,
|
||||
name=display_name,
|
||||
variants=tuple(variants),
|
||||
)
|
||||
|
||||
return schemes
|
||||
return schemes
|
||||
|
||||
|
||||
SCHEMES: dict[str, SchemeMeta] = _discover_schemes()
|
||||
|
||||
|
||||
def get_palette(scheme: str, variant: str, mode: str, accent: str | None = None) -> Palette:
|
||||
if scheme not in SCHEMES:
|
||||
raise KeyError(
|
||||
f"Unknown scheme '{scheme}'. Available: {', '.join(SCHEMES)}")
|
||||
def get_palette(
|
||||
scheme: str, variant: str, mode: str, accent: str | None = None
|
||||
) -> Palette:
|
||||
if scheme not in SCHEMES:
|
||||
raise KeyError(
|
||||
f"Unknown scheme '{scheme}'. Available: {', '.join(SCHEMES)}"
|
||||
)
|
||||
|
||||
meta = SCHEMES[scheme]
|
||||
var_ids = {v.id for v in meta.variants}
|
||||
if variant not in var_ids:
|
||||
raise KeyError(
|
||||
f"Unknown variant '{variant}' for scheme '{scheme}'. Available: {', '.join(sorted(var_ids))}")
|
||||
meta = SCHEMES[scheme]
|
||||
var_ids = {v.id for v in meta.variants}
|
||||
if variant not in var_ids:
|
||||
raise KeyError(
|
||||
f"Unknown variant '{variant}' for scheme '{scheme}'. Available: {', '.join(sorted(var_ids))}"
|
||||
)
|
||||
|
||||
if accent:
|
||||
filename = f"{accent}-{mode}.txt"
|
||||
else:
|
||||
filename = f"{mode}.txt"
|
||||
filename = f"{accent}-{mode}.txt" if accent else f"{mode}.txt"
|
||||
|
||||
txt_path = ASSETS / scheme / variant / filename
|
||||
if not txt_path.is_file():
|
||||
txt_path = ASSETS / scheme / variant / f"{mode}.txt"
|
||||
txt_path = ASSETS / scheme / variant / filename
|
||||
if not txt_path.is_file():
|
||||
txt_path = ASSETS / scheme / variant / f"{mode}.txt"
|
||||
|
||||
if not txt_path.is_file():
|
||||
var_info = next(v for v in meta.variants if v.id == variant)
|
||||
raise FileNotFoundError(
|
||||
f"No {mode} palette for '{scheme}:{variant}'. Available modes: {sorted(var_info.modes)}"
|
||||
)
|
||||
if not txt_path.is_file():
|
||||
var_info = next(v for v in meta.variants if v.id == variant)
|
||||
raise FileNotFoundError(
|
||||
f"No {mode} palette for '{scheme}:{variant}'. Available modes: {sorted(var_info.modes)}"
|
||||
)
|
||||
|
||||
colors = _parse_txt(txt_path)
|
||||
colors = _parse_txt(txt_path)
|
||||
|
||||
return Palette(colors=colors, mode=mode, scheme=scheme, variant=variant, accent=accent)
|
||||
return Palette(
|
||||
colors=colors, mode=mode, scheme=scheme, variant=variant, accent=accent
|
||||
)
|
||||
|
||||
|
||||
def list_schemes() -> dict[str, SchemeMeta]:
|
||||
return dict(SCHEMES)
|
||||
return dict(SCHEMES)
|
||||
|
||||
|
||||
def resolve_preset(spec: str) -> tuple[str, str]:
|
||||
parts = spec.split(":")
|
||||
if len(parts) == 2:
|
||||
return parts[0], parts[1]
|
||||
if len(parts) == 1:
|
||||
return parts[0], "default"
|
||||
raise ValueError(f"Invalid preset spec '{spec}'. Use <scheme>:<variant>")
|
||||
parts = spec.split(":")
|
||||
if len(parts) == 2:
|
||||
return parts[0], parts[1]
|
||||
if len(parts) == 1:
|
||||
return parts[0], "default"
|
||||
raise ValueError(f"Invalid preset spec '{spec}'. Use <scheme>:<variant>")
|
||||
|
||||
Reference in New Issue
Block a user