""" pylsp plugin: injects i80/LRU packages into import completions. Registered via entry_points group "pylsp" in pyproject.toml. pylsp calls these hooks automatically when the plugin is installed. """ import asyncio import logging from pylsp import hookimpl from .catalog import PypiCatalog logger = logging.getLogger(__name__) # Trigger characters that indicate we're completing an import statement _IMPORT_TRIGGERS = {"import", "from"} def _is_import_context(document, position) -> bool: """Return True if the cursor is on an import line.""" line_num = position["line"] if line_num >= len(document.lines): return False line = document.lines[line_num].strip() return any(line.startswith(kw) for kw in _IMPORT_TRIGGERS) @hookimpl def pylsp_completions(config, workspace, document, position): """Inject i80 pypi packages when completing import statements.""" if not _is_import_context(document, position): return [] # PypiCatalog._packages is populated at startup; safe to read synchronously packages = PypiCatalog._packages if not packages: return [] return [ { "label": pkg["name"], "kind": 9, # Module "detail": "i80 — pypi-server.i80.dk", "sortText": f"{pkg['sort_prefix']}{pkg['name']}", "documentation": { "kind": "markdown", "value": f"**{pkg['name']}**\n\nCustom i80/LRU package from `pypi-server.i80.dk`", }, } for pkg in packages ] @hookimpl def pylsp_hover(config, workspace, document, position): """Show package docs on hover for i80 packages.""" word = document.word_at_position(position) if not word: return None for pkg in PypiCatalog._packages: if pkg["name"] == word: return { "contents": { "kind": "markdown", "value": ( f"**{pkg['name']}** — i80 internal package\n\n" f"Source: `pypi-server.i80.dk`\n\n" f"Install: `pip install {pkg['name']} --index-url https://pypi-server.i80.dk/simple/`" ), } } return None