mac support

This commit is contained in:
2026-08-26 13:45:15 +02:00
parent 15d1319374
commit a9897606ac
6 changed files with 115 additions and 21 deletions
+51 -7
View File
@@ -8,6 +8,12 @@ import sys
from pathlib import Path
from typing import Literal
MACOS_EXECUTABLE_DIRECTORIES = (
Path("/opt/homebrew/bin"),
Path("/usr/local/bin"),
Path("/Library/TeX/texbin"),
)
WINDOWS_RESERVED_NAMES = {
"CON",
"PRN",
@@ -71,6 +77,36 @@ def safe_filename(value: str, fallback: str = "Unknown") -> str:
return cleaned
def add_platform_executable_paths(
environment: dict[str, str], platform_name: str | None = None
) -> dict[str, str]:
"""Expose common desktop-installed executables to child processes."""
result = dict(environment)
if (platform_name or sys.platform) != "darwin":
return result
existing = result.get("PATH", "").split(os.pathsep)
additions = [str(path) for path in MACOS_EXECUTABLE_DIRECTORIES if path.is_dir()]
result["PATH"] = os.pathsep.join(dict.fromkeys([*additions, *existing]))
return result
def find_executable(
*candidates: str, platform_name: str | None = None
) -> str | None:
"""Find a command in PATH or in standard macOS package locations."""
for candidate in candidates:
executable = shutil.which(candidate)
if executable:
return executable
if (platform_name or sys.platform) == "darwin":
for directory in MACOS_EXECUTABLE_DIRECTORIES:
for candidate in candidates:
executable = directory / candidate
if executable.is_file() and os.access(executable, os.X_OK):
return str(executable)
return None
def open_path(path: str | Path) -> None:
"""Open a file with the desktop's default application."""
target = str(Path(path).expanduser().resolve())
@@ -78,17 +114,26 @@ def open_path(path: str | Path) -> None:
os.startfile(target) # type: ignore[attr-defined]
elif sys.platform.startswith("linux"):
subprocess.Popen(["xdg-open", target])
elif sys.platform == "darwin":
opener = find_executable("open") or "/usr/bin/open"
subprocess.Popen([opener, target])
else:
raise RuntimeError(f"Unsupported platform: {sys.platform}")
def launch_pdf_arranger(path: str | Path) -> None:
executable = shutil.which("pdf-arranger") or shutil.which("pdfarranger")
if not executable:
raise FileNotFoundError(
"PDF Arranger is not installed or is not available in PATH."
)
subprocess.Popen([executable, str(Path(path).expanduser().resolve())])
target = str(Path(path).expanduser().resolve())
executable = find_executable("pdf-arranger", "pdfarranger")
if executable:
subprocess.Popen([executable, target])
return
if sys.platform == "darwin":
opener = find_executable("open") or "/usr/bin/open"
subprocess.Popen([opener, "-b", "com.apple.Preview", target])
return
raise FileNotFoundError(
"PDF Arranger is not installed or is not available in PATH."
)
def replace_with_link_or_copy(
@@ -118,4 +163,3 @@ def replace_with_link_or_copy(
shutil.copy2(source_path, destination_path)
return "copy"