Skip to content

Commit c9678e8

Browse files
committed
feat: copy magento path command
1 parent e70dce7 commit c9678e8

File tree

6 files changed

+138
-8
lines changed

6 files changed

+138
-8
lines changed

package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,21 @@
3838
{
3939
"command": "magento-toolbox.generateContextPlugin",
4040
"title": "Magento Toolbox: Generate Plugin"
41+
},
42+
{
43+
"command": "magento-toolbox.copyMagentoPath",
44+
"title": "Magento Toolbox: Copy Magento Path"
4145
}
4246
],
4347
"menus": {
4448
"commandPalette": [
4549
{
4650
"command": "magento-toolbox.generateContextPlugin",
4751
"when": "false"
52+
},
53+
{
54+
"command": "magento-toolbox.copyMagentoPath",
55+
"when": "false"
4856
}
4957
],
5058
"editor/context": [
@@ -64,6 +72,13 @@
6472
"command": "magento-toolbox.generateContextPlugin",
6573
"when": "magento-toolbox.canGeneratePlugin"
6674
}
75+
],
76+
"magento-toolbox.explorer-submenu": [
77+
{
78+
"command": "magento-toolbox.copyMagentoPath",
79+
"title": "Magento Toolbox: Copy Magento Path",
80+
"when": "resourceExtname in magento-toolbox.supportedMagentoPathExtensions && resourcePath =~ /view/"
81+
}
6782
]
6883
}
6984
},
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Command } from 'command/Command';
2+
import IndexManager from 'indexer/IndexManager';
3+
import { ModuleIndexData } from 'indexer/module/ModuleIndexData';
4+
import ModuleIndexer from 'indexer/module/ModuleIndexer';
5+
import { Uri, window, env } from 'vscode';
6+
7+
export default class CopyMagentoPathCommand extends Command {
8+
public static readonly TEMPLATE_EXTENSIONS = ['.phtml'];
9+
public static readonly WEB_EXTENSIONS = ['.css', '.js'];
10+
public static readonly IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg'];
11+
12+
private static readonly TEMPLATE_PATHS = [
13+
'view/frontend/templates/',
14+
'view/adminhtml/templates/',
15+
'view/base/templates/',
16+
'templates/',
17+
];
18+
19+
private static readonly WEB_PATHS = [
20+
'view/frontend/web/',
21+
'view/adminhtml/web/',
22+
'view/base/web/',
23+
'web/',
24+
];
25+
26+
constructor() {
27+
super('magento-toolbox.copyMagentoPath');
28+
}
29+
30+
public async execute(file: Uri): Promise<void> {
31+
if (!file) {
32+
return;
33+
}
34+
35+
const moduleIndex = IndexManager.getIndexData(ModuleIndexer.KEY);
36+
37+
if (!moduleIndex) {
38+
return;
39+
}
40+
41+
const moduleIndexData = new ModuleIndexData(moduleIndex);
42+
43+
const module = moduleIndexData.getModuleByUri(file);
44+
45+
if (!module) {
46+
return;
47+
}
48+
49+
const paths = this.getPaths(file);
50+
51+
if (!paths) {
52+
return;
53+
}
54+
55+
const pathIndex = paths.findIndex(p => file.fsPath.lastIndexOf(p) !== -1);
56+
57+
if (pathIndex === -1) {
58+
return;
59+
}
60+
61+
const endIndex = file.fsPath.lastIndexOf(paths[pathIndex]);
62+
const offset = paths[pathIndex].length;
63+
const relativePath = file.fsPath.slice(offset + endIndex);
64+
65+
const magentoPath = `${module.name}::${relativePath}`;
66+
67+
await env.clipboard.writeText(magentoPath);
68+
window.showInformationMessage(`Copied: ${magentoPath}`);
69+
}
70+
71+
private getPaths(file: Uri): string[] | undefined {
72+
if (CopyMagentoPathCommand.TEMPLATE_EXTENSIONS.some(ext => file.fsPath.endsWith(ext))) {
73+
return CopyMagentoPathCommand.TEMPLATE_PATHS;
74+
}
75+
76+
if (
77+
CopyMagentoPathCommand.WEB_EXTENSIONS.some(ext => file.fsPath.endsWith(ext)) ||
78+
CopyMagentoPathCommand.IMAGE_EXTENSIONS.some(ext => file.fsPath.endsWith(ext))
79+
) {
80+
return CopyMagentoPathCommand.WEB_PATHS;
81+
}
82+
83+
return undefined;
84+
}
85+
}

