Skip to content

Commit 26cd25c

Browse files
authored
Merge pull request #1783 from Haehnchen/feature/template-weight-completion
add Twig "include" and "extends" lookup element weight sorting
2 parents 7aecaa3 + 7c363fe commit 26cd25c

File tree

5 files changed

+85
-39
lines changed

5 files changed

+85
-39
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/ServiceCompletionProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ public List<String> getTopStrings() {
107107
}
108108
}
109109

110-
private static class MyLookupElementWeigher extends LookupElementWeigher {
110+
public static class MyLookupElementWeigher extends LookupElementWeigher {
111111
@NotNull
112112
private final List<String> elements;
113113

114-
MyLookupElementWeigher(@NotNull List<String> elements) {
114+
public MyLookupElementWeigher(@NotNull List<String> elements) {
115115
super("topElement");
116116
this.elements = elements;
117117

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TemplateLookupElement.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class TemplateLookupElement extends LookupElement {
2323
@NotNull
2424
private final String templateName;
2525

26+
private boolean bold = false;
27+
2628
@Nullable
2729
private InsertHandler<LookupElement> insertHandler = null;
2830

@@ -32,6 +34,11 @@ public TemplateLookupElement(@NotNull String templateName, @NotNull VirtualFile
3234
this.projectBaseDir = projectBaseDir;
3335
}
3436

37+
public TemplateLookupElement(@NotNull String templateName, @NotNull VirtualFile virtualFile, @NotNull VirtualFile projectBaseDir, boolean bold) {
38+
this(templateName, virtualFile, projectBaseDir);
39+
this.bold = bold;
40+
}
41+
3542
@NotNull
3643
@Override
3744
public String getLookupString() {
@@ -49,5 +56,6 @@ public void renderElement(LookupElementPresentation presentation) {
4956
presentation.setIcon(this.virtualFile.getFileType().getIcon());
5057
presentation.setTypeText(VfsUtil.getRelativePath(this.virtualFile, this.projectBaseDir, '/'));
5158
presentation.setTypeGrayed(true);
59+
presentation.setItemTextBold(bold);
5260
}
5361
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
2323
import fr.adrienbrault.idea.symfony2plugin.asset.AssetDirectoryReader;
2424
import fr.adrienbrault.idea.symfony2plugin.asset.provider.AssetCompletionProvider;
25+
import fr.adrienbrault.idea.symfony2plugin.dic.ServiceCompletionProvider;
2526
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
2627
import fr.adrienbrault.idea.symfony2plugin.templating.completion.QuotedInsertionLookupElement;
2728
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigExtension;
@@ -71,7 +72,7 @@ public TwigTemplateCompletionContributor() {
7172
TwigPattern.getPrintBlockOrTagFunctionPattern("include", "source"),
7273
TwigPattern.getIncludeTagArrayPattern(),
7374
TwigPattern.getTagTernaryPattern(TwigElementTypes.INCLUDE_TAG)
74-
), new TemplateCompletionProvider());
75+
), new TemplateCompletionProvider());
7576

7677
// provides support for 'a<xxx>'|trans({'%foo%' : bar|default}, 'Domain')
7778
// provides support for 'a<xxx>'|transchoice(2, {'%foo%' : bar|default}, 'Domain')
@@ -503,7 +504,7 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
503504
return;
504505
}
505506

506-
resultSet.addAllElements(TwigUtil.getTwigLookupElements(parameters.getPosition().getProject()));
507+
resultSet.addAllElements(TwigUtil.getTwigLookupElements(parameters.getPosition().getProject(), Collections.emptyList()));
507508
}
508509
}
509510

@@ -573,16 +574,33 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
573574

574575
}
575576

