Initial VimKit extraction
This commit is contained in:
67
src/vimkit/completion.py
Normal file
67
src/vimkit/completion.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user