2026-10-08 20:02:08 +00:00
|
|
|
import * as vscode from 'vscode';
|
|
|
|
|
|
|
|
|
|
export class TplHoverProvider implements vscode.HoverProvider {
|
2026-10-12 19:43:46 +00:00
|
|
|
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> {
|
2026-10-09 21:14:30 +00:00
|
|
|
const range = document.getWordRangeAtPosition(position, /[a-zA-Z0-9_.]+/);
|
2026-10-12 19:43:46 +00:00
|
|
|
if (!range) return null;
|
|
|
|
|
|
|
|
|
|
const word = document.getText(range); // z.B. "modelling.testDefine"
|
|
|
|
|
const text = document.getText();
|
|
|
|
|
const lines = text.split('\n');
|
2026-10-08 20:02:08 +00:00
|
|
|
|
2026-10-09 21:14:30 +00:00
|
|
|
const parts = word.split('.');
|
2026-10-12 19:43:46 +00:00
|
|
|
const importBase = parts[0];
|
|
|
|
|
const funcName = parts.length > 1 ? parts[1] : word;
|
2026-10-09 21:14:30 +00:00
|
|
|
|
2026-10-12 19:43:46 +00:00
|
|
|
// 1. Lokale Defines
|
|
|
|
|
if (parts.length === 1 || parts.length === 2) {
|
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
|
|
|
const line = lines[i];
|
|
|
|
|
const defMatch = line.match(new RegExp(`^\\s*define\\s+${funcName}\\b(?:\\s*\\((.*?)\\))?`));
|
|
|
|
|
if (defMatch) {
|
|
|
|
|
const params = defMatch[1] ? defMatch[1].trim() : '';
|
|
|
|
|
const md = new vscode.MarkdownString();
|
|
|
|
|
md.appendCodeblock(`define ${funcName}(${params})`, 'tpl');
|
|
|
|
|
|
|
|
|
|
const textAfterDefine = text.substring(text.indexOf(line) + line.length);
|
|
|
|
|
const docMatch = textAfterDefine.match(/^\s*(?:"""|''')([\s\S]*?)(?:"""|''')/);
|
|
|
|
|
if (docMatch) { md.appendMarkdown(`\n\n---\n\n${docMatch[1].trim()}`); }
|
|
|
|
|
|
|
|
|
|
return new vscode.Hover(md);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-08 20:02:08 +00:00
|
|
|
}
|
2026-10-09 21:14:30 +00:00
|
|
|
|
2026-10-12 19:43:46 +00:00
|
|
|
// 2. Cross-File Hover für from ... import
|
|
|
|
|
const fromImportRegex = new RegExp(`from\\s+([a-zA-Z0-9_.]+)\\s+import\\s+${importBase}\\b`);
|
|
|
|
|
const fromMatch = text.match(fromImportRegex);
|
|
|
|
|
if (fromMatch) {
|
|
|
|
|
const moduleName = fromMatch[1];
|
|
|
|
|
|
|
|
|
|
// Wenn der User über die Methode fährt (modelling.XYZ)
|
|
|
|
|
if (funcName !== importBase) {
|
|
|
|
|
const files = await vscode.workspace.findFiles('**/*.tpl', '**/node_modules/**');
|
|
|
|
|
for (const file of files) {
|
|
|
|
|
const doc = await vscode.workspace.openTextDocument(file);
|
|
|
|
|
const docText = doc.getText();
|
|
|
|
|
if (new RegExp(`tpl\\s+1\\.\\d+\\s+module\\s+${moduleName.replace(/\./g, '\\.')}\\s*;`).test(docText)) {
|
|
|
|
|
const docLines = docText.split('\n');
|
|
|
|
|
for (let i = 0; i < docLines.length; i++) {
|
|
|
|
|
const line = docLines[i];
|
|
|
|
|
const defMatch = line.match(new RegExp(`^\\s*define\\s+${funcName}\\b(?:\\s*\\((.*?)\\))?`));
|
|
|
|
|
if (defMatch) {
|
|
|
|
|
const params = defMatch[1] ? defMatch[1].trim() : '';
|
|
|
|
|
const md = new vscode.MarkdownString();
|
|
|
|
|
md.appendCodeblock(`define ${funcName}(${params})`, 'tpl');
|
|
|
|
|
|
|
|
|
|
const textAfterDefine = docText.substring(docText.indexOf(line) + line.length);
|
|
|
|
|
const docMatch = textAfterDefine.match(/^\s*(?:"""|''')([\s\S]*?)(?:"""|''')/);
|
|
|
|
|
if (docMatch) { md.appendMarkdown(`\n\n---\n\n${docMatch[1].trim()}`); }
|
|
|
|
|
md.appendMarkdown(`\n\n*(Importiert aus \`${moduleName}\`)*`);
|
|
|
|
|
return new vscode.Hover(md);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Wenn er nur über "modelling" fährt
|
|
|
|
|
return new vscode.Hover(new vscode.MarkdownString(`Importierte Definitions **${importBase}** aus Modul \`${moduleName}\`.`));
|
2026-10-09 21:14:30 +00:00
|
|
|
}
|
|
|
|
|
|
2026-10-12 19:43:46 +00:00
|
|
|
// 3. Hover für Built-Ins
|
|
|
|
|
if (word.startsWith('log.')) { return new vscode.Hover(new vscode.MarkdownString(`TPL Logging-Modul`)); }
|
|
|
|
|
if (word.startsWith('discovery.')) { return new vscode.Hover(new vscode.MarkdownString(`TPL Discovery-Modul`)); }
|
|
|
|
|
|
2026-10-08 20:02:08 +00:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|