Skip to content

Commit a249dc5

Browse files
committed
provide incomplete tags / function completion for Twig
1 parent 31020b3 commit a249dc5

File tree

3 files changed

+140
-2
lines changed

3 files changed

+140
-2
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public Comparable weigh(@NotNull LookupElement element) {
131131
int pos = elements.indexOf(lookupString) + 1;
132132

133133
// we reversed the list so, top most element has higher negative value now
134-
return -1000 - pos;
134+
return 8000 - pos;
135135
}
136136
}
137137
}

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

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import com.intellij.codeInsight.lookup.LookupElementBuilder;
66
import com.intellij.openapi.project.Project;
77
import com.intellij.openapi.util.Pair;
8-
import com.intellij.patterns.PlatformPatterns;
8+
import com.intellij.patterns.*;
99
import com.intellij.psi.PsiElement;
1010
import com.intellij.psi.PsiFile;
1111
import com.intellij.psi.PsiWhiteSpace;
@@ -406,6 +406,45 @@ public void addCompletions(@NotNull CompletionParameters parameters, ProcessingC
406406
}
407407
}
408408
);
409+
410+
// {% e => {% extends '...'
411+
extend(
412+
CompletionType.BASIC,
413+
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME).withSuperParent(2, PsiFile.class),
414+
new IncompleteExtendsCompletionProvider()
415+
);
416+
417+
// {% in => {% include '...'
418+
extend(
419+
CompletionType.BASIC,
420+
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME),
421+
new IncompleteIncludeCompletionProvider()
422+
);
423+
424+
// {{ in => {{ include('...')
425+
extend(
426+
CompletionType.BASIC,
427+
TwigPattern.getCompletablePattern(),
428+
new IncompleteIncludePrintBlockCompletionProvider()
429+
);
430+
}
431+
432+
private boolean isCompletionStartingMatch(@NotNull String fullText, @NotNull CompletionParameters completionParameters, int minLength) {
433+
PsiElement originalPosition = completionParameters.getOriginalPosition();
434+
if (originalPosition != null) {
435+
String text = originalPosition.getText();
436+
if (text.length() >= minLength && fullText.startsWith(text)) {
437+
return true;
438+
}
439+
}
440+
441+
PsiElement position = completionParameters.getPosition();
442+
String text = position.getText().toLowerCase().replace("intellijidearulezzz", "");
443+
if (text.length() >= minLength && fullText.startsWith(text)) {
444+
return true;
445+
}
446+
447+
return false;
409448
}
410449

