diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 77b31ead0f43..308d1fb281ce 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -24,6 +24,7 @@ import com.intellij.codeInsight.lookup.LookupManager import com.intellij.codeInsight.lookup.PsiTypeLookupItem import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.codeInsight.template.* +import com.intellij.codeInsight.template.impl.LiveTemplateDocumentationProvider import com.intellij.codeInsight.template.impl.TemplateImpl import com.intellij.codeInsight.template.impl.TemplateManagerImpl import com.intellij.codeInsight.template.impl.TemplateSettings @@ -1518,6 +1519,25 @@ class X extends Foo { assert myFixture.lookupElementStrings == ['public int getField'] } + public void "test live template quick doc"() { + myFixture.configureByText "a.java", """ +class Cls { + void foo() { + + } + void mySout() {} +} +""" + type('sout') + assert lookup + assert 'sout' in myFixture.lookupElementStrings + + def docProvider = new LiveTemplateDocumentationProvider() + def docElement = docProvider.getDocumentationElementForLookupItem(myFixture.psiManager, lookup.currentItem, null) + assert docElement.presentation.presentableText == 'sout' + assert docProvider.generateDoc(docElement, docElement).contains('System.out') + } + public void "test finishing class reference property value completion with dot opens autopopup"() { myFixture.configureByText "a.properties", "myprop=ja" type 'v' @@ -1552,5 +1572,4 @@ class Foo { def tabKeyPresentation = KeyEvent.getKeyText(TemplateSettings.TAB_CHAR as int) assert p.typeText == " [$tabKeyPresentation] " } - } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateDocumentationProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateDocumentationProvider.java new file mode 100644 index 000000000000..868c8d210faa --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateDocumentationProvider.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.template.impl; + +import com.intellij.lang.documentation.AbstractDocumentationProvider; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.FakePsiElement; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.DummyHolderFactory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class LiveTemplateDocumentationProvider extends AbstractDocumentationProvider { + @Override + public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) { + if (object instanceof LiveTemplateLookupElement) { + TemplateImpl template = ((LiveTemplateLookupElement)object).getTemplate(); + final TemplateImpl templateFromSettings = TemplateSettings.getInstance().getTemplate(template.getKey(), template.getGroupName()); + if (templateFromSettings != null) { + return new LiveTemplateElement(templateFromSettings, psiManager); + } + } + return null; + } + + @Override + public String generateDoc(PsiElement element, @Nullable PsiElement originalElement) { + if (!(element instanceof LiveTemplateElement)) { + return null; + } + + TemplateImpl template = ((LiveTemplateElement)element).getTemplate(); + String description = template.getDescription(); + if (StringUtil.isEmpty(description)) { + description = template.getTemplateText(); + } + return "

" + template.getKey() + "

" + + "
" + StringUtil.escapeXml(description) + "
"; + } + + private static class LiveTemplateElement extends FakePsiElement { + @NotNull private final TemplateImpl myTemplate; + @NotNull private final PsiManager myPsiManager; + @NotNull private DummyHolder myDummyHolder; + + public LiveTemplateElement(@NotNull TemplateImpl template, @NotNull PsiManager psiManager) { + myTemplate = template; + myPsiManager = psiManager; + myDummyHolder = DummyHolderFactory.createHolder(myPsiManager, null); + } + + @NotNull + public TemplateImpl getTemplate() { + return myTemplate; + } + + @Override + public PsiElement getParent() { + return myDummyHolder; + } + + @Override + public ItemPresentation getPresentation() { + return new ItemPresentation() { + @Nullable + @Override + public String getPresentableText() { + return myTemplate.getKey(); + } + + @Nullable + @Override + public String getLocationString() { + return null; + } + + @Nullable + @Override + public Icon getIcon(boolean unused) { + return null; + } + }; + } + + @Override + public PsiManager getManager() { + return myPsiManager; + } + } +} diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 2f6a4de3a727..00641e3f22fe 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -374,6 +374,7 @@ +