private static List<TemplateImpl> listApplicableTemplates(PsiFile file, int offset) { Set<TemplateContextType> contextTypes = TemplateManagerImpl.getApplicableContextTypes(file, offset); final ArrayList<TemplateImpl> result = ContainerUtil.newArrayList(); for (final TemplateImpl template : TemplateSettings.getInstance().getTemplates()) { if (!template.isDeactivated() && TemplateManagerImpl.isApplicable(template, contextTypes)) { result.add(template); } } return result; }
@TestOnly public static void setTemplateTesting(Project project, Disposable parentDisposable) { final TemplateManagerImpl instance = (TemplateManagerImpl) getInstance(project); instance.myTemplateTesting = true; Disposer.register( parentDisposable, new Disposable() { @Override public void dispose() { instance.myTemplateTesting = false; } }); }
public static void setHighlighter(Editor editor, TemplateContext templateContext) { SyntaxHighlighter baseHighlighter = null; for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { if (templateContext.isEnabled(type)) { baseHighlighter = type.createHighlighter(); if (baseHighlighter != null) break; } } if (baseHighlighter == null) { baseHighlighter = new PlainSyntaxHighlighter(); } SyntaxHighlighter highlighter = createTemplateTextHighlighter(baseHighlighter); ((EditorEx) editor) .setHighlighter( new LexerEditorHighlighter( highlighter, EditorColorsManager.getInstance().getGlobalScheme())); }
@Override public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext); final Project project = file.getProject(); PsiDocumentManager.getInstance(project).commitAllDocuments(); final TextRange selection = new TextRange( editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd()); PsiElement current = file.findElementAt(selection.getStartOffset()); int startOffset = selection.getStartOffset(); while (current instanceof PsiWhiteSpace) { current = current.getNextSibling(); if (current == null) break; startOffset = current.getTextRange().getStartOffset(); } if (startOffset >= selection.getEndOffset()) startOffset = selection.getStartOffset(); final PsiElement[] psiElements = PsiTreeUtil.collectElements( file, new PsiElementFilter() { @Override public boolean isAccepted(PsiElement element) { return selection.contains(element.getTextRange()) && element.getReferences().length > 0; } }); final Document document = EditorFactory.getInstance() .createDocument( editor.getDocument().getText().substring(startOffset, selection.getEndOffset())); final boolean isXml = file.getLanguage().is(StdLanguages.XML); final int offsetDelta = startOffset; new WriteCommandAction.Simple(project, (String) null) { @Override protected void run() throws Throwable { Map<RangeMarker, String> rangeToText = new HashMap<RangeMarker, String>(); for (PsiElement element : psiElements) { for (PsiReference reference : element.getReferences()) { if (!(reference instanceof PsiQualifiedReference) || ((PsiQualifiedReference) reference).getQualifier() == null) { String canonicalText = reference.getCanonicalText(); LOG.assertTrue(canonicalText != null, reference.getClass()); TextRange referenceRange = reference.getRangeInElement(); final TextRange elementTextRange = element.getTextRange(); LOG.assertTrue(elementTextRange != null, elementTextRange); final TextRange range = elementTextRange.cutOut(referenceRange).shiftRight(-offsetDelta); final String oldText = document.getText(range); // workaround for Java references: canonicalText contains generics, and we need to cut // them off because otherwise // they will be duplicated int pos = canonicalText.indexOf('<'); if (pos > 0 && !oldText.contains("<")) { canonicalText = canonicalText.substring(0, pos); } if (isXml) { // strip namespace prefixes pos = canonicalText.lastIndexOf(':'); if (pos >= 0 && pos < canonicalText.length() - 1 && !oldText.contains(":")) { canonicalText = canonicalText.substring(pos + 1); } } if (!canonicalText.equals(oldText)) { rangeToText.put(document.createRangeMarker(range), canonicalText); } } } } for (Map.Entry<RangeMarker, String> entry : rangeToText.entrySet()) { document.replaceString( entry.getKey().getStartOffset(), entry.getKey().getEndOffset(), entry.getValue()); } } }.execute(); final TemplateImpl template = new TemplateImpl( TemplateListPanel.ABBREVIATION, document.getText(), TemplateSettings.USER_GROUP_NAME); template.setToReformat(true); PsiFile copy; AccessToken token = WriteAction.start(); try { copy = TemplateManagerImpl.insertDummyIdentifier(editor, file); } finally { token.finish(); } Set<TemplateContextType> applicable = TemplateManagerImpl.getApplicableContextTypes(copy, startOffset); for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) { template.getTemplateContext().setEnabled(contextType, applicable.contains(contextType)); } final LiveTemplatesConfigurable configurable = new LiveTemplatesConfigurable(); ShowSettingsUtil.getInstance() .editConfigurable( project, configurable, () -> configurable.getTemplateListPanel().addTemplate(template)); }