From 0114e14502afdb4c3175e1bcbcc2952b2e5f446c Mon Sep 17 00:00:00 2001 From: Alexander Bashkirov Date: Tue, 5 Oct 2021 23:43:28 +0300 Subject: [PATCH] [quickdoc] Rewritten AdvancedSettings for quick doc syntax highlighting GitOrigin-RevId: 417fd46685e07552478d4ee74ad88e64ca967d4d --- .../javadoc/AnnotationDocGenerator.java | 16 +- .../javadoc/JavaDocInfoGenerator.java | 151 ++++++++++++------ .../javadoc/JavaDocInfoGeneratorFactory.java | 60 +++---- .../lang/java/JavaDocumentationProvider.java | 25 +-- .../javadocIG/clickableFieldReference.html | 2 +- ...JdkClassWhenExternalDocIsNotAvailable.html | 2 +- .../javadocIG/superJavadocErasureResolve.html | 2 +- .../javadocIG/superJavadocExactResolve.html | 2 +- .../codeInsight/JavaDocumentationTest.groovy | 2 +- .../messages/AnalysisBundle.properties | 4 + .../documentation/DocumentationSettings.java | 78 +++++++++ .../DocumentationManagerUtil.java | 7 +- .../messages/ApplicationBundle.properties | 11 +- .../DocumentationHtmlEditorKit.java | 14 +- .../DocumentationSettingsListener.java | 32 ++++ .../src/META-INF/LangExtensions.xml | 1 + .../src/META-INF/PlatformExtensions.xml | 9 +- .../annotate/GitAdvancedSettingsListener.java | 19 ++- .../documentation/GroovyPresentationUtil.java | 10 +- .../documentation/GroovyDocInfoGenerator.java | 17 +- .../GroovyDocumentationProvider.java | 39 ++--- .../idea/KotlinDocumentationProvider.kt | 21 ++- .../kotlin/idea/kdoc/KDocRenderer.kt | 65 ++++---- .../editor/quickDoc/JavadocNavigationTest.kt | 4 +- 24 files changed, 373 insertions(+), 220 deletions(-) create mode 100644 platform/analysis-api/src/com/intellij/lang/documentation/DocumentationSettings.java create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationSettingsListener.java diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/AnnotationDocGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/AnnotationDocGenerator.java index 2cec5f84e102..c4837f0dee8d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/AnnotationDocGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/AnnotationDocGenerator.java @@ -5,16 +5,14 @@ import com.intellij.codeInsight.AnnotationTargetUtil; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.lang.Language; +import com.intellij.lang.documentation.DocumentationSettings; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil; -import com.intellij.openapi.options.advanced.AdvancedSettings; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.util.MathUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import one.util.streamex.StreamEx; @@ -77,10 +75,6 @@ public final class AnnotationDocGenerator { return AnnotationUtil.isInferredAnnotation(myAnnotation); } - private static float getHighlightingSaturation() { - return MathUtil.clamp(AdvancedSettings.getInt("documentation.components.doc.syntax.highlighting.saturation"), 0, 100) * 0.01f; - } - private static void appendStyledSpan( boolean doSyntaxHighlighting, @NotNull StringBuilder buffer, @@ -88,7 +82,7 @@ public final class AnnotationDocGenerator { @Nullable String value ) { if (doSyntaxHighlighting) { - HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributesKey, value, getHighlightingSaturation()); + HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributesKey, value, DocumentationSettings.getHighlightingSaturation()); } else { buffer.append(value); @@ -104,7 +98,7 @@ public final class AnnotationDocGenerator { ) { if (doSyntaxHighlighting) { HtmlSyntaxInfoUtil.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - buffer, project, language, codeSnippet, getHighlightingSaturation()); + buffer, project, language, codeSnippet, DocumentationSettings.getHighlightingSaturation()); } else if (codeSnippet != null) { buffer.append(StringUtil.escapeXmlEntities(codeSnippet)); @@ -146,7 +140,7 @@ public final class AnnotationDocGenerator { String styledName = styledNameBuilder.toString(); JavaDocInfoGeneratorFactory.getBuilder(myContext.getProject()) .setIsGenerationForRenderedDoc(isForRenderedDoc) - .setDoSyntaxHighlighting(doSyntaxHighlighting) + .setDoHighlightSignatures(doSyntaxHighlighting) .create() .generateLink(buffer, myTargetClass, styledName, format == AnnotationFormat.JavaDocComplete); } @@ -242,7 +236,7 @@ public final class AnnotationDocGenerator { } JavaDocInfoGeneratorFactory.getBuilder(field.getProject()) .setIsGenerationForRenderedDoc(isForRenderedDoc) - .setDoSyntaxHighlighting(doSyntaxHighlighting) + .setDoHighlightSignatures(doSyntaxHighlighting) .create() .generateLink(buffer, text, aClass != null ? aClass.getName() + '.' + field.getName() : null, memberValue, false); } diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index b931b36aed79..c41daca34e47 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -8,11 +8,14 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.documentation.DocumentationManagerProtocol; import com.intellij.codeInsight.documentation.DocumentationManagerUtil; +import com.intellij.diagnostic.Checks; import com.intellij.java.JavaBundle; import com.intellij.javadoc.JavadocGeneratorRunProfile; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.lang.documentation.DocumentationMarkup; +import com.intellij.lang.documentation.DocumentationSettings; +import com.intellij.lang.documentation.DocumentationSettings.InlineCodeHighlightingMode; import com.intellij.lang.java.JavaDocumentationProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; @@ -20,10 +23,8 @@ import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil; -import com.intellij.openapi.options.advanced.AdvancedSettings; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -45,7 +46,10 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.javadoc.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; -import com.intellij.util.*; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ArrayUtilRt; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import kotlin.text.StringsKt; import org.jdom.Element; @@ -115,12 +119,23 @@ public class JavaDocInfoGenerator { private final @Nullable JavaSdkVersion mySdkVersion; private final boolean myIsRendered; - private final boolean myDoSyntaxHighlighting; - private final boolean myDoHighlightInlineCodeBlocks; - private final boolean myDoHighlightLinks; + private final boolean myDoHighlightSignatures; + private final boolean myDoHighlightCodeBlocks; + private final InlineCodeHighlightingMode myInlineCodeBlocksHighlightingMode; + private final boolean myDoSemanticHighlightingOfLinks; + private final float myHighlightingSaturation; public JavaDocInfoGenerator(@NotNull Project project, @Nullable PsiElement element) { - this(project, element, new JavaDocHighlightingManagerImpl(), false, true, true, true); + this( + project, + element, + new JavaDocHighlightingManagerImpl(), + false, + true, + true, + InlineCodeHighlightingMode.AS_DEFAULT_CODE, + false, + 1.0F); } public JavaDocInfoGenerator( @@ -128,17 +143,21 @@ public class JavaDocInfoGenerator { @Nullable PsiElement element, @NotNull JavaDocHighlightingManager highlightingManager, boolean isGenerationForRenderedDoc, - boolean doSyntaxHighlighting, - boolean doHighlightInlineCodeBlocks, - boolean doHighlightLinks + boolean doHighlightSignatures, + boolean doHighlightCodeBlocks, + @NotNull InlineCodeHighlightingMode inlineCodeBlocksHighlightingMode, + boolean doSemanticHighlightingOfLinks, + float highlightingSaturationFactor ) { myProject = project; myElement = element; myIsRendered = isGenerationForRenderedDoc; myHighlightingManager = highlightingManager; - myDoSyntaxHighlighting = doSyntaxHighlighting; - myDoHighlightInlineCodeBlocks = doHighlightInlineCodeBlocks; - myDoHighlightLinks = doHighlightLinks; + myDoHighlightSignatures = doHighlightSignatures; + myDoHighlightCodeBlocks = doHighlightCodeBlocks; + myInlineCodeBlocksHighlightingMode = inlineCodeBlocksHighlightingMode; + myDoSemanticHighlightingOfLinks = doSemanticHighlightingOfLinks; + myHighlightingSaturation = highlightingSaturationFactor; Sdk jdk = JavadocGeneratorRunProfile.getSdk(myProject); mySdkVersion = jdk == null ? null : JavaSdk.getInstance().getVersion(jdk); @@ -148,20 +167,24 @@ public class JavaDocInfoGenerator { return myIsRendered; } - public boolean doSyntaxHighlighting() { - return myDoSyntaxHighlighting; + public boolean doHighlightSignatures() { + return myDoHighlightSignatures; } - public boolean doHighlightInlineCodeBlocks() { - return myDoHighlightInlineCodeBlocks; + public boolean doHighlightCodeBlocks() { + return myDoHighlightCodeBlocks; } - public boolean doHighlightLinks() { - return myDoHighlightLinks; + public @NotNull InlineCodeHighlightingMode getInlineCodeHighlightingMode() { + return myInlineCodeBlocksHighlightingMode; + } + + public boolean doSemanticHighlightingOfLinks() { + return myDoSemanticHighlightingOfLinks; } public float getHighlightingSaturation() { - return MathUtil.clamp(AdvancedSettings.getInt("documentation.components.doc.syntax.highlighting.saturation"), 0, 100) * 0.01f; + return myHighlightingSaturation; } public @NotNull JavaDocHighlightingManager getHighlightingManager() { @@ -169,11 +192,12 @@ public class JavaDocInfoGenerator { } protected @NotNull StringBuilder appendStyledSpan( + boolean doHighlighting, @NotNull StringBuilder buffer, @NotNull TextAttributes attributes, @Nullable String value ) { - if (doSyntaxHighlighting()) { + if (doHighlighting) { HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributes, value, getHighlightingSaturation()); } else { @@ -182,13 +206,22 @@ public class JavaDocInfoGenerator { return buffer; } + protected @NotNull StringBuilder appendStyledSpan( + @NotNull StringBuilder buffer, + @NotNull TextAttributes attributes, + @Nullable String value + ) { + return appendStyledSpan(doHighlightSignatures(), buffer, attributes, value); + } + protected @NotNull StringBuilder appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( + boolean doHighlighting, @NotNull StringBuilder buffer, @NotNull Project project, @NotNull Language language, @Nullable String codeSnippet ) { - if (doSyntaxHighlighting()) { + if (doHighlighting) { HtmlSyntaxInfoUtil.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( buffer, project, language, codeSnippet, getHighlightingSaturation()); } @@ -201,8 +234,8 @@ public class JavaDocInfoGenerator { return buffer; } - public @NotNull String getStyledSpan(@NotNull TextAttributes attributes, @Nullable String value) { - return appendStyledSpan(new StringBuilder(), attributes, value).toString(); + protected @NotNull String getStyledSpan(boolean doHighlighting, @NotNull TextAttributes attributes, @Nullable String value) { + return appendStyledSpan(doHighlighting, new StringBuilder(), attributes, value).toString(); } public @NotNull String getHighlightedByLexerAndEncodedAsHtmlCodeSnippet( @@ -210,7 +243,7 @@ public class JavaDocInfoGenerator { @NotNull Language language, @Nullable String codeSnippet ) { - return appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(new StringBuilder(), project, language, codeSnippet).toString(); + return appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(true, new StringBuilder(), project, language, codeSnippet).toString(); } private static InheritDocProvider mapProvider(InheritDocProvider i, boolean dropFirst) { @@ -589,7 +622,7 @@ public class JavaDocInfoGenerator { } if (!isRendered()) { - new NonCodeAnnotationGenerator(aClass, buffer).explainAnnotations(isRendered(), doSyntaxHighlighting()); + new NonCodeAnnotationGenerator(aClass, buffer).explainAnnotations(isRendered(), doHighlightSignatures()); } buffer.append(DocumentationMarkup.SECTIONS_END); } @@ -792,7 +825,7 @@ public class JavaDocInfoGenerator { if (!isRendered()) { JavaDocColorUtil.appendColorPreview(field, buffer); - new NonCodeAnnotationGenerator(field, buffer).explainAnnotations(isRendered(), doSyntaxHighlighting()); + new NonCodeAnnotationGenerator(field, buffer).explainAnnotations(isRendered(), doHighlightSignatures()); } buffer.append(DocumentationMarkup.SECTIONS_END); @@ -988,7 +1021,8 @@ public class JavaDocInfoGenerator { if (trunc) { text = text.substring(0, index); } - appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(buffer, initializer.getProject(), initializer.getLanguage(), text); + appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( + doHighlightSignatures(), buffer, initializer.getProject(), initializer.getLanguage(), text); if (trunc) { buffer.append("..."); } @@ -1059,7 +1093,7 @@ public class JavaDocInfoGenerator { } for (AnnotationDocGenerator anno : generators) { StringBuilder buf = new StringBuilder(); - anno.generateAnnotation(buf, AnnotationFormat.JavaDocShort, generateLink, isRendered(), doSyntaxHighlighting()); + anno.generateAnnotation(buf, AnnotationFormat.JavaDocShort, generateLink, isRendered(), doHighlightSignatures()); len += StringUtil.unescapeXmlEntities(StringUtil.stripHtml(buf.toString(), true)).length() + 1; buffer.append(buf); buffer.append(NBSP); @@ -1078,7 +1112,7 @@ public class JavaDocInfoGenerator { AnnotationFormat format = place == SignaturePlace.Javadoc ? AnnotationFormat.JavaDocShort : AnnotationFormat.ToolTip; for (AnnotationDocGenerator anno : AnnotationDocGenerator.getAnnotationsToShow(owner)) { if (ignoreNonSourceAnnotations && (anno.isInferred() || anno.isExternal())) continue; - anno.generateAnnotation(buffer, format, generateLink, isRendered(), doSyntaxHighlighting()); + anno.generateAnnotation(buffer, format, generateLink, isRendered(), doHighlightSignatures()); buffer.append(NBSP); if (splitAnnotations) buffer.append('\n'); @@ -1133,7 +1167,7 @@ public class JavaDocInfoGenerator { } buffer.append(DocumentationMarkup.SECTIONS_START); - new NonCodeAnnotationGenerator(parameter, buffer).explainAnnotations(isRendered(), doSyntaxHighlighting()); + new NonCodeAnnotationGenerator(parameter, buffer).explainAnnotations(isRendered(), doHighlightSignatures()); buffer.append(DocumentationMarkup.SECTIONS_END); } @@ -1209,7 +1243,8 @@ public class JavaDocInfoGenerator { startHeaderSection(buffer, JavaBundle.message(aClass.isInterface() ? "javadoc.description.copied.from.interface" : "javadoc.description.copied.from.class")) .append("

"); - generateLink(buffer, aClass, getStyledSpan(getHighlightingManager().getClassDeclarationAttributes(aClass), + generateLink(buffer, aClass, getStyledSpan(doSemanticHighlightingOfLinks(), + getHighlightingManager().getClassDeclarationAttributes(aClass), JavaDocUtil.getShortestClassName(aClass, method)), false); buffer.append(BR_TAG); @@ -1228,7 +1263,8 @@ public class JavaDocInfoGenerator { if (fieldDocComment != null && !isEmptyDescription(fieldDocComment)) { startHeaderSection(buffer, JavaBundle.message("javadoc.description.copied.from.field")) .append("

"); - generateLink(buffer, field, getStyledSpan(getHighlightingManager().getFieldDeclarationAttributes(field), field.getName()), + generateLink(buffer, field, getStyledSpan(doSemanticHighlightingOfLinks(), + getHighlightingManager().getFieldDeclarationAttributes(field), field.getName()), false); buffer.append(BR_TAG); generateValue(buffer, fieldDocComment.getDescriptionElements(), ourEmptyElementsProvider); @@ -1263,7 +1299,7 @@ public class JavaDocInfoGenerator { } if (!isRendered()) { - new NonCodeAnnotationGenerator(method, buffer).explainAnnotations(isRendered(), doSyntaxHighlighting()); + new NonCodeAnnotationGenerator(method, buffer).explainAnnotations(isRendered(), doHighlightSignatures()); } buffer.append(DocumentationMarkup.SECTIONS_END); @@ -1513,29 +1549,37 @@ public class JavaDocInfoGenerator { buffer.setLength(lastNonWhite + 1); } - buffer.append(isRendered() ? "" : ""); + buffer.append(isRendered() ? "" : ""); int pos = buffer.length(); StringBuilder codeSnippetBuilder = new StringBuilder(); generateLiteralValue(codeSnippetBuilder, tag, false); String codeSnippet = codeSnippetBuilder.toString(); + if (isCodeBlock) { + codeSnippet = StringsKt.trimIndent(codeSnippet); + } - if (isCodeBlock || doHighlightInlineCodeBlocks()) { + if (isCodeBlock && doHighlightCodeBlocks() + || !isCodeBlock && getInlineCodeHighlightingMode() == InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING) { + // highlights code by lexer codeSnippetBuilder.setLength(0); - appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - codeSnippetBuilder, tag.getProject(), tag.getLanguage(), codeSnippet); + appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(true, codeSnippetBuilder, tag.getProject(), tag.getLanguage(), codeSnippet); codeSnippet = codeSnippetBuilder.toString(); + } + if (isCodeBlock && doHighlightCodeBlocks() + || !isCodeBlock && getInlineCodeHighlightingMode() != InlineCodeHighlightingMode.NO_HIGHLIGHTING) { + // highlights plain code as HighlighterColors.TEXT codeSnippetBuilder.setLength(0); TextAttributes codeAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(HighlighterColors.TEXT).clone(); codeAttributes.setBackgroundColor(null); - appendStyledSpan(codeSnippetBuilder, codeAttributes, codeSnippet); + appendStyledSpan(true, codeSnippetBuilder, codeAttributes, codeSnippet); codeSnippet = codeSnippetBuilder.toString(); } if (isCodeBlock) { // indent code block - codeSnippet = Arrays.stream(codeSnippet.split(BR_TAG)) + codeSnippet = Arrays.stream(codeSnippet.contains(BR_TAG) ? codeSnippet.split(BR_TAG) : codeSnippet.split("\n")) .map(it -> " " + it) .collect(Collectors.joining(BR_TAG)); } @@ -2002,10 +2046,12 @@ public class JavaDocInfoGenerator { StringBuilder methodBuffer = new StringBuilder(); generateLink( methodBuffer, superMethod, - getStyledSpan(getHighlightingManager().getMethodDeclarationAttributes(superMethod), superMethod.getName()), false); + getStyledSpan(doSemanticHighlightingOfLinks(), + getHighlightingManager().getMethodDeclarationAttributes(superMethod), superMethod.getName()), false); StringBuilder classBuffer = new StringBuilder(); generateLink(classBuffer, superClass, - getStyledSpan(getHighlightingManager().getClassDeclarationAttributes(superClass), superClass.getName()), false); + getStyledSpan(doSemanticHighlightingOfLinks(), + getHighlightingManager().getClassDeclarationAttributes(superClass), superClass.getName()), false); if (superClass.isInterface()) { buffer.append(JavaBundle.message("javadoc.method.in.interface", methodBuffer.toString(), classBuffer.toString())); } @@ -2066,7 +2112,7 @@ public class JavaDocInfoGenerator { buffer.append("").append(label).append(""); } else { - generateLink(buffer, target, doHighlightLinks() ? tryHighlightLinkLabel(target, label) : label, plainLink); + generateLink(buffer, target, doSemanticHighlightingOfLinks() ? tryHighlightLinkLabel(target, label) : label, plainLink); } } @@ -2089,11 +2135,12 @@ public class JavaDocInfoGenerator { } private @NotNull String tryHighlightLinkLabel(@NotNull PsiElement element, @NotNull String label) { + Checks.require(doSemanticHighlightingOfLinks()); if (element instanceof PsiClass) { - return getStyledSpan(tuneAttributesForLink(getHighlightingManager().getClassDeclarationAttributes((PsiClass)element)), label); + return getStyledSpan(true, tuneAttributesForLink(getHighlightingManager().getClassDeclarationAttributes((PsiClass)element)), label); } if (element instanceof PsiPackage) { - return getStyledSpan(tuneAttributesForLink(getHighlightingManager().getClassNameAttributes()), label); + return getStyledSpan(true, tuneAttributesForLink(getHighlightingManager().getClassNameAttributes()), label); } else if (element instanceof PsiMethod) { return tryHighlightLinkOnClassMember( @@ -2113,6 +2160,7 @@ public class JavaDocInfoGenerator { @NotNull TextAttributes labelAttributes, @NotNull String label ) { + Checks.require(doSemanticHighlightingOfLinks()); StringBuilder buffer = new StringBuilder(); int openParenIndex = label.indexOf("("); if (openParenIndex == -1) openParenIndex = label.length(); @@ -2122,14 +2170,15 @@ public class JavaDocInfoGenerator { TextAttributes containingClassAttributes = containingClass != null ? getHighlightingManager().getClassDeclarationAttributes(containingClass) : getHighlightingManager().getClassNameAttributes(); - appendStyledSpan(buffer, containingClassAttributes, label.substring(0, classNameIndex)); - appendStyledSpan(buffer, getHighlightingManager().getDotAttributes(), "."); + containingClassAttributes = tuneAttributesForLink(containingClassAttributes); + appendStyledSpan(true, buffer, containingClassAttributes, label.substring(0, classNameIndex)); + appendStyledSpan(true, buffer, getHighlightingManager().getDotAttributes(), "."); } classNameIndex++; - appendStyledSpan(buffer, labelAttributes, label.substring(classNameIndex, openParenIndex)); + appendStyledSpan(true, buffer, labelAttributes, label.substring(classNameIndex, openParenIndex)); if (openParenIndex == label.length()) return buffer.toString(); appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - buffer, member.getProject(), member.getLanguage(), label.substring(openParenIndex)); + true, buffer, member.getProject(), member.getLanguage(), label.substring(openParenIndex)); return buffer.toString(); } @@ -2570,13 +2619,13 @@ public class JavaDocInfoGenerator { @Override public void visitExpression(PsiExpression expression) { appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - myBuffer, expression.getProject(), expression.getLanguage(), expression.getText()); + doHighlightSignatures(), myBuffer, expression.getProject(), expression.getLanguage(), expression.getText()); } @Override public void visitReferenceExpression(PsiReferenceExpression expression) { appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - myBuffer, expression.getProject(), expression.getLanguage(), expression.getText()); + doHighlightSignatures(), myBuffer, expression.getProject(), expression.getLanguage(), expression.getText()); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorFactory.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorFactory.java index 4acbb2ccbe9e..2e8e50286e1d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorFactory.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorFactory.java @@ -1,9 +1,9 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.javadoc; +import com.intellij.lang.documentation.DocumentationSettings; +import com.intellij.lang.documentation.DocumentationSettings.InlineCodeHighlightingMode; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; -import com.intellij.openapi.options.advanced.AdvancedSettings; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -17,17 +17,16 @@ public class JavaDocInfoGeneratorFactory { } protected JavaDocInfoGenerator createImpl(@NotNull Project project, @Nullable PsiElement element) { - EditorSettingsExternalizable.getInstance(); - EditorSettingsExternalizable.getInstance(); - EditorSettingsExternalizable.getInstance(); return new JavaDocInfoGenerator( project, element, JavaDocHighlightingManagerImpl.getInstance(), false, - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting"), - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting.of.inline.code.blocks"), - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting.of.links")); + DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), + DocumentationSettings.isHighlightingOfCodeBlocksEnabled(), + DocumentationSettings.getInlineCodeHighlightingMode(), + DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), + DocumentationSettings.getHighlightingSaturation()); } @NotNull @@ -45,12 +44,11 @@ public class JavaDocInfoGeneratorFactory { private @Nullable PsiElement myElement; private @NotNull JavaDocHighlightingManager myManager = new JavaDocHighlightingManagerImpl(); private boolean myIsRendered = false; - private boolean myDoHighlighting = - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting"); - private boolean myDoHighlightBlocks = - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting.of.inline.code.blocks"); - private boolean myDoHighlightLinks = - AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting.of.inline.code.blocks"); + private boolean myDoHighlightSignatures = DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(); + private boolean myDoHighlightCodeBlocks = DocumentationSettings.isHighlightingOfCodeBlocksEnabled(); + private @NotNull InlineCodeHighlightingMode myInlineCodeBlocksHighlightingMode = DocumentationSettings.getInlineCodeHighlightingMode(); + private boolean myDoSemanticHighlightingOfLinks = DocumentationSettings.isSemanticHighlightingOfLinksEnabled(); + private float myHighlightingSaturation = DocumentationSettings.getHighlightingSaturation(); private JavaDocInfoGeneratorBuilder(@NotNull Project project) { myProject = project; @@ -71,34 +69,42 @@ public class JavaDocInfoGeneratorFactory { return this; } - public JavaDocInfoGeneratorBuilder setDoSyntaxHighlighting(boolean doHighlighting) { - myDoHighlighting = doHighlighting; + public JavaDocInfoGeneratorBuilder setDoHighlightSignatures(boolean doHighlighting) { + myDoHighlightSignatures = doHighlighting; return this; } - public JavaDocInfoGeneratorBuilder setDoHighlightInlineCodeBlocks(boolean doHighlightBlocks) { - myDoHighlightBlocks = doHighlightBlocks; + public JavaDocInfoGeneratorBuilder setDoHighlightCodeBlocks(boolean doHighlighting) { + myDoHighlightCodeBlocks = doHighlighting; return this; } - public JavaDocInfoGeneratorBuilder setDoHighlightLinks(boolean doHighlightLinks) { - myDoHighlightLinks = doHighlightLinks; + public JavaDocInfoGeneratorBuilder setDoInlineCodeHighlightingMode(@NotNull InlineCodeHighlightingMode mode) { + myInlineCodeBlocksHighlightingMode = mode; + return this; + } + + public JavaDocInfoGeneratorBuilder setDoSemanticHighlightingOfLinks(boolean doHighlightLinks) { + myDoSemanticHighlightingOfLinks = doHighlightLinks; + return this; + } + + public JavaDocInfoGeneratorBuilder setHighlightingSaturationFactor(float saturationFactor) { + myHighlightingSaturation = saturationFactor; return this; } public JavaDocInfoGenerator create() { - if (!myDoHighlighting) { - myDoHighlightBlocks = false; - myDoHighlightLinks = false; - } return new JavaDocInfoGenerator( myProject, myElement, myManager, myIsRendered, - myDoHighlighting, - myDoHighlightBlocks, - myDoHighlightLinks); + myDoHighlightSignatures, + myDoHighlightCodeBlocks, + myInlineCodeBlocksHighlightingMode, + myDoSemanticHighlightingOfLinks, + myHighlightingSaturation); } } } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index c99ad761eaea..fd15955496c1 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -17,14 +17,13 @@ import com.intellij.lang.CodeDocumentationAwareCommenter; import com.intellij.lang.LanguageCommenters; import com.intellij.lang.documentation.CodeDocumentationProvider; import com.intellij.lang.documentation.CompositeDocumentationProvider; +import com.intellij.lang.documentation.DocumentationSettings; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil; import com.intellij.openapi.module.Module; -import com.intellij.openapi.options.advanced.AdvancedSettings; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -47,7 +46,6 @@ import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.util.*; -import com.intellij.util.MathUtil; import com.intellij.util.SmartList; import com.intellij.util.Url; import com.intellij.util.containers.ContainerUtil; @@ -82,8 +80,8 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext @NotNull TextAttributes attributes, @Nullable String value ) { - if (doSyntaxHighlighting()) { - HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributes, value, getHighlightingSaturation()); + if (DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled()) { + HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributes, value, DocumentationSettings.getHighlightingSaturation()); } else { buffer.append(value); @@ -96,7 +94,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext @Nullable String value, String @NotNull ... properties ) { - if (doSyntaxHighlighting()) { + if (DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled()) { HtmlSyntaxInfoUtil.appendStyledSpan(buffer, value, properties); } else { @@ -104,14 +102,6 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext } } - protected static boolean doSyntaxHighlighting() { - return AdvancedSettings.getBoolean("documentation.components.enable.doc.syntax.highlighting"); - } - - protected static float getHighlightingSaturation() { - return MathUtil.clamp(AdvancedSettings.getInt("documentation.components.doc.syntax.highlighting.saturation"), 0, 100) * 0.01f; - } - @Override public @Nls String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) { return QuickDocUtil.inferLinkFromFullDocumentation(this, element, originalElement, @@ -228,10 +218,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext } private static JavaDocInfoGenerator getDocInfoGenerator(@NotNull Project project, boolean isGenerationForRenderedDoc) { - return JavaDocInfoGeneratorFactory.getBuilder(project) - .setIsGenerationForRenderedDoc(isGenerationForRenderedDoc) - .setDoSyntaxHighlighting(doSyntaxHighlighting()) - .create(); + return JavaDocInfoGeneratorFactory.getBuilder(project).setIsGenerationForRenderedDoc(isGenerationForRenderedDoc).create(); } public static @Nls String generateClassInfo(PsiClass aClass) { @@ -313,7 +300,6 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext JavaDocInfoGeneratorFactory.getBuilder(aClass.getProject()) .setIsGenerationForRenderedDoc(false) .setHighlightingManager(highlightingManager) - .setDoSyntaxHighlighting(doSyntaxHighlighting()) .create() .generateType(buffer, refs[i], aClass, false, true); @@ -697,7 +683,6 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext JavaDocInfoGenerator generator = JavaDocInfoGeneratorFactory.getBuilder(target.getProject()) .setPsiElement(target) .setIsGenerationForRenderedDoc(true) - .setDoSyntaxHighlighting(doSyntaxHighlighting()) .create(); return JavaDocExternalFilter.filterInternalDocInfo(generator.generateRenderedDocInfo()); } diff --git a/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html index 9b9b4a60d4b7..1a14350ad2ae 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html +++ b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html @@ -1,2 +1,2 @@ -

@Bar(Baz.CONST, value = {Baz.CONST}) 
+
@Bar(Baz.CONST, value = {Baz.CONST}) 
 class Foo
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html b/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html index 7fc8468d1d9a..2ae7f017d7c1 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html +++ b/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html @@ -57,4 +57,4 @@ Unicode code points (i.e., characters), in addition to those for dealing with Unicode code units (i.e., char values). -

Since:

JDK1.0

See Also:

Object.toString(),
StringBuffer,
StringBuilder,
java.nio.charset.Charset

\ No newline at end of file +

Since:

JDK1.0

See Also:

Object.toString(),
StringBuffer,
StringBuilder,
java.nio.charset.Charset

\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/superJavadocErasureResolve.html b/java/java-tests/testData/codeInsight/javadocIG/superJavadocErasureResolve.html index bb5666ea0bb3..baf7476ef0fb 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/superJavadocErasureResolve.html +++ b/java/java-tests/testData/codeInsight/javadocIG/superJavadocErasureResolve.html @@ -1 +1 @@ -
E remove(
Integer idx
)

See Also:

TestImpl.remove(Number)

\ No newline at end of file +
E remove(
Integer idx
)

See Also:

TestImpl.remove(Number)

\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/superJavadocExactResolve.html b/java/java-tests/testData/codeInsight/javadocIG/superJavadocExactResolve.html index b2e4023da381..5dff26e02736 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/superJavadocExactResolve.html +++ b/java/java-tests/testData/codeInsight/javadocIG/superJavadocExactResolve.html @@ -1 +1 @@ -
E remove(
int idx
)

See Also:

TestImpl.remove(int)

\ No newline at end of file +
E remove(
int idx
)

See Also:

TestImpl.remove(int)

\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaDocumentationTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaDocumentationTest.groovy index d30eb1a5b18f..466574952c45 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaDocumentationTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaDocumentationTest.groovy @@ -157,7 +157,7 @@ class JavaDocumentationTest extends LightJavaCodeInsightFixtureTestCase { def doc = new JavaDocumentationProvider().generateDoc(method, null) def expected = - "
public void m()
" + "
public void m()
" assert doc == expected } diff --git a/platform/analysis-api/resources/messages/AnalysisBundle.properties b/platform/analysis-api/resources/messages/AnalysisBundle.properties index 984ed38f6565..5b6587cdbf84 100644 --- a/platform/analysis-api/resources/messages/AnalysisBundle.properties +++ b/platform/analysis-api/resources/messages/AnalysisBundle.properties @@ -212,3 +212,7 @@ file.write.error=Cannot write to file {0}. file.delete.root.error=Cannot delete root file {0}. jar.modification.not.supported.error=Cannot modify archive file {0} + +documentation.settings.inline.code.highlighting.mode.no.highlighting=No highlighting +documentation.settings.inline.code.highlighting.mode.as.default.code=As plain code +documentation.settings.inline.code.highlighting.mode.semantic.highlighting=With keywords highlighted \ No newline at end of file diff --git a/platform/analysis-api/src/com/intellij/lang/documentation/DocumentationSettings.java b/platform/analysis-api/src/com/intellij/lang/documentation/DocumentationSettings.java new file mode 100644 index 000000000000..f36b152fbbe9 --- /dev/null +++ b/platform/analysis-api/src/com/intellij/lang/documentation/DocumentationSettings.java @@ -0,0 +1,78 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.lang.documentation; + +import com.intellij.analysis.AnalysisBundle; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.advanced.AdvancedSettings; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.MathUtil; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + + +@ApiStatus.Experimental +public class DocumentationSettings { + + private DocumentationSettings() { + } + + public static boolean isHighlightingOfQuickDocSignaturesEnabled() { + return ApplicationManager.getApplication().isUnitTestMode() + || AdvancedSettings.getBoolean("documentation.components.enable.doc.highlighting.of.quick.doc.signatures"); + } + + public static boolean isHighlightingOfCodeBlocksEnabled() { + return ApplicationManager.getApplication().isUnitTestMode() + || AdvancedSettings.getBoolean("documentation.components.enable.doc.highlighting.of.code.blocks"); + } + + public static boolean isSemanticHighlightingOfLinksEnabled() { + return ApplicationManager.getApplication().isUnitTestMode() + || AdvancedSettings.getBoolean("documentation.components.enable.doc.semantic.highlighting.of.links"); + } + + public static @NotNull InlineCodeHighlightingMode getInlineCodeHighlightingMode() { + return ApplicationManager.getApplication().isUnitTestMode() + ? InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING + : AdvancedSettings.getEnum("documentation.components.doc.inline.code.highlighting.mode", InlineCodeHighlightingMode.class); + } + + public static float getHighlightingSaturation() { + return ApplicationManager.getApplication().isUnitTestMode() + ? 1.0f + : MathUtil.clamp(AdvancedSettings.getInt("documentation.components.doc.highlighting.saturation"), 0, 100) * 0.01F; + } + + /** + * Swing HTML Editor Kit processes values in percents of 'font-size' css property really weirdly + * and even in not a cross-platform way. + * So we have to do some hacks to align fonts. + */ + public static int getMonospaceFontSizeCorrection() { + return SystemInfo.isWin10OrNewer && !ApplicationManager.getApplication().isUnitTestMode() ? 90 : 96; + } + + + public enum InlineCodeHighlightingMode { + NO_HIGHLIGHTING { + @Override + public String toString() { + return AnalysisBundle.message("documentation.settings.inline.code.highlighting.mode.no.highlighting"); + } + }, + + AS_DEFAULT_CODE { + @Override + public String toString() { + return AnalysisBundle.message("documentation.settings.inline.code.highlighting.mode.as.default.code"); + } + }, + + SEMANTIC_HIGHLIGHTING { + @Override + public String toString() { + return AnalysisBundle.message("documentation.settings.inline.code.highlighting.mode.semantic.highlighting"); + } + } + } +} diff --git a/platform/core-api/src/com/intellij/codeInsight/documentation/DocumentationManagerUtil.java b/platform/core-api/src/com/intellij/codeInsight/documentation/DocumentationManagerUtil.java index 1eb2ad7294d4..9eef1be58cc9 100644 --- a/platform/core-api/src/com/intellij/codeInsight/documentation/DocumentationManagerUtil.java +++ b/platform/core-api/src/com/intellij/codeInsight/documentation/DocumentationManagerUtil.java @@ -2,6 +2,7 @@ package com.intellij.codeInsight.documentation; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.SystemInfo; import com.intellij.psi.PsiElement; public class DocumentationManagerUtil { @@ -23,7 +24,7 @@ public class DocumentationManagerUtil { buffer.append(refText); buffer.append("\">"); if (!plainLink) { - buffer.append(isRendered ? "" : ""); + buffer.append(isRendered ? "" : ""); } buffer.append(label); if (!plainLink) { @@ -32,6 +33,10 @@ public class DocumentationManagerUtil { buffer.append(""); } + private static int getMonospaceFontSizeCorrection() { + return SystemInfo.isWin10OrNewer && !ApplicationManager.getApplication().isUnitTestMode() ? 90 : 96; + } + public static void createHyperlink(StringBuilder buffer, String refText, String label, boolean plainLink) { getInstance().createHyperlinkImpl(buffer, null, refText, label, plainLink, false); } diff --git a/platform/ide-core/resources/messages/ApplicationBundle.properties b/platform/ide-core/resources/messages/ApplicationBundle.properties index bd4f6bfe6fa9..a8a1111bdcee 100644 --- a/platform/ide-core/resources/messages/ApplicationBundle.properties +++ b/platform/ide-core/resources/messages/ApplicationBundle.properties @@ -828,11 +828,12 @@ advanced.setting.editor.open.tabs.in.main.window=Open declaration source called advanced.setting.editor.open.tabs.in.main.window.description=When navigating to a method/class/variable declaration from a tab in the detached window, new tabs will be opened in the main IDE window. Overrides 'Open declaration source in the same tab'. advanced.setting.ide.macos.disable.native.shortcut.symbols=Use words instead of symbols for macOS keyboard shortcuts advanced.setting.ide.macos.disable.native.shortcut.symbols.description=Change shortcut symbols \u238B, \u232B, \u2325, and others to Esc, Backspace, Option, etc -advanced.setting.documentation.components.enable.doc.syntax.highlighting=Enable code highlighting in documentation components -advanced.setting.documentation.components.enable.doc.syntax.highlighting.of.inline.code.blocks=Highlight inline code blocks -advanced.setting.documentation.components.enable.doc.syntax.highlighting.of.links=Highlight links on code elements -advanced.setting.documentation.components.doc.syntax.highlighting.saturation=Highlighting saturation -advanced.setting.documentation.components.doc.syntax.highlighting.saturation.description=Allows reducing saturation of highlighting colors in order to lower distraction from the main code. Here 100 is the normal saturation (bright tones) and 0 is zero saturation (grey tones) +advanced.setting.documentation.components.enable.doc.highlighting.of.quick.doc.signatures=Highlight code elements' signatures +advanced.setting.documentation.components.enable.doc.highlighting.of.code.blocks=Highlight multiline code blocks +advanced.setting.documentation.components.enable.doc.semantic.highlighting.of.links=Enable semantic highlighting of links on code elements +advanced.setting.documentation.components.doc.inline.code.highlighting.mode=Inline code highlighting mode +advanced.setting.documentation.components.doc.highlighting.saturation=Highlighting saturation +advanced.setting.documentation.components.doc.highlighting.saturation.description=Allows reducing saturation of highlighting colors in order to lower distraction from the main code. Here 100 is the normal saturation (bright tones) and 0 is zero saturation (grey tones) group.advanced.settings.other=Other group.advanced.settings.ide=IDE group.advanced.settings.ui=User Interface diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationHtmlEditorKit.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationHtmlEditorKit.java index e6316729c2b7..0fdc3fd15d98 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationHtmlEditorKit.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationHtmlEditorKit.java @@ -1,7 +1,9 @@ // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.documentation; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.impl.EditorCssFontResolver; +import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.ColorUtil; import com.intellij.util.ui.JBHtmlEditorKit; import com.intellij.util.ui.JBUI; @@ -30,6 +32,15 @@ public final class DocumentationHtmlEditorKit extends JBHtmlEditorKit { return myHtmlFactory; } + /** + * Swing HTML Editor Kit processes values in percents of 'font-size' css property really weirdly + * and even in not a cross-platform way. + * So we have to do some hacks to align fonts. + */ + private static int getMonospaceFontSizeCorrection() { + return SystemInfo.isWin10OrNewer && !ApplicationManager.getApplication().isUnitTestMode() ? 96 : 100; + } + private static void prepareCSS(@NotNull JBHtmlEditorKit editorKit) { editorKit.setFontResolver(EditorCssFontResolver.getGlobalInstance()); @@ -38,7 +49,8 @@ public final class DocumentationHtmlEditorKit extends JBHtmlEditorKit { String linkColor = ColorUtil.toHtmlColor(JBUI.CurrentTheme.Link.Foreground.ENABLED); String borderColor = ColorUtil.toHtmlColor(UIUtil.getTooltipSeparatorColor()); String sectionColor = ColorUtil.toHtmlColor(SECTION_COLOR); - String editorFontStyle = "{font-family:\"" + EditorCssFontResolver.EDITOR_FONT_NAME_NO_LIGATURES_PLACEHOLDER + "\";}"; + String editorFontStyle = "{font-family:\"" + EditorCssFontResolver.EDITOR_FONT_NAME_NO_LIGATURES_PLACEHOLDER + + "\";font-size:" + getMonospaceFontSizeCorrection() + "%;}"; StyleSheet styleSheet = editorKit.getStyleSheet(); styleSheet.addRule("tt" + editorFontStyle); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationSettingsListener.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationSettingsListener.java new file mode 100644 index 000000000000..989711faaa67 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationSettingsListener.java @@ -0,0 +1,32 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInsight.documentation; + +import com.intellij.codeInsight.documentation.render.DocRenderManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.advanced.AdvancedSettingsChangeListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupActivity; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + + +@ApiStatus.Experimental +public final class DocumentationSettingsListener implements StartupActivity { + + @Override + public void runActivity(@NotNull Project project) { + ApplicationManager.getApplication().getMessageBus() + .connect() + .subscribe(AdvancedSettingsChangeListener.TOPIC, new AdvancedSettingsChangeListener() { + @Override + public void advancedSettingChanged(@NotNull String id, @NotNull Object oldValue, @NotNull Object newValue) { + if (StringUtil.startsWith(id, "documentation.components")) { + DocRenderManager.resetAllEditorsToDefaultState(); + } + } + }); + } +} + + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 8f306d02c15f..aa23308c9ca7 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -1452,6 +1452,7 @@ + diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 5618acf5dd09..378a13a26a48 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1306,10 +1306,11 @@ - - - - + + + + + 0) appendStyledSpan(buffer, GroovyDocHighlightingManager.getInstance().getCommaAttributes(), ", "); if (parameter instanceof GrParameter) { - GroovyPresentationUtil.appendParameterPresentation((GrParameter)parameter, substitutor, TypePresentation.LINK, buffer, doSyntaxHighlighting()); + GroovyPresentationUtil.appendParameterPresentation( + (GrParameter)parameter, substitutor, TypePresentation.LINK, buffer, + DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled()); } else { PsiType type = parameter.getType(); @@ -314,7 +298,6 @@ public class GroovyDocumentationProvider implements CodeDocumentationProvider, E JavaDocInfoGeneratorFactory.getBuilder(context.getProject()) .setHighlightingManager(GroovyDocHighlightingManager.getInstance()) .setIsGenerationForRenderedDoc(isRendered) - .setDoSyntaxHighlighting(doSyntaxHighlighting()) .create() .generateType(buffer, type, context); } @@ -427,9 +410,11 @@ public class GroovyDocumentationProvider implements CodeDocumentationProvider, E return new GroovyDocInfoGenerator( element, isGenerationForRenderedDoc, - doSyntaxHighlighting(), - doHighlightingOfInlineCodeBlocksEnabled(), - doHighlightingOfLinksEnabled()); + DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), + DocumentationSettings.isHighlightingOfCodeBlocksEnabled(), + DocumentationSettings.getInlineCodeHighlightingMode(), + DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), + DocumentationSettings.getHighlightingSaturation()); } protected static @Nls @Nullable String generateExternalJavaDoc(@NotNull PsiElement element) { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt index 7b9d151aa6ae..d1c153b34d29 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt @@ -8,23 +8,20 @@ import com.intellij.codeInsight.javadoc.JavaDocExternalFilter import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory import com.intellij.lang.documentation.AbstractDocumentationProvider import com.intellij.lang.documentation.DocumentationMarkup.* +import com.intellij.lang.documentation.DocumentationSettings import com.intellij.lang.java.JavaDocumentationProvider import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.DefaultLanguageHighlighterColors import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.colors.EditorColorsManager import com.intellij.openapi.editor.colors.TextAttributesKey -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.editor.markup.TextAttributes import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil -import com.intellij.openapi.options.advanced.AdvancedSettings.Companion.getBoolean -import com.intellij.openapi.options.advanced.AdvancedSettings.Companion.getInt import com.intellij.openapi.project.Project import com.intellij.openapi.util.NlsSafe import com.intellij.psi.* import com.intellij.psi.impl.compiled.ClsMethodImpl import com.intellij.psi.util.PsiTreeUtil -import com.intellij.util.MathUtil import org.jetbrains.annotations.Nls import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration @@ -231,12 +228,17 @@ class KotlinDocumentationProvider : AbstractDocumentationProvider() { KotlinIdeDescriptorRendererHighlightingManager.Companion.Attributes private fun createHighlightingManager(project: Project?): KotlinIdeDescriptorRendererHighlightingManager { - if (!doSyntaxHighlighting) { + if (!DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled()) { return KotlinIdeDescriptorRendererHighlightingManager.NO_HIGHLIGHTING } return object : KotlinIdeDescriptorRendererHighlightingManager { override fun StringBuilder.appendHighlighted(value: String, attributes: TextAttributesAdapter) { - HtmlSyntaxInfoUtil.appendStyledSpan(this, attributes.attributes, value, highlightingSaturation) + HtmlSyntaxInfoUtil.appendStyledSpan( + this, + attributes.attributes, + value, + DocumentationSettings.getHighlightingSaturation() + ) } override fun StringBuilder.appendCodeSnippetHighlightedByLexer(codeSnippet: String) { @@ -245,7 +247,7 @@ class KotlinDocumentationProvider : AbstractDocumentationProvider() { project!!, KotlinLanguage.INSTANCE, codeSnippet, - highlightingSaturation + DocumentationSettings.getHighlightingSaturation() ) } @@ -285,11 +287,6 @@ class KotlinDocumentationProvider : AbstractDocumentationProvider() { .eraseTypeParameter() } - private val doSyntaxHighlighting: Boolean get() = getBoolean("documentation.components.enable.doc.syntax.highlighting") - - private val highlightingSaturation: Float - get() = MathUtil.clamp(getInt("documentation.components.doc.syntax.highlighting.saturation"), 0, 100) * 0.01f - private fun StringBuilder.appendHighlighted( value: String, attributesBuilder: KotlinIdeDescriptorRendererHighlightingManager.() diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt index 33fa0de8f4c3..20977091cd39 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt @@ -5,22 +5,19 @@ package org.jetbrains.kotlin.idea.kdoc import com.intellij.codeInsight.documentation.DocumentationManagerUtil import com.intellij.lang.Language import com.intellij.lang.documentation.DocumentationMarkup.* +import com.intellij.lang.documentation.DocumentationSettings +import com.intellij.lang.documentation.DocumentationSettings.InlineCodeHighlightingMode import com.intellij.openapi.editor.DefaultLanguageHighlighterColors import com.intellij.openapi.editor.HighlighterColors import com.intellij.openapi.editor.colors.CodeInsightColors import com.intellij.openapi.editor.colors.EditorColorsManager import com.intellij.openapi.editor.colors.TextAttributesKey -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.editor.markup.TextAttributes import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil -import com.intellij.openapi.options.advanced.AdvancedSettings -import com.intellij.openapi.options.advanced.AdvancedSettings.Companion.getBoolean -import com.intellij.openapi.options.advanced.AdvancedSettings.Companion.getInt import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement -import com.intellij.util.MathUtil import org.intellij.markdown.IElementType import org.intellij.markdown.MarkdownElementTypes import org.intellij.markdown.MarkdownTokenTypes @@ -47,17 +44,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType object KDocRenderer { - private val doSyntaxHighlighting: Boolean get() = getBoolean("documentation.components.enable.doc.syntax.highlighting") - - private val doHighlightInlineCodeBlocks: Boolean - get() = getBoolean("documentation.components.enable.doc.syntax.highlighting.of.inline.code.blocks") - - private val doHighlightLinks: Boolean - get() = getBoolean("documentation.components.enable.doc.syntax.highlighting.of.links") - - private val highlightingSaturation: Float get() = - MathUtil.clamp(getInt("documentation.components.doc.syntax.highlighting.saturation"), 0, 100) * 0.01f - fun StringBuilder.appendKDocContent(docComment: KDocTag): StringBuilder = append(markdownToHtml(docComment, allowSingleParagraph = true)) @@ -128,10 +114,10 @@ object KDocRenderer { pathSegment.first().isLowerCase() -> DefaultLanguageHighlighterColors.IDENTIFIER else -> KotlinHighlightingColors.CLASS } - appendStyledSpan(doHighlightLinks, segmentAttributes, pathSegment) - appendStyledSpan(doHighlightLinks, KotlinHighlightingColors.DOT, ".") + appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), segmentAttributes, pathSegment) + appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), KotlinHighlightingColors.DOT, ".") } - appendStyledSpan(doHighlightLinks, lastSegmentAttributes, elementName) + appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), lastSegmentAttributes, elementName) } } @@ -181,7 +167,13 @@ object KDocRenderer { else -> trimCommonIndent(target.extractExampleText()).htmlEscape() } this@appendSamplesList.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - doSyntaxHighlighting, subjectLink.project, KotlinLanguage.INSTANCE, codeSnippet + when (DocumentationSettings.isHighlightingOfCodeBlocksEnabled()) { + true -> InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING + false -> InlineCodeHighlightingMode.NO_HIGHLIGHTING + }, + subjectLink.project, + KotlinLanguage.INSTANCE, + codeSnippet ) } } @@ -249,7 +241,7 @@ object KDocRenderer { if (subjectName != null) { append("

") when (val link = it.getChildrenOfType().firstOrNull()) { - null -> appendStyledSpan(doHighlightLinks, titleAttributes, subjectName) + null -> appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), titleAttributes, subjectName) else -> appendHyperlink(link) } append("") @@ -342,9 +334,9 @@ object KDocRenderer { val startDelimiter = node.child(MarkdownTokenTypes.BACKTICK)?.text if (startDelimiter != null) { val text = node.text.substring(startDelimiter.length).removeSuffix(startDelimiter) - sb.append("") + sb.append("") sb.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - doHighlightInlineCodeBlocks, + DocumentationSettings.getInlineCodeHighlightingMode(), comment.project, KotlinLanguage.INSTANCE, text @@ -414,7 +406,10 @@ object KDocRenderer { MarkdownTokenTypes.CODE_LINE, MarkdownTokenTypes.CODE_FENCE_CONTENT -> { sb.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - doSyntaxHighlighting, + when (DocumentationSettings.isHighlightingOfCodeBlocksEnabled()) { + true -> InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING + false -> InlineCodeHighlightingMode.NO_HIGHLIGHTING + }, comment.project, guessLanguage(currentCodeFenceLang) ?: KotlinLanguage.INSTANCE, nodeText @@ -522,7 +517,7 @@ object KDocRenderer { private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributesKey: TextAttributesKey, value: String?): StringBuilder { if (doHighlighting) { - HtmlSyntaxInfoUtil.appendStyledSpan(this, attributesKey, value, highlightingSaturation) + HtmlSyntaxInfoUtil.appendStyledSpan(this, attributesKey, value, DocumentationSettings.getHighlightingSaturation()) } else { append(value) } @@ -531,7 +526,7 @@ object KDocRenderer { private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributes: TextAttributes, value: String?): StringBuilder { if (doHighlighting) { - HtmlSyntaxInfoUtil.appendStyledSpan(this, attributes, value, highlightingSaturation) + HtmlSyntaxInfoUtil.appendStyledSpan(this, attributes, value, DocumentationSettings.getHighlightingSaturation()) } else { append(value) } @@ -539,23 +534,27 @@ object KDocRenderer { } private fun StringBuilder.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - doHighlighting: Boolean, + highlightingMode: InlineCodeHighlightingMode, project: Project, language: Language, codeSnippet: String ): StringBuilder { val codeSnippetBuilder = StringBuilder() - if (doHighlighting) { // highlight code by lexer + if (highlightingMode == InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING) { // highlight code by lexer HtmlSyntaxInfoUtil.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet( - codeSnippetBuilder, project, language, codeSnippet, false, highlightingSaturation + codeSnippetBuilder, project, language, codeSnippet, false, DocumentationSettings.getHighlightingSaturation() ) } else { codeSnippetBuilder.append(StringUtil.escapeXmlEntities(codeSnippet)) } - // set code text color as editor default code color instead of doc component text color - val codeAttributes = EditorColorsManager.getInstance().globalScheme.getAttributes(HighlighterColors.TEXT).clone() - codeAttributes.backgroundColor = null - appendStyledSpan(doHighlighting, codeAttributes, codeSnippetBuilder.toString()) + if (highlightingMode != InlineCodeHighlightingMode.NO_HIGHLIGHTING) { + // set code text color as editor default code color instead of doc component text color + val codeAttributes = EditorColorsManager.getInstance().globalScheme.getAttributes(HighlighterColors.TEXT).clone() + codeAttributes.backgroundColor = null + appendStyledSpan(true, codeAttributes, codeSnippetBuilder.toString()) + } else { + append(codeSnippetBuilder.toString()) + } return this } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/editor/quickDoc/JavadocNavigationTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/editor/quickDoc/JavadocNavigationTest.kt index d53023bbbf78..202424cc8eb2 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/editor/quickDoc/JavadocNavigationTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/editor/quickDoc/JavadocNavigationTest.kt @@ -31,8 +31,8 @@ class JavadocNavigationTest() : KotlinLightCodeInsightFixtureTestCase() { val docInfo = JavaDocInfoGenerator(project, psiClass).generateDocInfo(emptyList()) Assert.assertEquals( """

class ExtMethod
-extends Super
- directory +extends Super

""", docInfo) }