release: Vs Code New Extension with layout Support
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
"use strict";
|
||||
|
||||
const vscode = require("vscode");
|
||||
|
||||
const COMPONENT_DECLARATION =
|
||||
/^\s*(component|layout)\s+([A-Za-z_$][\w$]*)\s*\{/gm;
|
||||
|
||||
function getTagAtPosition(document, position) {
|
||||
const range = document.getWordRangeAtPosition(
|
||||
position,
|
||||
/[A-Za-z_$][\w$]*/,
|
||||
);
|
||||
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const name = document.getText(range);
|
||||
|
||||
if (!/^[A-Z][A-Za-z0-9_$]*$/.test(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const line = document.lineAt(position.line).text;
|
||||
const offset = document.offsetAt(position);
|
||||
const lineStart = document.offsetAt(
|
||||
new vscode.Position(position.line, 0),
|
||||
);
|
||||
|
||||
const characterOffset = offset - lineStart;
|
||||
const before = line.slice(0, characterOffset);
|
||||
const after = line.slice(characterOffset);
|
||||
|
||||
const insideTag =
|
||||
before.lastIndexOf("<") > before.lastIndexOf(">") &&
|
||||
after.includes(">");
|
||||
|
||||
if (!insideTag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
range,
|
||||
};
|
||||
}
|
||||
|
||||
async function findDeclaration(name) {
|
||||
const files = await vscode.workspace.findFiles(
|
||||
"**/*.wrn",
|
||||
"**/{node_modules,dist,.wrnexus,.git}/**",
|
||||
);
|
||||
|
||||
const matches = [];
|
||||
|
||||
for (const uri of files) {
|
||||
let document;
|
||||
|
||||
try {
|
||||
document = await vscode.workspace.openTextDocument(uri);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
const source = document.getText();
|
||||
|
||||
COMPONENT_DECLARATION.lastIndex = 0;
|
||||
|
||||
let match;
|
||||
|
||||
while ((match = COMPONENT_DECLARATION.exec(source)) !== null) {
|
||||
const declarationName = match[2];
|
||||
|
||||
if (declarationName !== name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const nameOffset =
|
||||
match.index +
|
||||
match[0].indexOf(declarationName);
|
||||
|
||||
const start = document.positionAt(nameOffset);
|
||||
const end = document.positionAt(
|
||||
nameOffset + declarationName.length,
|
||||
);
|
||||
|
||||
matches.push(
|
||||
new vscode.Location(
|
||||
uri,
|
||||
new vscode.Range(start, end),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
async function provideDefinition(document, position) {
|
||||
const tag = getTagAtPosition(document, position);
|
||||
|
||||
if (!tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const matches = await findDeclaration(tag.name);
|
||||
|
||||
if (matches.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return matches.length === 1 ? matches[0] : matches;
|
||||
}
|
||||
|
||||
function registerDefinitionProvider(context) {
|
||||
const disposable = vscode.languages.registerDefinitionProvider(
|
||||
{
|
||||
language: "wrn",
|
||||
scheme: "file",
|
||||
},
|
||||
{
|
||||
provideDefinition,
|
||||
},
|
||||
);
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findDeclaration,
|
||||
getTagAtPosition,
|
||||
provideDefinition,
|
||||
registerDefinitionProvider,
|
||||
};
|
||||
Reference in New Issue
Block a user