feat(language-server): merge HTML completions and hover into one response

This commit is contained in:
2026-08-18 20:56:17 +05:30
parent d77638131b
commit 97801287f9
5 changed files with 22543 additions and 14 deletions
+33 -1
View File
@@ -1,4 +1,12 @@
import { getLanguageService, TextDocument as HtmlTextDocument } from "vscode-html-languageservice";
// The default `main` entrypoint is a UMD bundle whose internal AMD-style
// `require("./parser/htmlScanner")` calls survive bundling literally instead
// of being inlined, so a bundled language server fails at runtime with
// "Cannot find module './parser/htmlScanner'". The ESM entrypoint bundles
// cleanly, so import it explicitly.
import {
getLanguageService,
TextDocument as HtmlTextDocument,
} from "vscode-html-languageservice/lib/esm/htmlLanguageService.js";
import { isInsideHtml, virtualHtmlDocument } from "./html-regions.ts";
import { offsetAt, type Position, type TextDocument } from "./index.ts";
@@ -126,3 +134,27 @@ export function htmlTagComplete(document: TextDocument, position: Position): str
return selfClosingTagCompletion(document.text, offset);
}
/**
* One completion list from both sources.
*
* WRNexus entries take the `0` sortText prefix so they rank above HTML without
* either list being filtered. An exact label collision resolves to the
* WRNexus entry: a component named `Table` is what the author meant.
*/
interface CompletionLike {
label: string;
kind?: number;
sortText?: string;
}
export function mergeCompletions(
wrnexus: CompletionLike[],
html: CompletionLike[],
): CompletionLike[] {
const taken = new Set(wrnexus.map((item) => item.label));
return [
...wrnexus.map((item) => ({ ...item, sortText: `0${item.sortText ?? item.label}` })),
...html.filter((item) => !taken.has(item.label)),
];
}