UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

392 lines (389 loc) • 11.2 kB
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url); import { SPECIAL_FILENAMES } from "./chunk-5ZEJHV35.js"; // dist/clients/language-registry.js var LANGUAGES = [ { id: "ada", extensions: [".adb", ".ads"] }, { id: "astro", extensions: [".astro"] }, { id: "c", kind: "cxx", extensions: [".c", ".h"], grammar: "c" }, { id: "clojure", kind: "clojure", extensions: [".clj", ".cljc", ".cljs", ".edn"] }, { id: "cmake", kind: "cmake", extensions: [".cmake"], filenames: ["CMakeLists.txt"] }, { id: "cobol", extensions: [".cob", ".cbl"] }, { id: "cpp", kind: "cxx", // The clang extension table (file-kinds.ts KIND_EXTENSIONS.cxx) minus the // C header/source pair, which the `c` entry owns. `.cuh` deliberately // diverges from clang's table: CUDA/HIP projects use it for C++ headers, // so it must reach the same cpp grammar and clangd path as `.cu`/`.hip`. extensions: [ ".c++", ".c++m", ".cc", ".cl", ".clcpp", ".cp", ".cpp", ".cppm", ".cu", ".cuh", ".cxx", ".cxxm", ".hh", ".hip", ".hpp", ".hxx", ".inl", ".ipp", ".ixx", ".m", ".mm", ".tpp", ".txx" ], grammar: "cpp", // The module-interface (.c++m/.cppm/.cxxm/.ixx), Objective-C (.m/.mm), // OpenCL (.cl/.clcpp) and .cp tail is classified cxx but has never been // routed to the cpp grammar by extension; kind-keyed consumers still // reach cpp through `kindFallback`. grammarExtensions: [ ".c++", ".cc", ".cpp", ".cu", ".cuh", ".cxx", ".hh", ".hip", ".hpp", ".hxx", ".inl", ".ipp", ".tpp", ".txx" ], kindFallback: true }, { id: "csharp", kind: "csharp", extensions: [".cs"], grammar: "csharp" }, { id: "css", kind: "css", extensions: [".css"], grammar: "css" }, { id: "cue", kind: "cue", extensions: [".cue"], grammar: "cue", // The cue grammar and its symbol queries ship, but no extension resolver // has ever routed `.cue` to them; kind-keyed consumers reach it anyway. grammarExtensions: [] }, { id: "dart", kind: "dart", extensions: [".dart"], grammar: "dart" }, { id: "dockerfile", kind: "docker", extensions: [".dockerfile"], filenames: ["Dockerfile"] }, { id: "elixir", kind: "elixir", extensions: [".ex", ".exs"], grammar: "elixir" }, { id: "erlang", extensions: [".erl", ".hrl"] }, { id: "fish", kind: "fish", extensions: [".fish"] }, { id: "fortran", extensions: [".f", ".f90", ".f95"] }, { id: "fsharp", kind: "fsharp", extensions: [".fs", ".fsi", ".fsx"] }, { id: "gleam", kind: "gleam", extensions: [".gleam"] }, { id: "go", kind: "go", extensions: [".go"], grammar: "go" }, // go.mod / go.sum: the LSP id is plain `go`, but they are not Go source and // file-kinds.ts deliberately does not classify them. { id: "go-mod", extensions: [".mod", ".sum"], lspId: "go" }, { id: "graphql", extensions: [".graphql", ".gql"] }, { id: "haskell", kind: "haskell", extensions: [".hs", ".lhs"] }, { id: "helm", kind: "helm-template", extensions: [".tpl"] }, { id: "html", kind: "html", extensions: [".htm", ".html"], grammar: "html", grammarExtensions: [] }, { id: "java", kind: "java", extensions: [".java"], grammar: "java" }, { id: "javascript", kind: "jsts", extensions: [".js", ".mjs", ".cjs"], grammar: "javascript" }, // `.jsx` is JSX-flavoured JavaScript: its own LSP id, but the plain // javascript grammar (which parses JSX) rather than the tsx one. { id: "javascriptreact", kind: "jsts", extensions: [".jsx"], grammar: "javascript" }, { id: "json", kind: "json", extensions: [".json", ".json5"], grammar: "json", grammarExtensions: [] }, { id: "jsonc", kind: "json", extensions: [".jsonc"] }, { id: "julia", extensions: [".jl"] }, { id: "kotlin", kind: "kotlin", extensions: [".kt", ".kts"], grammar: "kotlin" }, { id: "less", kind: "css", extensions: [".less"] }, { id: "lua", kind: "lua", extensions: [".lua"], grammar: "lua" }, { id: "markdown", kind: "markdown", extensions: [".md", ".mdx"] }, { id: "nix", kind: "nix", extensions: [".nix"] }, { id: "ocaml", kind: "ocaml", extensions: [".ml", ".mli"], grammar: "ocaml" }, { id: "pascal", extensions: [".pas", ".pp"] }, { id: "perl", extensions: [".pl", ".pm"] }, { id: "php", kind: "php", extensions: [".php", ".phtml", ".php3", ".php4", ".php5"], grammar: "php" }, { id: "powershell", kind: "powershell", extensions: [".ps1", ".psm1", ".psd1"] }, { id: "prisma", kind: "prisma", extensions: [".prisma"] }, { id: "proto", extensions: [".proto"] }, { id: "python", kind: "python", extensions: [".py", ".pyi"], grammar: "python", // `.pyi` stubs are not routed to the grammar by extension today. grammarExtensions: [".py"] }, { id: "r", extensions: [".r"] }, // Rusty Object Notation: served as `rust` by the LSP seam, not Rust source. { id: "ron", extensions: [".ron"], lspId: "rust" }, { id: "ruby", kind: "ruby", extensions: [".rb", ".rake", ".gemspec", ".ru"], grammar: "ruby", grammarExtensions: [".rb"] }, { id: "rust", kind: "rust", extensions: [".rs"], grammar: "rust" }, { id: "sass", kind: "css", extensions: [".sass"] }, { id: "scala", extensions: [".scala", ".sc"] }, { id: "scss", kind: "css", extensions: [".scss"] }, { id: "shell", kind: "shell", extensions: [".sh", ".bash", ".zsh"], filenames: ["Makefile"], // The LSP spec spells it `shellscript`; the tree-sitter grammar is `bash`. lspId: "shellscript", grammar: "bash", grammarExtensions: [".sh", ".bash"] }, { id: "sql", kind: "sql", extensions: [".sql"] }, { id: "svelte", kind: "jsts", extensions: [".svelte"] }, { id: "swift", kind: "swift", extensions: [".swift"], grammar: "swift" }, { id: "systemverilog", extensions: [".sv"] }, { id: "terraform", kind: "terraform", extensions: [".tf", ".tfvars"] }, { id: "terragrunt", kind: "terragrunt", extensions: [], filenames: ["terragrunt.hcl", "root.hcl"] }, { id: "toml", kind: "toml", extensions: [".toml"], grammar: "toml", grammarExtensions: [] }, { id: "typescript", kind: "jsts", extensions: [".ts", ".mts", ".cts"], grammar: "typescript" }, // `.tsx` needs the tsx grammar (the typescript grammar ERRORs on JSX) and // the LSP spec's `typescriptreact` id. { id: "typescriptreact", kind: "jsts", extensions: [".tsx"], grammar: "tsx" }, { id: "typst", extensions: [".typ", ".typc"] }, { id: "verilog", extensions: [".v"] }, { id: "vhdl", extensions: [".vhd", ".vhdl"] }, { id: "vue", kind: "jsts", extensions: [".vue"], grammar: "vue", // The vue grammar ships as wasm but no extension resolver routes to it; // the jsts fact providers deliberately skip .vue/.svelte (file-kinds.ts). grammarExtensions: [] }, { id: "yaml", kind: "yaml", extensions: [".yaml", ".yml"], grammar: "yaml", grammarExtensions: [] }, { id: "zig", kind: "zig", extensions: [".zig", ".zon"], grammar: "zig", grammarExtensions: [".zig"] } ]; function lspLanguageId(entry) { return entry.lspId ?? entry.id; } function grammarExtensionsOf(entry) { if (!entry.grammar) return []; return entry.grammarExtensions ?? entry.extensions; } var BY_EXTENSION = /* @__PURE__ */ new Map(); var BY_FILENAME = /* @__PURE__ */ new Map(); for (const entry of LANGUAGES) { for (const extension of entry.extensions) { BY_EXTENSION.set(extension.toLowerCase(), entry); } for (const filename of entry.filenames ?? []) { BY_FILENAME.set(filename.toLowerCase(), entry); } } var BY_ID = new Map(LANGUAGES.map((entry) => [entry.id, entry])); function extensionsForLanguage(id) { return BY_ID.get(id)?.extensions ?? []; } var GRAMMAR_TO_EXTENSIONS = Object.freeze((() => { const byGrammar = /* @__PURE__ */ new Map(); for (const entry of LANGUAGES) { if (!entry.grammar) continue; const list = byGrammar.get(entry.grammar) ?? []; list.push(...entry.extensions); byGrammar.set(entry.grammar, list); } return Object.fromEntries([...byGrammar].map(([grammar, extensions]) => [ grammar, Object.freeze([...new Set(extensions)]) ])); })()); function extensionsForLanguageToken(token) { return GRAMMAR_TO_EXTENSIONS[token] ?? extensionsForLanguage(token); } function basenameOf(filePath) { const cut = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\")); return cut === -1 ? filePath : filePath.slice(cut + 1); } function extensionOf(filePath) { const base = basenameOf(filePath); const dot = base.lastIndexOf("."); return dot <= 0 ? "" : base.slice(dot).toLowerCase(); } var BY_KIND = /* @__PURE__ */ new Map(); { const owners = /* @__PURE__ */ new Map(); for (const entry of LANGUAGES) { if (!entry.kind) continue; const list = owners.get(entry.kind) ?? []; list.push(entry); owners.set(entry.kind, list); } for (const [kind, list] of owners) { const resolved = list.length === 1 ? list[0] : list.find((entry) => entry.kindFallback); if (resolved) BY_KIND.set(kind, resolved); } } function resolveLanguage(filePath) { if (!filePath) return void 0; const base = basenameOf(filePath); const byName = BY_FILENAME.get(base.toLowerCase()); if (byName) return byName; const byExtension = BY_EXTENSION.get(extensionOf(filePath)); if (byExtension) return byExtension; for (const { pattern, kind } of SPECIAL_FILENAMES) { if (pattern.test(base)) return BY_KIND.get(kind); } return void 0; } var EXTENSION_TO_LSP_ID = Object.freeze(Object.fromEntries(LANGUAGES.flatMap((entry) => entry.extensions.map((extension) => [extension, lspLanguageId(entry)])))); var EXTENSION_TO_GRAMMAR = Object.freeze(Object.fromEntries(LANGUAGES.flatMap((entry) => grammarExtensionsOf(entry).map((extension) => [extension, entry.grammar])))); var KIND_TO_GRAMMAR = Object.freeze(Object.fromEntries([...BY_KIND.entries()].filter(([, entry]) => Boolean(entry.grammar)).map(([kind, entry]) => [kind, entry.grammar]))); var SCAN_LANGUAGE_PRIORITY = [ ["typescript", "typescriptreact"], ["javascript", "javascriptreact"], ["python"], ["rust"], ["go"], ["ruby"], ["java"], ["kotlin"], ["swift"], ["csharp"], ["cpp"], ["c"], ["zig"], ["haskell"], ["elixir"], ["gleam"], ["terraform"], ["nix"], ["shell"], ["php"], ["lua"], ["dart"], ["vue"], ["svelte"], ["css", "scss", "less"], ["html"], ["json", "jsonc"], ["yaml"], ["toml"], ["prisma"] ]; export { extensionsForLanguage, extensionsForLanguageToken, resolveLanguage, EXTENSION_TO_LSP_ID, EXTENSION_TO_GRAMMAR, KIND_TO_GRAMMAR, SCAN_LANGUAGE_PRIORITY };