411450
private static class FilterCompletionProvider extends CompletionProvider<CompletionParameters> {
@@ -664,5 +703,103 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
664703
);
665704
}
666705
}
706+
707+
/**
708+
* {% e => {% extends '...'
709+
*/
710+
private class IncompleteExtendsCompletionProvider extends CompletionProvider<CompletionParameters> {
711+
@Override
712+
protected void addCompletions(@NotNull CompletionParameters completionParameters, @NotNull ProcessingContext processingContext, @NotNull CompletionResultSet resultSet) {
713+
if(!Symfony2ProjectComponent.isEnabled(completionParameters.getPosition())) {
714+
return;
715+
}
716+
717+
if (!isCompletionStartingMatch("extends", completionParameters, 1)) {
718+
return;
719+
}
720+
721+
List<String> extendsTemplateUsageAsOrderedList = TwigUtil.getExtendsTemplateUsageAsOrderedList(completionParameters.getPosition().getProject(), 50);
722+
723+
CompletionSorter completionSorter = CompletionService.getCompletionService()
724+
.defaultSorter(completionParameters, resultSet.getPrefixMatcher())
725+
.weigh(new ServiceCompletionProvider.MyLookupElementWeigher(extendsTemplateUsageAsOrderedList));
726+
727+
resultSet = resultSet.withRelevanceSorter(completionSorter);
728+
729+
for (String s : extendsTemplateUsageAsOrderedList) {
730+
resultSet.addElement(LookupElementBuilder.create(String.format("extends '%s'", s)).withIcon(TwigIcons.TwigFileIcon));
731+
}
732+
}
733+
}
734+
735+
/**
736+
* {% in => {% include '...'
737+
*/
738+
private class IncompleteIncludeCompletionProvider extends CompletionProvider<CompletionParameters> {
739+
@Override
740+
protected void addCompletions(@NotNull CompletionParameters completionParameters, @NotNull ProcessingContext processingContext, @NotNull CompletionResultSet resultSet) {
741+
if(!Symfony2ProjectComponent.isEnabled(completionParameters.getPosition())) {
742+
return;
743+
}
744+
745+
resultSet.restartCompletionOnPrefixChange(StandardPatterns.string().longerThan(1).with(new PatternCondition<>("include startsWith") {
746+
@Override
747+
public boolean accepts(@NotNull String s, ProcessingContext processingContext) {
748+
return "include".startsWith(s);
749+
}
750+
}));
751+
752+
if (!isCompletionStartingMatch("include", completionParameters, 2)) {
753+
return;
754+
}
755+
756+
List<String> extendsTemplateUsageAsOrderedList = TwigUtil.getIncludeTemplateUsageAsOrderedList(completionParameters.getPosition().getProject(), 50);
757+
758+
CompletionSorter completionSorter = CompletionService.getCompletionService()
759+
.defaultSorter(completionParameters, resultSet.getPrefixMatcher())
760+
.weigh(new ServiceCompletionProvider.MyLookupElementWeigher(extendsTemplateUsageAsOrderedList));
761+
762+
resultSet = resultSet.withRelevanceSorter(completionSorter);
763+
764+
for (String s : extendsTemplateUsageAsOrderedList) {
765+
resultSet.addElement(LookupElementBuilder.create(String.format("include '%s'", s)).withIcon(TwigIcons.TwigFileIcon));
766+
}
767+
}
768+
}
769+
770+
/**
771+
* {{ in => {{ include('...')
772+
*/
773+
private class IncompleteIncludePrintBlockCompletionProvider extends CompletionProvider<CompletionParameters> {
774+
@Override
775+
protected void addCompletions(@NotNull CompletionParameters completionParameters, @NotNull ProcessingContext processingContext, @NotNull CompletionResultSet resultSet) {
776+
if(!Symfony2ProjectComponent.isEnabled(completionParameters.getPosition())) {
777+
return;
778+
}
779+
780+
resultSet.restartCompletionOnPrefixChange(StandardPatterns.string().longerThan(1).with(new PatternCondition<>("include startsWith") {
781+
@Override
782+
public boolean accepts(@NotNull String s, ProcessingContext processingContext) {
783+
return "include".startsWith(s);
784+
}
785+
}));
786+
787+
if (!isCompletionStartingMatch("include", completionParameters, 2)) {
788+
return;
789+
}
790+
791+
List<String> extendsTemplateUsageAsOrderedList = TwigUtil.getIncludeTemplateUsageAsOrderedList(completionParameters.getPosition().getProject(), 50);
792+
793+
CompletionSorter completionSorter = CompletionService.getCompletionService()
794+
.defaultSorter(completionParameters, resultSet.getPrefixMatcher())
795+
.weigh(new ServiceCompletionProvider.MyLookupElementWeigher(extendsTemplateUsageAsOrderedList));
796+
797+
resultSet = resultSet.withRelevanceSorter(completionSorter);
798+
799+
for (String s : extendsTemplateUsageAsOrderedList) {
800+
resultSet.addElement(LookupElementBuilder.create(String.format("include('%s')", s)).withIcon(TwigIcons.TwigFileIcon));
801+
}
802+
}
803+
}
667804
}
668805

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/completion/TwigHtmlCompletionContributor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.intellij.codeInsight.completion.*;
44
import com.intellij.codeInsight.lookup.LookupElement;
5+
import com.intellij.codeInsight.lookup.LookupElementBuilder;
56
import com.intellij.patterns.ElementPattern;
67
import com.intellij.patterns.PlatformPatterns;
78
import com.intellij.psi.PsiElement;

0 commit comments

Comments
 (0)