576-
private class TemplateCompletionProvider extends CompletionProvider<CompletionParameters> {
577+
private static class TemplateCompletionProvider extends CompletionProvider<CompletionParameters> {
577578
public void addCompletions(@NotNull CompletionParameters parameters,
578-
ProcessingContext context,
579-
@NotNull CompletionResultSet resultSet) {
579+
@NotNull ProcessingContext context,
580+
@NotNull CompletionResultSet resultSet) {
580581

581582
if(!Symfony2ProjectComponent.isEnabled(parameters.getPosition())) {
582583
return;
583584
}
584585

585-
resultSet.addAllElements(TwigUtil.getTwigLookupElements(parameters.getPosition().getProject()));
586+
List<String> prioritizedKeys = new ArrayList<>();
587+
Project project = parameters.getPosition().getProject();
588+
589+
if (TwigPattern.getTemplateFileReferenceTagPattern("extends").accepts(parameters.getPosition())) {
590+
prioritizedKeys.addAll(TwigUtil.getExtendsTemplateUsageAsOrderedList(project, 50));
591+
} else if(TwigPattern.getTemplateFileReferenceTagPattern("include").accepts(parameters.getPosition())) {
592+
prioritizedKeys.addAll(TwigUtil.getIncludeTemplateUsageAsOrderedList(project, 50));
593+
}
594+
595+
if (prioritizedKeys.size() > 0) {
596+
CompletionSorter completionSorter = CompletionService.getCompletionService()
597+
.defaultSorter(parameters, resultSet.getPrefixMatcher())
598+
.weighBefore("priority", new ServiceCompletionProvider.MyLookupElementWeigher(prioritizedKeys));
599+
600+
resultSet = resultSet.withRelevanceSorter(completionSorter);
601+
}
602+
603+
resultSet.addAllElements(TwigUtil.getTwigLookupElements(project, new HashSet<>(prioritizedKeys)));
586604
}
587605
}
588606

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/action/TwigExtendsGenerator.java

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,17 @@
88
import com.intellij.openapi.editor.Editor;
99
import com.intellij.openapi.project.Project;
1010
import com.intellij.openapi.ui.popup.JBPopupFactory;
11-
import com.intellij.openapi.vfs.VirtualFile;
1211
import com.intellij.psi.PsiElement;
1312
import com.intellij.psi.PsiFile;
1413
import com.intellij.psi.impl.source.html.HtmlFileImpl;
15-
import com.intellij.psi.search.GlobalSearchScope;
1614
import com.intellij.util.ThrowableRunnable;
17-
import com.intellij.util.indexing.FileBasedIndex;
1815
import com.jetbrains.php.completion.insert.PhpInsertHandlerUtil;
1916
import com.jetbrains.twig.TwigFile;
2017
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
21-
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigExtendsStubIndex;
2218
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
2319
import org.jetbrains.annotations.NotNull;
2420

25-
import java.util.*;
21+
import java.util.List;
2622
import java.util.function.Function;
2723
import java.util.stream.Collectors;
2824

@@ -53,23 +49,7 @@ public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull Ps
5349
return;
5450
}
5551

56-
Set<String> allKeys = FileBasedIndex.getInstance().getAllKeys(TwigExtendsStubIndex.KEY, project)
57-
.stream()
58-
.filter(s -> !s.toLowerCase().contains("@webprofiler") && !s.toLowerCase().contains("/profiler/") && !s.toLowerCase().contains("@twig") && !s.equalsIgnoreCase("form_div_layout.html.twig"))
59-
.collect(Collectors.toSet());
60-
61-
Map<String, Integer> extendsWithFileCountUsage = new HashMap<>();
62-
for (String allKey : allKeys) {
63-
Collection<VirtualFile> containingFiles = FileBasedIndex.getInstance().getContainingFiles(TwigExtendsStubIndex.KEY, allKey, GlobalSearchScope.allScope(project));
64-
extendsWithFileCountUsage.put(allKey, containingFiles.size());
65-
}
66-
67-
List<String> prioritizedKeys = extendsWithFileCountUsage.entrySet()
68-
.stream()
69-
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
70-
.map(Map.Entry::getKey)
71-
.limit(40)
72-
.collect(Collectors.toList());
52+
List<String> prioritizedKeys = TwigUtil.getExtendsTemplateUsageAsOrderedList(project, 40);
7353

