feat(vscode): close HTML tags as they are typed in .wrn files

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 21:16:47 +05:30
co-authored by Claude Opus 5
parent d9e8f5be82
commit e83f0366ef
6 changed files with 179 additions and 33 deletions
+54 -29
View File
@@ -1,8 +1,7 @@
#!/usr/bin/env node
// WRN editor language server source hash: 1317c4e318ab938fffab3dd5b65655b0e220a81c481c9fa92f23706ede60303c
// WRN editor language server source hash: 1bda85712569242c96adb5fe2512cc07a59d469c50791a892c5146ab61043da9
// WRN editor language server generator hash: f593a44aaf05495b789ce7a3086bee1eebb951b884d41c0e017bbcfe5f547e72
// @bun @bun-cjs
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -195906,20 +195905,12 @@ function regionsFor(document) {
regionCache.set(document.uri, { version: document.version, regions });
return regions;
}
// packages/language-server/src/index.ts
function offsetAt2(text, position) {
const lines = text.split(/\r?\n/);
let offset = 0;
for (let line = 0;line < Math.min(position.line, lines.length); line++)
offset += (lines[line]?.length ?? 0) + 1;
return Math.min(text.length, offset + Math.max(0, position.character));
function clearHtmlRegionCache(uri) {
if (uri)
regionCache.delete(uri);
else
regionCache.clear();
}
var semanticTokenTypes2 = ["variable"];
var semanticTokenModifiers2 = ["declaration", "modification"];
var semanticTokensLegend2 = {
tokenTypes: [...semanticTokenTypes2],
tokenModifiers: [...semanticTokenModifiers2]
};
// packages/language-server/src/html-service.ts
var service = getLanguageService();
@@ -195936,7 +195927,7 @@ function markdown(value) {
return "";
}
function htmlCompletions(document, position) {
if (!isInsideHtml(document, offsetAt2(document.text, position)))
if (!isInsideHtml(document, offsetAt(document.text, position)))
return [];
const virtual = htmlDocument(document);
const parsed = service.parseHTMLDocument(virtual);
@@ -195951,7 +195942,7 @@ function htmlCompletions(document, position) {
}));
}
function htmlHover(document, position) {
if (!isInsideHtml(document, offsetAt2(document.text, position)))
if (!isInsideHtml(document, offsetAt(document.text, position)))
return null;
const virtual = htmlDocument(document);
const result = service.doHover(virtual, position, service.parseHTMLDocument(virtual));
@@ -195964,12 +195955,51 @@ function htmlFoldingRanges(document) {
return service.getFoldingRanges(htmlDocument(document)).map((range) => ({ startLine: range.startLine, endLine: range.endLine }));
}
function htmlLinkedEditingRanges(document, position) {
if (!isInsideHtml(document, offsetAt2(document.text, position)))
if (!isInsideHtml(document, offsetAt(document.text, position)))
return null;
const virtual = htmlDocument(document);
const ranges = service.findLinkedEditingRanges(virtual, position, service.parseHTMLDocument(virtual));
return ranges && ranges.length ? ranges : null;
}
function selfClosingTagCompletion(text, offset) {
if (text.charAt(offset - 1) !== "/")
return null;
if (text.charAt(offset) === ">")
return null;
const tagStart = text.lastIndexOf("<", offset - 1);
if (tagStart < 0)
return null;
if (!/^<[A-Za-z][\w-]*/.test(text.slice(tagStart)))
return null;
let quote = null;
for (let i = tagStart + 1;i < offset - 1; i++) {
const ch = text[i];
if (quote) {
if (ch === quote)
quote = null;
continue;
}
if (ch === '"' || ch === "'") {
quote = ch;
continue;
}
if (ch === "<" || ch === ">")
return null;
}
if (quote)
return null;
return ">";
}
function htmlTagComplete(document, position) {
const offset = offsetAt(document.text, position);
if (!isInsideHtml(document, offset))
return null;
const virtual = htmlDocument(document);
const result = service.doTagComplete(virtual, position, service.parseHTMLDocument(virtual));
if (result)
return result;
return selfClosingTagCompletion(document.text, offset);
}
function mergeCompletions(wrnexus, html) {
const taken = new Set(wrnexus.map((item) => item.label));
return [
@@ -195978,15 +196008,6 @@ function mergeCompletions(wrnexus, html) {
];
}
// packages/language-server/src/html-regions.ts
var regionCache2 = new Map;
function clearHtmlRegionCache(uri) {
if (uri)
regionCache2.delete(uri);
else
regionCache2.clear();
}
// packages/language-server/src/server.ts
var documents = new Map;
var diagnosticTimers = new Map;
@@ -196192,6 +196213,11 @@ async function handle(message) {
result(message.id, ranges ? { ranges } : null);
break;
}
case "wrn/tagComplete": {
const document = documents.get(params.textDocument.uri);
result(message.id, document ? htmlTagComplete(document, params.position) : null);
break;
}
case "textDocument/definition": {
const document = documents.get(params.textDocument.uri);
result(message.id, document ? definitionLocation(document, params.position) : null);
@@ -196388,4 +196414,3 @@ process.stdin.on("data", (chunk) => {
}
});
process.stdin.resume();
})(exports, require, module, __filename, __dirname);