"""Command completion helpers for VimEditor.""" from __future__ import annotations from pathlib import Path from vimkit.commands import COMMANDS def list_path_matches(cwd: Path, partial: str) -> list[str]: try: if "/" in partial: dir_part, name_part = partial.rsplit("/", 1) base = (cwd / dir_part).expanduser().resolve() prefix = dir_part + "/" lower = name_part.lower() else: base = cwd prefix = "" lower = partial.lower() if not base.is_dir(): return [] return sorted( prefix + path.name + ("/" if path.is_dir() else "") for path in base.iterdir() if lower in path.name.lower() )[:20] except Exception: return [] def compute_command_completions(cmd_buf: str, cwd: Path, commands: dict[str, str] | None = None) -> list[str]: commands = commands or COMMANDS stripped = cmd_buf.lstrip() if not stripped or " " not in stripped: lower = stripped.lower() return [ cmd + (" " if cmd in ("e", "w", "wq", "cd") else "") for cmd in commands if lower in cmd.lower() ] if stripped.startswith("e ") or stripped.startswith("w ") or stripped.startswith("wq "): partial = cmd_buf[2:] if stripped.startswith("wq "): partial = cmd_buf[3:] return list_path_matches(cwd, partial) if stripped.startswith("cd "): partial = cmd_buf[3:] named = [name for name in ("projects", "notebooks") if partial == "" or name.startswith(partial.lower())] file_matches = list_path_matches(cwd, partial) if partial else [] return named + [match for match in file_matches if match not in named] return [] def apply_completion_text(cmd_buf: str, completions: list[str], index: int) -> str: if not completions: return cmd_buf stripped = cmd_buf.lstrip() selected = completions[index % len(completions)] if " " not in stripped: return selected for prefix in ("e ", "w ", "wq ", "cd "): if stripped.startswith(prefix): return prefix + selected return cmd_buf