// Server Registry - Maps a language id (or file extension) to an LSP server // launcher plus the root markers that identify a project boundary. // // Add new servers here. `match` is a list of file extensions (no dot) OR // language ids; either matches. import * as fs from "node:fs"; import * as path from "node:path"; import type { ServerConfig } from "./src/types.ts"; // Resolve Python Path - Prefer the project's virtualenv when present so // Pyright sees the same interpreter/dependencies as project commands. function resolvePythonPath(rootDir: string): string | undefined { const candidates = [ path.join(rootDir, ".venv", "bin", "python"), path.join(rootDir, "venv", "bin", "python"), ]; return candidates.find((candidate) => fs.existsSync(candidate)); } // Pyright Settings - Minimal editor settings needed for diagnostics and import // resolution. Shared by workspace/configuration and didChangeConfiguration. function pyrightSettings(rootDir: string): { pythonPath: string | undefined; analysis: { diagnosticMode: string; typeCheckingMode: string; autoSearchPaths: boolean; useLibraryCodeForTypes: boolean; }; } { return { pythonPath: resolvePythonPath(rootDir), analysis: { diagnosticMode: "openFilesOnly", typeCheckingMode: "basic", autoSearchPaths: true, useLibraryCodeForTypes: true, }, }; } // Global Root Markers — appended to every server's rootMarkers list export const globalRootMarkers = [".git"]; export const servers: ServerConfig[] = [ { id: "gopls", match: ["go"], command: "gopls", args: ["-remote=auto"], rootMarkers: ["go.work", "go.mod"], languageId: "go", }, { id: "typescript-language-server", match: ["ts", "tsx", "js", "jsx", "mts", "cts"], command: "typescript-language-server", args: ["--stdio"], rootMarkers: ["pnpm-workspace.yaml", "tsconfig.json", "package.json"], languageId: "typescript", }, { id: "pyright", match: ["py"], command: "pyright-langserver", args: ["--stdio"], rootMarkers: ["pyproject.toml", "setup.py", "setup.cfg"], languageId: "python", workspaceConfiguration: { initialSettings: ({ rootDir }) => ({ python: pyrightSettings(rootDir) }), getSection: (section, { rootDir }) => { const settings = pyrightSettings(rootDir); if (section === "python") return settings; if (section === "python.analysis") return settings.analysis; return null; }, }, }, { id: "lua-language-server", match: ["lua"], command: "lua-language-server", args: [], rootMarkers: [".luarc.json"], languageId: "lua", }, { id: "vscode-html-language-server", match: ["html", "css", "jsonl", "jsonc", "json"], command: "vscode-html-language-server", args: ["--stdio"], rootMarkers: ["package.json"], languageId: "html", }, { id: "nil", match: ["nix"], command: "nil", args: [], rootMarkers: ["flake.nix"], languageId: "nix", }, { id: "oxlint", match: ["ts", "tsx", "js", "jsx", "mjs", "cjs"], command: "oxlint", args: ["--lsp"], rootMarkers: [".oxlintrc.json", "oxlint.config.json"], languageId: "typescript", diagnosticsOnly: true, }, ];