Add config() Go to Definition support to VS Code extension

Always include params in window.rsxapp to reduce state variations
Add request params to window.rsxapp global
Enhance module creation commands with clear nomenclature guidance
Add module/submodule/feature nomenclature clarification to docs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-10-30 19:13:57 +00:00
parent 8c8fb8e902
commit ac082bce2a
15 changed files with 546 additions and 16 deletions

View File

@@ -160,6 +160,16 @@ export class RspadeDefinitionProvider implements vscode.DefinitionProvider {
return routeResult;
}
// Check for config() pattern - works in PHP and Blade files
if (['php', 'blade', 'html'].includes(languageId) ||
fileName.endsWith('.php') ||
fileName.endsWith('.blade.php')) {
const configResult = await this.handleConfigPattern(document, position);
if (configResult) {
return configResult;
}
}
// Check for href="/" pattern in Blade/Jqhtml files
if (fileName.endsWith('.blade.php') || fileName.endsWith('.jqhtml')) {
const hrefResult = await this.handleHrefPattern(document, position);
@@ -304,6 +314,126 @@ export class RspadeDefinitionProvider implements vscode.DefinitionProvider {
return undefined;
}
/**
* Handle config() pattern in PHP and Blade files
* Detects patterns like:
* - config('rsx.default_user.email')
* - config("app.name")
*
* Searches in both system/config/ and rsx/resource/config/
* (rsx/resource/config/ takes precedence)
*/
private async handleConfigPattern(
document: vscode.TextDocument,
position: vscode.Position
): Promise<vscode.Definition | undefined> {
const line = document.lineAt(position.line).text;
// Match config('key.path') or config("key.path")
const configPattern = /config\s*\(\s*(['"])([a-zA-Z0-9_.]+)\1\s*\)/g;
let match;
while ((match = configPattern.exec(line)) !== null) {
const fullMatch = match[0];
const configKey = match[2]; // e.g., "rsx.default_user.email"
const keyStart = match.index + match[0].indexOf(configKey);
const keyEnd = keyStart + configKey.length;
// Check if cursor is on the config key
if (position.character >= keyStart && position.character < keyEnd) {
// Parse the config key
const keyParts = configKey.split('.');
const configFile = keyParts[0]; // e.g., "rsx"
const nestedPath = keyParts.slice(1); // e.g., ["default_user", "email"]
// Get the RSpade project root
const rspade_root = this.find_rspade_root();
if (!rspade_root) {
return undefined;
}
// Search for config file (prioritize rsx/resource/config/)
const rsxConfigPath = path.join(rspade_root, 'rsx', 'resource', 'config', `${configFile}.php`);
const systemConfigPath = path.join(rspade_root, 'system', 'config', `${configFile}.php`);
let configFilePath: string | undefined;
// Check rsx/resource/config first
if (fs.existsSync(rsxConfigPath)) {
configFilePath = rsxConfigPath;
} else if (fs.existsSync(systemConfigPath)) {
configFilePath = systemConfigPath;
}
if (!configFilePath) {
return undefined;
}
// Read the config file
try {
const configContent = fs.readFileSync(configFilePath, 'utf8');
// Find the line containing the nested key
const location = this.findConfigKeyInFile(configContent, nestedPath, configFilePath);
if (location) {
this.clear_status_bar();
return location;
}
// If we can't find the specific key, just return the file
const fileUri = vscode.Uri.file(configFilePath);
const filePosition = new vscode.Position(0, 0);
this.clear_status_bar();
return new vscode.Location(fileUri, filePosition);
} catch (error) {
console.error('Error reading config file:', error);
return undefined;
}
}
}
return undefined;
}
/**
* Find a nested config key in a PHP config file
* Returns the location of the key definition if found
*/
private findConfigKeyInFile(
content: string,
nestedPath: string[],
filePath: string
): vscode.Location | undefined {
if (nestedPath.length === 0) {
// No nested path, return start of file
const fileUri = vscode.Uri.file(filePath);
return new vscode.Location(fileUri, new vscode.Position(0, 0));
}
// Split content into lines
const lines = content.split('\n');
// Search for the key in the file
// For nested keys like ["default_user", "email"], we need to find:
// 1. First, find 'default_user' => [
// 2. Then find 'email' => value
// Simple approach: search for the last key in quotes
const targetKey = nestedPath[nestedPath.length - 1];
const keyPattern = new RegExp(`['"]${targetKey}['"]\\s*=>`, 'i');
for (let i = 0; i < lines.length; i++) {
if (keyPattern.test(lines[i])) {
const fileUri = vscode.Uri.file(filePath);
const position = new vscode.Position(i, 0);
return new vscode.Location(fileUri, position);
}
}
return undefined;
}
/**
* Handle href="/" pattern in Blade/Jqhtml files
* Detects when cursor is on "/" within href attribute