Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@
"category": "MageForge",
"icon": "$(eye)"
},
{
"command": "mageforge.theme.buildInline",
"title": "Build",
"category": "MageForge"
},
{
"command": "mageforge.theme.watchInline",
"title": "Watch",
"category": "MageForge"
},
{
"command": "mageforge.theme.clean",
"title": "Theme: Clean",
Expand Down Expand Up @@ -207,6 +217,16 @@
}
],
"view/item/context": [
{
"command": "mageforge.theme.buildInline",
"when": "view == mageforge.themes && viewItem == mageforgeTheme",
"group": "inline@1"
},
{
"command": "mageforge.theme.watchInline",
"when": "view == mageforge.themes && viewItem == mageforgeTheme",
"group": "inline@2"
},
{
"command": "mageforge.theme.build",
"when": "view == mageforge.themes && viewItem == mageforgeTheme",
Expand Down
14 changes: 13 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function activate(context: vscode.ExtensionContext) {
new WelcomeViewProvider(context.extensionUri),
),
vscode.window.registerTreeDataProvider('mageforge.commands', commandsProvider),
vscode.window.registerTreeDataProvider('mageforge.themes', themesProvider),
vscode.window.createTreeView('mageforge.themes', { treeDataProvider: themesProvider }),
);

// Notify the user and open the changelog after the extension was updated.
Expand All @@ -39,6 +39,18 @@ export function activate(context: vscode.ExtensionContext) {
);
}

// Inline text-only aliases for the themes view.
const buildCmd = MAGEFORGE_COMMANDS.find((c) => c.id === 'mageforge.theme.build')!;
const watchCmd = MAGEFORGE_COMMANDS.find((c) => c.id === 'mageforge.theme.watch')!;
context.subscriptions.push(
vscode.commands.registerCommand('mageforge.theme.buildInline', (item?: ThemeTreeItem) =>
runMageforgeCommand(buildCmd, themesProvider, item),
),
vscode.commands.registerCommand('mageforge.theme.watchInline', (item?: ThemeTreeItem) =>
runMageforgeCommand(watchCmd, themesProvider, item),
),
);

context.subscriptions.push(
vscode.commands.registerCommand('mageforge.refreshThemes', () => themesProvider.refresh()),
vscode.commands.registerCommand(
Expand Down
2 changes: 1 addition & 1 deletion src/magento.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export function execMageforge(
{ cwd: magentoRoot, maxBuffer: 10 * 1024 * 1024 },
(error, stdout, stderr) => {
if (error) {
reject(new Error(stderr || error.message));
reject(new Error(stderr || error.message || 'Command failed'));
return;
}
resolve(stdout);
Expand Down
30 changes: 29 additions & 1 deletion src/themesProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export class ThemesProvider implements vscode.TreeDataProvider<ThemeTreeItem> {
this.loadError = undefined;
} catch (error) {
this.themes = [];
this.loadError = error instanceof Error ? error.message : String(error);
const message = error instanceof Error ? error.message : String(error);
const cleaned = stripAnsi(message);
this.loadError = formatLoadError(cleaned);
}
}
}
Expand All @@ -86,6 +88,32 @@ function stripAnsi(text: string): string {
return text.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '');
}

/**
* Convert a raw command failure into a user-friendly error message.
* Long messages are truncated so they do not break the tree view layout.
*/
function formatLoadError(message: string): string {
const normalized = message.toLowerCase();

if (
normalized.includes('ddev') &&
/not (running|started)|could not|failed|unable/i.test(message)
) {
return 'DDEV is not running. Start the project with `ddev start` and try again.';
}
if (normalized.includes('docker-compose') || normalized.includes('docker compose')) {
return 'Docker Compose service unavailable. Check that containers are running.';
}
if (normalized.includes('lando')) {
return 'Lando environment unavailable. Start the project with `lando start`.';
}
if (normalized.includes('command not found') || normalized.includes('no such file')) {
return 'MageForge CLI not found. Run `composer require openforgeproject/mageforge`.';
}

return message.length > 120 ? `${message.slice(0, 120)}…` : message;
}

/**
* Parse `mageforge:theme:list` output. The command renders a Symfony console
* table with the columns Code | Title | Path – we extract the theme codes
Expand Down
Loading