7454
if (prioritizedKeys.size() == 0) {
7555
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@
4343
import fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtensionParameter;
4444
import fr.adrienbrault.idea.symfony2plugin.stubs.SymfonyProcessors;
4545
import fr.adrienbrault.idea.symfony2plugin.stubs.dict.TemplateUsage;
46-
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.PhpTwigTemplateUsageStubIndex;
47-
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigBlockIndexExtension;
48-
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigExtendsStubIndex;
49-
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigMacroFunctionStubIndex;
46+
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.*;
5047
import fr.adrienbrault.idea.symfony2plugin.templating.TemplateLookupElement;
5148
import fr.adrienbrault.idea.symfony2plugin.templating.TwigPattern;
5249
import fr.adrienbrault.idea.symfony2plugin.templating.dict.*;
@@ -1527,17 +1524,20 @@ public static Collection<PsiElement> getTwigMacroTargets(final Project project,
15271524

15281525
/**
15291526
* Lookup elements for Twig files
1527+
* @return
15301528
*/
15311529
@NotNull
1532-
public static Collection<LookupElement> getTwigLookupElements(@NotNull Project project) {
1530+
public static Collection<LookupElement> getTwigLookupElements(@NotNull Project project, @NotNull Collection<String> highlight) {
15331531
VirtualFile baseDir = ProjectUtil.getProjectDir(project);
1534-
15351532
return getTemplateMap(project).entrySet()
15361533
.stream()
15371534
.filter(entry -> entry.getValue().size() > 0)
1538-
.map((java.util.function.Function<Map.Entry<String, Set<VirtualFile>>, LookupElement>) entry ->
1539-
new TemplateLookupElement(entry.getKey(), entry.getValue().iterator().next(), baseDir)
1540-
)
1535+
.map((java.util.function.Function<Map.Entry<String, Set<VirtualFile>>, LookupElement>) entry -> new TemplateLookupElement(
1536+
entry.getKey(),
1537+
entry.getValue().iterator().next(),
1538+
baseDir,
1539+
highlight.contains(entry.getKey())
1540+
))
15411541
.collect(Collectors.toList());
15421542
}
15431543

@@ -2787,6 +2787,46 @@ public void visitElement(PsiElement element) {
27872787
});
27882788
}
27892789

2790+
public static List<String> getIncludeTemplateUsageAsOrderedList(@NotNull Project project, int limit) {
2791+
Set<String> allKeys = FileBasedIndex.getInstance().getAllKeys(TwigIncludeStubIndex.KEY, project)
2792+
.stream()
2793+
.filter(s -> !s.toLowerCase().contains("@webprofiler") && !s.toLowerCase().contains("/profiler/") && !s.toLowerCase().contains("@twig") && !s.equalsIgnoreCase("form_div_layout.html.twig"))
2794+
.collect(Collectors.toSet());
2795+
2796+
Map<String, Integer> extendsWithFileCountUsage = new HashMap<>();
2797+
for (String allKey : allKeys) {
2798+
Collection<VirtualFile> containingFiles = FileBasedIndex.getInstance().getContainingFiles(TwigIncludeStubIndex.KEY, allKey, GlobalSearchScope.allScope(project));
2799+
extendsWithFileCountUsage.put(allKey, containingFiles.size());
2800+
}
2801+
2802+
return extendsWithFileCountUsage.entrySet()
2803+
.stream()
2804+
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
2805+
.map(Map.Entry::getKey)
2806+
.limit(limit)
2807+
.collect(Collectors.toList());
2808+
}
2809+
2810+
public static List<String> getExtendsTemplateUsageAsOrderedList(@NotNull Project project, int limit) {
2811+
Set<String> allKeys = FileBasedIndex.getInstance().getAllKeys(TwigExtendsStubIndex.KEY, project)
2812+
.stream()
2813+
.filter(s -> !s.toLowerCase().contains("@webprofiler") && !s.toLowerCase().contains("/profiler/") && !s.toLowerCase().contains("@twig") && !s.equalsIgnoreCase("form_div_layout.html.twig"))
2814+
.collect(Collectors.toSet());
2815+
2816+
Map<String, Integer> extendsWithFileCountUsage = new HashMap<>();
2817+
for (String allKey : allKeys) {
2818+
Collection<VirtualFile> containingFiles = FileBasedIndex.getInstance().getContainingFiles(TwigExtendsStubIndex.KEY, allKey, GlobalSearchScope.allScope(project));
2819+
extendsWithFileCountUsage.put(allKey, containingFiles.size());
2820+
}
2821+
2822+
return extendsWithFileCountUsage.entrySet()
2823+
.stream()
2824+
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
2825+
.map(Map.Entry::getKey)
2826+
.limit(limit)
2827+
.collect(Collectors.toList());
2828+
}
2829+
27902830
/**
27912831
* Visit each "controller()" with its normalized parameter
27922832
*/

0 commit comments

Comments
 (0)