Skip to content

Commit d18927e

Browse files
committed
livewire component linking
1 parent 00aadaf commit d18927e

File tree

5 files changed

+58
-3
lines changed

5 files changed

+58
-3
lines changed

generatable.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,12 @@
5050
"features": [
5151
"link"
5252
]
53+
},
54+
{
55+
"type": "livewireComponent",
56+
"label": "Livewire components",
57+
"features": [
58+
"link"
59+
]
5360
}
5461
]

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@
284284
"generated": true,
285285
"description": null
286286
},
287+
"Laravel.livewireComponent.link": {
288+
"type": "boolean",
289+
"default": true,
290+
"generated": true,
291+
"description": "Enable linking for Livewire components."
292+
},
287293
"Laravel.middleware.diagnostics": {
288294
"type": "boolean",
289295
"default": true,

src/features/livewireComponent.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { getViews } from "@src/repositories/views";
2+
import { projectPath } from "@src/support/project";
3+
import * as vscode from "vscode";
4+
import { LinkProvider } from "..";
5+
6+
export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => {
7+
const links: vscode.DocumentLink[] = [];
8+
const text = doc.getText();
9+
const lines = text.split("\n");
10+
const views = getViews().items;
11+
12+
lines.forEach((line, index) => {
13+
const match = line.match(/<\/?livewire:([^\s>]+)/);
14+
15+
if (match && match.index !== undefined) {
16+
const componentName = match[1];
17+
// Standard component
18+
const viewName = `livewire.${componentName}`;
19+
// Index component
20+
const view = views.find((v) => v.key === viewName);
21+
22+
if (view) {
23+
links.push(
24+
new vscode.DocumentLink(
25+
new vscode.Range(
26+
new vscode.Position(index, match.index + 1),
27+
new vscode.Position(
28+
index,
29+
match.index + match[0].length,
30+
),
31+
),
32+
vscode.Uri.parse(projectPath(view.path)),
33+
),
34+
);
35+
}
36+
}
37+
});
38+
39+
return Promise.resolve(links);
40+
};

src/link/LinkProvider.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { linkProvider as config } from "@src/features/config";
88
import { linkProvider as controllerAction } from "@src/features/controllerAction";
99
import { linkProvider as env } from "@src/features/env";
1010
import { linkProvider as inertia } from "@src/features/inertia";
11+
import { linkProvider as livewireComponent } from "@src/features/livewireComponent";
1112
import { linkProvider as middleware } from "@src/features/middleware";
1213
import { linkProvider as mix } from "@src/features/mix";
1314
import { linkProvider as paths } from "@src/features/paths";
@@ -28,17 +29,18 @@ const allProviders: Partial<Record<GeneratedConfigKey, LinkProviderType>> = {
2829
"appBinding.link": appBinding,
2930
"asset.link": asset,
3031
"auth.link": auth,
32+
"bladeComponent.link": bladeComponent,
3133
"config.link": config,
3234
"controllerAction.link": controllerAction,
3335
"env.link": env,
3436
"inertia.link": inertia,
37+
"livewireComponent.link": livewireComponent,
3538
"middleware.link": middleware,
3639
"mix.link": mix,
40+
"paths.link": paths,
3741
"route.link": route,
3842
"translation.link": translation,
3943
"view.link": view,
40-
"paths.link": paths,
41-
"bladeComponent.link": bladeComponent,
4244
};
4345

4446
export const linkProviders: DocumentLinkProvider[] = Object.entries(

src/support/generated-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export type GeneratedConfigKey = 'appBinding.diagnostics' | 'appBinding.hover' | 'appBinding.link' | 'appBinding.completion' | 'asset.diagnostics' | 'asset.hover' | 'asset.link' | 'asset.completion' | 'auth.diagnostics' | 'auth.hover' | 'auth.link' | 'auth.completion' | 'bladeComponent.link' | 'config.diagnostics' | 'config.hover' | 'config.link' | 'config.completion' | 'controllerAction.diagnostics' | 'controllerAction.hover' | 'controllerAction.link' | 'controllerAction.completion' | 'env.diagnostics' | 'env.hover' | 'env.link' | 'env.completion' | 'inertia.diagnostics' | 'inertia.hover' | 'inertia.link' | 'inertia.completion' | 'middleware.diagnostics' | 'middleware.hover' | 'middleware.link' | 'middleware.completion' | 'mix.diagnostics' | 'mix.hover' | 'mix.link' | 'mix.completion' | 'paths.link' | 'route.diagnostics' | 'route.hover' | 'route.link' | 'route.completion' | 'translation.diagnostics' | 'translation.hover' | 'translation.link' | 'translation.completion' | 'view.diagnostics' | 'view.hover' | 'view.link' | 'view.completion';
1+
export type GeneratedConfigKey = 'appBinding.diagnostics' | 'appBinding.hover' | 'appBinding.link' | 'appBinding.completion' | 'asset.diagnostics' | 'asset.hover' | 'asset.link' | 'asset.completion' | 'auth.diagnostics' | 'auth.hover' | 'auth.link' | 'auth.completion' | 'bladeComponent.link' | 'config.diagnostics' | 'config.hover' | 'config.link' | 'config.completion' | 'controllerAction.diagnostics' | 'controllerAction.hover' | 'controllerAction.link' | 'controllerAction.completion' | 'env.diagnostics' | 'env.hover' | 'env.link' | 'env.completion' | 'inertia.diagnostics' | 'inertia.hover' | 'inertia.link' | 'inertia.completion' | 'livewireComponent.link' | 'middleware.diagnostics' | 'middleware.hover' | 'middleware.link' | 'middleware.completion' | 'mix.diagnostics' | 'mix.hover' | 'mix.link' | 'mix.completion' | 'paths.link' | 'route.diagnostics' | 'route.hover' | 'route.link' | 'route.completion' | 'translation.diagnostics' | 'translation.hover' | 'translation.link' | 'translation.completion' | 'view.diagnostics' | 'view.hover' | 'view.link' | 'view.completion';

0 commit comments

Comments
 (0)