src/common/Context.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
import { commands, TextEditor } from 'vscode';
22
import PhpDocumentParser from './php/PhpDocumentParser';
3+
import CopyMagentoPathCommand from 'command/CopyMagentoPathCommand';
34

45
export interface EditorContext {
56
canGeneratePlugin: boolean;
7+
supportedMagentoPathExtensions: string[];
68
}
79

810
class Context {
9-
public editorContext: EditorContext = {
10-
canGeneratePlugin: false,
11-
};
11+
private editorContext: EditorContext;
12+
13+
constructor() {
14+
this.editorContext = this.getDefaultContext();
15+
}
1216

1317
public async updateContext(type: 'editor' | 'selection', editor?: TextEditor) {
1418
if (!editor) {
15-
await this.setContext({
16-
canGeneratePlugin: false,
17-
});
19+
await this.setContext(this.getDefaultContext());
1820

1921
return;
2022
}
2123

2224
if (type === 'editor') {
2325
await this.setContext({
26+
...this.editorContext,
2427
canGeneratePlugin: await this.canGeneratePlugin(editor),
2528
});
2629
}
@@ -37,6 +40,17 @@ class Context {
3740
await Promise.all(promises);
3841
}
3942

43+
public getDefaultContext(): EditorContext {
44+
return {
45+
canGeneratePlugin: false,
46+
supportedMagentoPathExtensions: [
47+
...CopyMagentoPathCommand.TEMPLATE_EXTENSIONS,
48+
...CopyMagentoPathCommand.WEB_EXTENSIONS,
49+
...CopyMagentoPathCommand.IMAGE_EXTENSIONS,
50+
],
51+
};
52+
}
53+
4054
private async canGeneratePlugin(editor: TextEditor): Promise<boolean> {
4155
if (editor.document.languageId !== 'php') {
4256
return false;

src/extension.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ import ChangeTextEditorSelectionObserver from 'observer/ChangeTextEditorSelectio
1111
import DocumentCache from 'cache/DocumentCache';
1212
import GenerateContextPluginCommand from 'command/GenerateContextPluginCommand';
1313
import { XmlClasslikeDefinitionProvider } from 'definition/XmlClasslikeDefinitionProvider';
14+
import CopyMagentoPathCommand from 'command/CopyMagentoPathCommand';
15+
1416
// This method is called when your extension is activated
1517
// Your extension is activated the very first time the command is executed
1618
export async function activate(context: vscode.ExtensionContext) {
1719
console.log('[Magento Toolbox] Activating extension');
18-
const commands = [IndexWorkspaceCommand, GenerateModuleCommand, GenerateContextPluginCommand];
20+
const commands = [
21+
IndexWorkspaceCommand,
22+
GenerateModuleCommand,
23+
GenerateContextPluginCommand,
24+
CopyMagentoPathCommand,
25+
];
1926

2027
ExtensionState.init(context);
2128

src/indexer/module/ModuleIndexData.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { WizardSelectOption } from 'webview/types';
22
import { Module } from './types';
33
import { IndexData } from 'indexer/IndexData';
4+
import { Uri } from 'vscode';
45

56
export class ModuleIndexData extends IndexData<Module> {
67
public getModuleOptions(filter?: (module: Module) => boolean): WizardSelectOption[] {
@@ -15,4 +16,12 @@ export class ModuleIndexData extends IndexData<Module> {
1516
public getModule(name: string): Module | undefined {
1617
return this.getValues().find(module => module.name === name);
1718
}
19+
20+
public getModuleByUri(uri: Uri): Module | undefined {
21+
const module = this.getValues().find(module => {
22+
return uri.fsPath.startsWith(module.path);
23+
});
24+
25+
return module;
26+
}
1827
}

src/indexer/module/ModuleIndexer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default class ModuleIndexer extends Indexer<Module> {
5454
name: moduleName,
5555
version: setupVersion,
5656
sequence: sequence.map((module: any) => module['@_name']),
57-
path: uri.fsPath,
57+
path: Uri.joinPath(uri, '..', '..').fsPath,
5858
location: uri.fsPath.includes('vendor') ? 'vendor' : 'app',
5959
};
6060
}

0 commit comments

Comments
 (0)