Skip to content
This repository was archived by the owner on Mar 12, 2022. It is now read-only.

Commit 7126f98

Browse files
committed
provide directory navigation for Blade template strings
1 parent 8bc7c41 commit 7126f98

File tree

6 files changed

+114
-11
lines changed

6 files changed

+114
-11
lines changed

src/de/espend/idea/laravel/blade/util/BladeTemplateUtil.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,44 @@ public static void visitUpPath(final PsiFile psiFile, int depth, final Directive
219219
});
220220
}
221221

222+
/**
223+
* Try to find directory or file navigation for template name
224+
*
225+
* "foo.bar" => "foo", "bar"
226+
*/
227+
@NotNull
228+
public static Collection<VirtualFile> resolveTemplate(@NotNull Project project, @NotNull String templateName, int offset) {
229+
Set<VirtualFile> files = new HashSet<>();
230+
231+
// try to find a path pattern on current offset after path normalization
232+
if(offset > 0 && offset < templateName.length()) {
233+
String templateNameWithCaret = normalizeTemplate(new StringBuilder(templateName).insert(offset, '\u0182').toString()).replace("/", ".");
234+
offset = templateNameWithCaret.indexOf('\u0182');
235+
236+
int i = StringUtils.strip(templateNameWithCaret.replace(String.valueOf('\u0182'), ""), "/").indexOf(".", offset);
237+
if(i > 0) {
238+
files.addAll(resolveTemplateDirectory(project, templateName.substring(0, i)));
239+
}
240+
}
241+
242+
// full filepath fallback: "foo/foo<caret>.blade.php"
243+
if(files.size() == 0) {
244+
files.addAll(resolveTemplateName(project, templateName));
245+
}
246+
247+
return files;
248+
}
249+
250+
/**
251+
* Normalize template path
252+
*/
253+
@NotNull
254+
public static String normalizeTemplate(@NotNull String templateName) {
255+
return templateName
256+
.replace("\\", "/")
257+
.replaceAll("/+", "/");
258+
}
259+
222260
private static class DirectivePsiRecursiveElementWalkingVisitor extends PsiRecursiveElementWalkingVisitor {
223261

224262
@NotNull

src/de/espend/idea/laravel/view/ViewReferences.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.codeInsight.lookup.LookupElement;
44
import com.intellij.codeInsight.lookup.LookupElementBuilder;
55
import com.intellij.openapi.application.ApplicationManager;
6+
import com.intellij.openapi.editor.Editor;
67
import com.intellij.openapi.vfs.VirtualFile;
78
import com.intellij.patterns.PlatformPatterns;
89
import com.intellij.psi.PsiElement;
@@ -197,18 +198,27 @@ public Collection<LookupElement> getLookupElements() {
197198

198199
@NotNull
199200
@Override
200-
public Collection<PsiElement> getPsiTargets(StringLiteralExpression element) {
201-
String content = element.getContents();
202-
if(StringUtils.isBlank(content)) {
201+
public Collection<? extends PsiElement> getPsiTargets(@NotNull PsiElement psiElement, int offset, @NotNull Editor editor) {
202+
PsiElement stringLiteral = psiElement.getParent();
203+
if(!(stringLiteral instanceof StringLiteralExpression)) {
203204
return Collections.emptyList();
204205
}
205206

206-
Collection<PsiElement> targets = new ArrayList<>(
207-
PsiElementUtils.convertVirtualFilesToPsiFiles(getProject(), BladeTemplateUtil.resolveTemplateName(getProject(), content))
208-
);
207+
String contents = ((StringLiteralExpression) stringLiteral).getContents();
208+
if(StringUtils.isBlank(contents)) {
209+
return Collections.emptyList();
210+
}
211+
212+
// select position of click event
213+
int caretOffset = offset - psiElement.getTextRange().getStartOffset();
214+
215+
Collection<PsiElement> targets = new ArrayList<>(PsiElementUtils.convertVirtualFilesToPsiFiles(
216+
getProject(),
217+
BladeTemplateUtil.resolveTemplate(getProject(), contents, caretOffset)
218+
));
209219

210220
// @TODO: no filesystem access in test; fake item
211-
if("test_view".equals(content) && ApplicationManager.getApplication().isUnitTestMode()) {
221+
if("test_view".equals(contents) && ApplicationManager.getApplication().isUnitTestMode()) {
212222
targets.add(PsiManager.getInstance(getProject()).findDirectory(getProject().getBaseDir()));
213223
}
214224

src/fr/adrienbrault/idea/symfony2plugin/codeInsight/GotoCompletionProvider.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package fr.adrienbrault.idea.symfony2plugin.codeInsight;
22

3+
import com.intellij.openapi.editor.Editor;
34
import com.intellij.openapi.project.Project;
45
import com.intellij.psi.PsiElement;
56
import fr.adrienbrault.idea.symfony2plugin.codeInsight.completion.CompletionContributorParameter;
@@ -30,4 +31,9 @@ public Collection<PsiElement> getPsiTargets(PsiElement element) {
3031
}
3132

3233
public void getLookupElements(CompletionContributorParameter parameter) {}
34+
35+
@NotNull
36+
public Collection<? extends PsiElement> getPsiTargets(@NotNull PsiElement psiElement, int offset, @NotNull Editor editor) {
37+
return Collections.emptyList();
38+
}
3339
}

src/fr/adrienbrault/idea/symfony2plugin/codeInsight/GotoCompletionProviderInterface.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.adrienbrault.idea.symfony2plugin.codeInsight;
22

33
import com.intellij.codeInsight.lookup.LookupElement;
4+
import com.intellij.openapi.editor.Editor;
45
import com.intellij.psi.PsiElement;
56
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
67
import fr.adrienbrault.idea.symfony2plugin.codeInsight.completion.CompletionContributorParameter;
@@ -22,4 +23,7 @@ default Collection<PsiElement> getPsiTargets(StringLiteralExpression element) {
2223

2324
@NotNull
2425
Collection<PsiElement> getPsiTargets(PsiElement element);
26+
27+
@NotNull
28+
Collection<? extends PsiElement> getPsiTargets(@NotNull PsiElement psiElement, int offset, @NotNull Editor editor);
2529
}

src/fr/adrienbrault/idea/symfony2plugin/codeInsight/navigation/GotoHandler.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
2828
PsiElement parent = psiElement.getParent();
2929

3030
for(GotoCompletionContributor contributor: GotoCompletionUtil.getContributors(psiElement)) {
31-
GotoCompletionProviderInterface formReferenceCompletionContributor = contributor.getProvider(psiElement);
32-
if(formReferenceCompletionContributor != null) {
31+
GotoCompletionProviderInterface gotoCompletionContributorProvider = contributor.getProvider(psiElement);
32+
if(gotoCompletionContributorProvider != null) {
3333
// @TODO: replace this: just valid PHP files
3434
if(parent instanceof StringLiteralExpression) {
35-
psiTargets.addAll(formReferenceCompletionContributor.getPsiTargets((StringLiteralExpression) parent));
35+
psiTargets.addAll(gotoCompletionContributorProvider.getPsiTargets((StringLiteralExpression) parent));
3636
} else {
37-
psiTargets.addAll(formReferenceCompletionContributor.getPsiTargets(psiElement));
37+
psiTargets.addAll(gotoCompletionContributorProvider.getPsiTargets(psiElement));
3838
}
39+
40+
psiTargets.addAll(gotoCompletionContributorProvider.getPsiTargets(psiElement, i, editor));
3941
}
4042
}
4143

tests/de/espend/idea/laravel/tests/blade/util/BladeTemplateUtilTempTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,47 @@ public void testResolveTemplateDirectory() {
138138
.orElse(null)
139139
);
140140
}
141+
142+
/**
143+
* @see BladeTemplateUtil#resolveTemplate
144+
*/
145+
public void testResolveTemplate() {
146+
createFiles("resources/views/foobar/foo/foo_blade.blade.php");
147+
148+
assertNotNull(BladeTemplateUtil.resolveTemplate(getProject(), "foobar.foo.foo_blade", 3)
149+
.stream()
150+
.filter(virtualFile -> virtualFile.isDirectory() && "foobar".equals(virtualFile.getName()))
151+
.findFirst()
152+
.orElseGet(null)
153+
);
154+
155+
assertNotNull(BladeTemplateUtil.resolveTemplate(getProject(), "foobar.foo.foo_blade", 9)
156+
.stream()
157+
.filter(virtualFile -> virtualFile.isDirectory() && "foo".equals(virtualFile.getName()))
158+
.findFirst()
159+
.orElseGet(null)
160+
);
161+
162+
assertNotNull(BladeTemplateUtil.resolveTemplate(getProject(), "foobar/foo/foo_blade", 9)
163+
.stream()
164+
.filter(virtualFile -> virtualFile.isDirectory() && "foo".equals(virtualFile.getName()))
165+
.findFirst()
166+
.orElseGet(null)
167+
);
168+
169+
assertNotNull(BladeTemplateUtil.resolveTemplate(getProject(), "foobar.foo.foo_blade", 14)
170+
.stream()
171+
.filter(virtualFile -> "foo_blade.blade.php".equals(virtualFile.getName()))
172+
.findFirst()
173+
.orElseGet(null)
174+
);
175+
}
176+
177+
/**
178+
* @see BladeTemplateUtil#normalizeTemplate
179+
*/
180+
public void testNormalizeTemplate() {
181+
assertEquals("foo/bar", BladeTemplateUtil.normalizeTemplate("foo\\bar"));
182+
assertEquals("foo/bar", BladeTemplateUtil.normalizeTemplate("foo\\\\bar"));
183+
}
141184
}

0 commit comments

Comments
 (0)