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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user