Skip to content

Commit b8ebae2

Browse files
authored
Merge pull request #1781 from Haehnchen/feature/twig-block-generator
add Twig block overwrite generator action
2 parents bc2d020 + bca0c12 commit b8ebae2

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/Symfony2Icons.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public class Symfony2Icons {
7474
public static final Icon CONFIG_VALUE = IconLoader.getIcon("/icons/config_value.png");
7575
public static final Icon CONFIG_VALUE_SHORTCUT = IconLoader.getIcon("/icons/config_value_shortcut.png");
7676

77+
public static final Icon TWIG_BLOCK_OVERWRITE = IconLoader.getIcon("/icons/twig_block_overwrite.png");
78+
7779
public static Image getImage(Icon icon) {
7880

7981
if (icon instanceof ImageIcon) {
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package fr.adrienbrault.idea.symfony2plugin.templating.action;
2+
3+
import com.intellij.codeInsight.CodeInsightActionHandler;
4+
import com.intellij.codeInsight.actions.CodeInsightAction;
5+
import com.intellij.codeInsight.hint.HintManager;
6+
import com.intellij.codeInsight.lookup.LookupElement;
7+
import com.intellij.openapi.application.ApplicationManager;
8+
import com.intellij.openapi.command.WriteCommandAction;
9+
import com.intellij.openapi.editor.Editor;
10+
import com.intellij.openapi.project.Project;
11+
import com.intellij.openapi.ui.popup.JBPopupFactory;
12+
import com.intellij.openapi.util.Pair;
13+
import com.intellij.psi.PsiElement;
14+
import com.intellij.psi.PsiFile;
15+
import com.intellij.psi.impl.source.html.HtmlFileImpl;
16+
import com.intellij.util.ThrowableRunnable;
17+
import com.jetbrains.php.completion.insert.PhpInsertHandlerUtil;
18+
import com.jetbrains.twig.TwigFile;
19+
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
20+
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
21+
import fr.adrienbrault.idea.symfony2plugin.twig.utils.TwigFileUtil;
22+
import icons.TwigIcons;
23+
import org.apache.commons.lang.StringUtils;
24+
import org.jetbrains.annotations.NotNull;
25+
import org.jetbrains.annotations.Nullable;
26+
27+
import java.util.Collection;
28+
import java.util.List;
29+
import java.util.function.Function;
30+
import java.util.stream.Collectors;
31+
32+
/**
33+
* @author Daniel Espendiller <daniel@espendiller.net>
34+
*/
35+
public class TwigBlockOverwriteGenerator extends CodeInsightAction {
36+
@Override
37+
protected @NotNull
38+
CodeInsightActionHandler getHandler() {
39+
return new MyCodeInsightActionHandler();
40+
}
41+
42+
@Override
43+
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
44+
return Symfony2ProjectComponent.isEnabled(project) && (
45+
file instanceof TwigFile
46+
|| (file instanceof HtmlFileImpl && file.getName().toLowerCase().endsWith(".twig"))
47+
|| getInjectedTwigElement(file, editor) != null
48+
);
49+
}
50+
51+
@Nullable
52+
private static PsiElement getInjectedTwigElement(@NotNull PsiFile psiFile, @NotNull Editor editor) {
53+
int caretOffset = editor.getCaretModel().getOffset();
54+
if(caretOffset <= 0) {
55+
return null;
56+
}
57+
58+
PsiElement psiElement = psiFile.findElementAt(caretOffset - 1);
59+
if(psiElement == null) {
60+
return null;
61+
}
62+
63+
return TwigUtil.getElementOnTwigViewProvider(psiElement);
64+
}
65+
66+
private static class MyCodeInsightActionHandler implements CodeInsightActionHandler {
67+
@Override
68+
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
69+
int caretOffset = editor.getCaretModel().getOffset();
70+
if(caretOffset <= 0) {
71+
return;
72+
}
73+
74+
PsiElement psiElement = getInjectedTwigElement(file, editor);
75+
if(psiElement == null) {
76+
return;
77+
}
78+
79+
// collect blocks in all related files
80+
Pair<Collection<PsiFile>, Boolean> scopedContext = TwigUtil.findScopedFile(psiElement);
81+
82+
Collection<LookupElement> blockLookupElements = TwigUtil.getBlockLookupElements(
83+
project,
84+
TwigFileUtil.collectParentFiles(scopedContext.getSecond(), scopedContext.getFirst())
85+
);
86+
87+
List<String> items = blockLookupElements.stream()
88+
.map(LookupElement::getLookupString)
89+
.distinct()
90+
.collect(Collectors.toList());
91+
92+
if (items.size() == 0) {
93+
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
94+
HintManager.getInstance().showErrorHint(editor, "No block found");
95+
}
96+
97+
return;
98+
}
99+
100+
JBPopupFactory.getInstance().createPopupChooserBuilder(items)
101+
.setTitle("Symfony: Twig Blocks")
102+
.setItemsChosenCallback(strings -> {
103+
try {
104+
String titleBlocks = StringUtils.abbreviate(strings.stream()
105+
.map((Function<String, String>) s -> s)
106+
.collect(Collectors.joining(", ")), 10);
107+
108+
WriteCommandAction.writeCommandAction(editor.getProject())
109+
.withName("Block Overwrite: " + titleBlocks)
110+
.run((ThrowableRunnable<Throwable>) () -> {
111+
String content = strings.stream()
112+
.map((Function<String, String>) s -> "{% block " + s + " %}{% endblock %}")
113+
.collect(Collectors.joining("\n"));
114+
115+
PhpInsertHandlerUtil.insertStringAtCaret(editor, content);
116+
});
117+
} catch (Throwable ignored) {
118+
}
119+
})
120+
.createPopup()
121+
.showInBestPositionFor(editor);
122+
}
123+
}
124+
}

src/main/java/icons/SymfonyIcons.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public class SymfonyIcons {
88
public static final Icon FormType = Symfony2Icons.FORM_TYPE;
99
public static final Icon Translation = Symfony2Icons.TRANSLATION;
1010
public static final Icon SymfonyToolWindow = Symfony2Icons.SYMFONY_TOOL_WINDOW;
11+
public static final Icon TwigBlockOverwrite = Symfony2Icons.TWIG_BLOCK_OVERWRITE;
1112
}

src/main/resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,13 @@
718718
<add-to-group group-id="GoToTargetEx"/>
719719
</action>
720720

721+
<action icon="SymfonyIcons.TwigBlockOverwrite"
722+
id="SymfonyTwigBlockOverwrite"
723+
class="fr.adrienbrault.idea.symfony2plugin.templating.action.TwigBlockOverwriteGenerator"
724+
text="Block Overwrite">
725+
<add-to-group group-id="GenerateGroup"/>
726+
</action>
727+
721728
</actions>
722729
</idea-plugin>
723730

Loading
Loading

0 commit comments

Comments
 (0)