Show me more

This commit is contained in:
2025-09-07 02:45:51 +02:00
parent 11a7724c58
commit 9c2a6cb7e7
4 changed files with 267 additions and 63 deletions

View File

@@ -13,6 +13,7 @@ export interface CommandInfo {
description: string;
parameters: CommandParameter[];
example?: string;
filePath?: string;
}
export class CommandParser {
@@ -103,6 +104,7 @@ export class CommandParser {
let description = '';
let parameters: CommandParameter[] = [];
let example = '';
let signatureParams: string[] = [];
let inParametersSection = false;
let inExampleSection = false;
@@ -116,12 +118,21 @@ export class CommandParser {
continue;
}
// Extract main description (first comment block)
// Extract main description (first comment block) and parameter names from signature
if (line.startsWith('# `') && line.includes('`')) {
const match = line.match(/# `([^`]+)`/);
if (match) {
description = match[1];
description = match[1] + '\n\n';
foundFirstDescription = true;
// Extract parameter names from command signature
// e.g., "anim object name [reverse]" -> ["object", "name", "reverse"]
const signature = match[1];
const paramMatches = signature.match(/\b\w+\b/g);
if (paramMatches && paramMatches.length > 1) {
// Skip the first match (command name) and extract parameter names
signatureParams = paramMatches.slice(1);
}
}
continue;
}
@@ -142,7 +153,7 @@ export class CommandParser {
// If we haven't found the first description yet, this might be it
if (!foundFirstDescription && cleanLine) {
description = cleanLine;
description += cleanLine;
foundFirstDescription = true;
continue;
}
@@ -155,7 +166,7 @@ export class CommandParser {
cleanLine.includes('Run the command') || cleanLine.includes('Function called when')) {
break;
}
description += ' ' + cleanLine;
description += '\n' + cleanLine;
}
continue;
}
@@ -195,12 +206,21 @@ export class CommandParser {
defaultValue = defaultMatch[1].trim();
}
// Determine parameter type from description
// Determine parameter type from description with more comprehensive detection
let paramType = 'string';
if (paramDesc.includes('boolean') || paramDesc.includes('true') || paramDesc.includes('false')) {
const descLower = paramDesc.toLowerCase();
if (descLower.includes('boolean') || descLower.includes('true') || descLower.includes('false') ||
descLower.includes('bool') || descLower.includes('flag')) {
paramType = 'boolean';
} else if (paramDesc.includes('number') || paramDesc.includes('int') || paramDesc.includes('float')) {
} else if (descLower.includes('number') || descLower.includes('int') || descLower.includes('float') ||
descLower.includes('integer') || descLower.includes('numeric')) {
paramType = 'number';
} else if (descLower.includes('object') || descLower.includes('node') || descLower.includes('item')) {
paramType = 'object';
} else if (descLower.includes('scene') || descLower.includes('room')) {
paramType = 'scene';
} else if (descLower.includes('animation') || descLower.includes('anim')) {
paramType = 'animation';
}
parameters.push({
@@ -219,10 +239,18 @@ export class CommandParser {
for (let j = i + 1; j < Math.min(i + 15, lines.length); j++) {
const configLine = lines[j].trim();
if (configLine.includes('ESCCommandArgumentDescriptor.new(')) {
// Parse the descriptor parameters
const descriptorMatch = configLine.match(/ESCCommandArgumentDescriptor\.new\(\s*(\d+)/);
if (descriptorMatch) {
const minArgs = parseInt(descriptorMatch[1]);
// Parse the descriptor parameters - look for the number on the next line
let minArgs = 0;
for (let k = j + 1; k < Math.min(j + 5, lines.length); k++) {
const nextLine = lines[k].trim();
const numberMatch = nextLine.match(/^(\d+),?$/);
if (numberMatch) {
minArgs = parseInt(numberMatch[1]);
break;
}
}
if (minArgs > 0) {
// Look for type arrays, defaults, and required flags in subsequent lines
let types: string[] = [];
@@ -240,16 +268,17 @@ export class CommandParser {
}
}
// Extract defaults array
if (typeLine.includes('null') && typeLine.includes('[') && !typeLine.includes('TYPE_')) {
// Extract defaults array (first array that doesn't contain TYPE_)
if (typeLine.includes('[') && !typeLine.includes('TYPE_') && !defaults.length) {
const defaultMatch = typeLine.match(/\[([^\]]+)\]/);
if (defaultMatch) {
defaults = defaultMatch[1].split(',').map(d => d.trim());
}
}
// Extract required flags array (look for true/false pattern)
if (typeLine.includes('true') && typeLine.includes('false') && typeLine.includes('[') && !typeLine.includes('TYPE_')) {
// Extract required flags array (second array that doesn't contain TYPE_ and has true/false)
if (typeLine.includes('[') && !typeLine.includes('TYPE_') && defaults.length > 0 &&
(typeLine.includes('true') || typeLine.includes('false'))) {
const requiredMatch = typeLine.match(/\[([^\]]+)\]/);
if (requiredMatch) {
requiredFlags = requiredMatch[1].split(',').map(f => f.trim() === 'true');
@@ -264,13 +293,16 @@ export class CommandParser {
// Store original parameters from comments for name preservation
const originalParams = [...parameters];
for (let p = 0; p < maxParams; p++) {
// Use the total number of types, not just minArgs
const totalParams = types.length;
for (let p = 0; p < totalParams; p++) {
const type = types[p] || 'TYPE_STRING';
const defaultValue = defaults[p] || 'null';
// If requiredFlags array is not provided, use minArgs to determine required parameters
const isRequired = p < minArgs || (requiredFlags[p] !== undefined ? requiredFlags[p] : p < minArgs);
// Convert Godot types to readable types
// Convert Godot types to readable types with more comprehensive mapping
let paramType = 'string';
if (type.includes('TYPE_BOOL')) {
paramType = 'boolean';
@@ -278,12 +310,24 @@ export class CommandParser {
paramType = 'number';
} else if (type.includes('TYPE_STRING')) {
paramType = 'string';
} else if (type.includes('TYPE_VECTOR2')) {
paramType = 'vector2';
} else if (type.includes('TYPE_VECTOR3')) {
paramType = 'vector3';
} else if (type.includes('TYPE_ARRAY')) {
paramType = 'array';
} else if (type.includes('TYPE_DICTIONARY')) {
paramType = 'dictionary';
} else if (type.includes('TYPE_OBJECT')) {
paramType = 'object';
}
// Try to get parameter name from comments if available, otherwise generate one
// Try to get parameter name from comments if available, otherwise use signature or generate one
let paramName = `param${p + 1}`;
if (p < originalParams.length && originalParams[p] && originalParams[p].name !== `param${p + 1}`) {
if (p < originalParams.length && originalParams[p] && originalParams[p].name) {
paramName = originalParams[p].name;
} else if (p < signatureParams.length && signatureParams[p]) {
paramName = signatureParams[p];
}
newParameters.push({
@@ -311,8 +355,10 @@ export class CommandParser {
if (configureMatch) {
const paramCount = parseInt(configureMatch[1]);
for (let i = 0; i < paramCount; i++) {
// Use signature parameter name if available, otherwise generate one
const paramName = i < signatureParams.length ? signatureParams[i] : `param${i + 1}`;
parameters.push({
name: `param${i + 1}`,
name: paramName,
type: 'string',
required: true
});
@@ -324,8 +370,8 @@ export class CommandParser {
if (description) {
description = description.trim();
// Remove extra whitespace
description = description.replace(/\s+/g, ' ');
// Remove extra whitespace but preserve newlines
description = description.replace(/[ \t]+/g, ' ').replace(/\n\s+/g, '\n');
// Truncate if too long (keep first sentence or first 200 chars)
const firstSentence = description.split('.')[0];
@@ -345,7 +391,8 @@ export class CommandParser {
name: commandName,
description: description || `${commandName} command`,
parameters: parameters,
example: example
example: example,
filePath: filePath
};
} catch (error) {
@@ -395,13 +442,14 @@ export class CommandParser {
/**
* Get commands in the format expected by the VSCode extension
*/
public getCommandsForExtension(): Array<{name: string, description: string, parameters: CommandParameter[]}> {
public getCommandsForExtension(): Array<{name: string, description: string, parameters: CommandParameter[], filePath?: string}> {
const commands = this.parseCommands();
return commands.map(cmd => ({
name: cmd.name,
description: cmd.description,
parameters: cmd.parameters
parameters: cmd.parameters,
filePath: cmd.filePath
}));
}
}