Spaces:
Sleeping
Sleeping
| """Shell detection utilities for completion generation. | |
| This module provides functionality to detect the current shell type by inspecting | |
| environment variables. This is useful for dynamically generating appropriate completion | |
| scripts for different shell environments. | |
| """ | |
| import os | |
| import subprocess | |
| from pathlib import Path | |
| from typing import Literal | |
| class ShellDetectionError(Exception): | |
| """Raised when the shell type cannot be detected.""" | |
| def _extract_shell_name(shell_string: str) -> Literal["zsh", "bash", "fish"] | None: | |
| """Extract shell name from a string (path or process name). | |
| Parameters | |
| ---------- | |
| shell_string : str | |
| String that may contain a shell name (e.g., "/bin/bash", "zsh", "-bash"). | |
| Returns | |
| ------- | |
| Literal["zsh", "bash", "fish"] | None | |
| The detected shell type, or None if not recognized. | |
| """ | |
| shell_lower = shell_string.lower() | |
| if "zsh" in shell_lower: | |
| return "zsh" | |
| elif "bash" in shell_lower: | |
| return "bash" | |
| elif "fish" in shell_lower: | |
| return "fish" | |
| return None | |
| def detect_shell() -> Literal["zsh", "bash", "fish"]: | |
| """Detect the current shell type using multiple detection methods. | |
| Returns | |
| ------- | |
| Literal["zsh", "bash", "fish"] | |
| The detected shell type. | |
| Raises | |
| ------ | |
| ShellDetectionError | |
| If the shell type cannot be determined from any detection method. | |
| Examples | |
| -------- | |
| >>> shell = detect_shell() # doctest: +SKIP | |
| >>> print(f"Detected shell: {shell}") # doctest: +SKIP | |
| Detected shell: bash | |
| """ | |
| if os.environ.get("ZSH_VERSION"): | |
| return "zsh" | |
| elif os.environ.get("BASH_VERSION"): | |
| return "bash" | |
| elif os.environ.get("FISH_VERSION"): | |
| return "fish" | |
| try: | |
| ppid = os.getppid() | |
| result = subprocess.run( | |
| ["ps", "-p", str(ppid), "-o", "comm="], | |
| capture_output=True, | |
| text=True, | |
| timeout=1, | |
| ) | |
| if result.returncode == 0 and result.stdout: | |
| parent_process = result.stdout.strip() | |
| shell = _extract_shell_name(parent_process) | |
| if shell: | |
| return shell | |
| except (subprocess.SubprocessError, FileNotFoundError, OSError): | |
| pass | |
| shell_path = os.environ.get("SHELL", "") | |
| if shell_path: | |
| shell_name = Path(shell_path).name | |
| shell = _extract_shell_name(shell_name) | |
| if shell: | |
| return shell | |
| raise ShellDetectionError("Unable to detect shell type.") | |