Bug 574195: [SourceEditor] Add support for context specific tab size to
assist proposals / browser information input
- Add format type FORMAT_HTMLSOURCE_INPUT for browser information
input
- Add nullable annotations to DefaultBrowserInformationInput
Change-Id: Id5714c989c97300e80271762ab57d3e34944009d
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/text/ui/DefaultBrowserInformationInput.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/text/ui/DefaultBrowserInformationInput.java
index 5bf869c..8f32a1c 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/text/ui/DefaultBrowserInformationInput.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/text/ui/DefaultBrowserInformationInput.java
@@ -14,8 +14,8 @@
package org.eclipse.statet.ecommons.text.ui;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
import org.eclipse.jface.internal.text.html.BrowserInformationControlInput;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
@@ -25,6 +25,8 @@
import org.eclipse.swt.graphics.FontData;
import org.eclipse.statet.jcommons.lang.Disposable;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
@@ -32,16 +34,22 @@
/**
*
*/
+@NonNullByDefault
public class DefaultBrowserInformationInput extends BrowserInformationControlInput {
- private static Formatter FORMATTER;
+ public static final int FORMAT_NONE= 0;
+ public static final int FORMAT_TEXT_INPUT= 1;
+ public static final int FORMAT_SOURCE_INPUT= 2;
+ public static final int FORMAT_HTMLBODY_INPUT= 3;
+ public static final int FORMAT_HTMLSOURCE_INPUT= 4;
+
+
+ private static @Nullable Formatter FORMATTER;
private static class Formatter implements IPropertyChangeListener, Disposable {
- private static final Pattern TAB_PATTERN= Pattern.compile("\\\t"); //$NON-NLS-1$
-
- private String STYLE_SHEET;
+ private String stylesheet= nonNullLateInit();
public Formatter() {
JFaceResources.getFontRegistry().addListener(this);
@@ -65,124 +73,151 @@
private void updateStyleSheet() {
String style =
// Font definitions
- "html { font-family: sans-serif; font-size: 9pt; font-style: normal; font-weight: normal; }\n"+
- "body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; }\n"+
- "pre { font-family: monospace; }\n"+
+ "html { font-family: sans-serif; font-size: 9pt; font-style: normal; font-weight: normal; }\n" +
+ "body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; }\n" +
+ "pre { font-family: monospace; }\n" +
// Margins
- "html { margin: 0px; padding: 0px }"+
- "body { overflow: auto; margin-top: 0.25em; margin-bottom: 0.5em; margin-left: 0.25em; margin-right: 0.25em; }\n"+
- "h1 { margin-top: 0.3em; margin-bottom: 0.04em; }\n"+
- "h2 { margin-top: 2em; margin-bottom: 0.25em; }\n"+
- "h3 { margin-top: 1.7em; margin-bottom: 0.25em; }\n"+
- "h4 { margin-top: 2em; margin-bottom: 0.3em; }\n"+
- "h5 { margin-top: 0px; margin-bottom: 0px; }\n"+
- "p { margin-top: 1em; margin-bottom: 1em; }\n"+
-// "pre { margin-left: 0.6em; }\n"+
- "ul { margin-top: 0px; margin-bottom: 1em; }\n"+
- "li { margin-top: 0px; margin-bottom: 0px; }\n"+
- "li p { margin-top: 0px; margin-bottom: 0px; }\n"+
- "ol { margin-top: 0px; margin-bottom: 1em; }\n"+
- "dl { margin-top: 0px; margin-bottom: 1em; }\n"+
- "dt { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }\n"+
- "dd { margin-top: 0px; margin-bottom: 0px; }\n"+
+ "html { margin: 0px; padding: 0px }" +
+ "body { overflow: auto; margin-top: 0.25em; margin-bottom: 0.5em; margin-left: 0.25em; margin-right: 0.25em; }\n" +
+ "h1 { margin-top: 0.3em; margin-bottom: 0.04em; }\n" +
+ "h2 { margin-top: 2em; margin-bottom: 0.25em; }\n" +
+ "h3 { margin-top: 1.7em; margin-bottom: 0.25em; }\n" +
+ "h4 { margin-top: 2em; margin-bottom: 0.3em; }\n" +
+ "h5 { margin-top: 0px; margin-bottom: 0px; }\n" +
+ "p { margin-top: 1em; margin-bottom: 1em; }\n" +
+// "pre { margin-left: 0.6em; }\n" +
+ "ul { margin-top: 0px; margin-bottom: 1em; }\n" +
+ "li { margin-top: 0px; margin-bottom: 0px; }\n" +
+ "li p { margin-top: 0px; margin-bottom: 0px; }\n" +
+ "ol { margin-top: 0px; margin-bottom: 1em; }\n" +
+ "dl { margin-top: 0px; margin-bottom: 1em; }\n" +
+ "dt { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }\n" +
+ "dd { margin-top: 0px; margin-bottom: 0px; }\n" +
// Styles and colors
- "a:link { color: #0000FF; }\n"+
- "a:hover { color: #000080; }\n"+
- "a:visited { text-decoration: underline; }\n"+
- "h4 { font-style: italic; }\n"+
- "strong { font-weight: bold; }\n"+
- "em { font-style: italic; }\n"+
- "var { font-style: italic; }\n"+
- "th { font-weight: bold; }\n";
+ "a:link { color: #0000FF; }\n" +
+ "a:hover { color: #000080; }\n" +
+ "a:visited { text-decoration: underline; }\n" +
+ "h4 { font-style: italic; }\n" +
+ "strong { font-weight: bold; }\n" +
+ "em { font-style: italic; }\n" +
+ "var { font-style: italic; }\n" +
+ "th { font-weight: bold; }\n";
try {
final FontData[] fontData= JFaceResources.getFontRegistry().getFontData(JFaceResources.DIALOG_FONT);
if (fontData != null && fontData.length > 0) {
- style= style.replace("9pt", fontData[0].getHeight()+"pt");
- style= style.replace("sans-serif", "sans-serif, '"+fontData[0].getName()+"'");
+ style= style.replace("9pt", fontData[0].getHeight() + "pt");
+ style= style.replace("sans-serif", "sans-serif, '" + fontData[0].getName() + "'");
}
}
catch (final Throwable e) {
}
- this.STYLE_SHEET= style;
+ this.stylesheet= style;
}
- String format(String content, final int formatting) {
- final StringBuilder s;
+ String format(String content, final int formatting,
+ final int tabSize) {
+ final String stylesheet= this.stylesheet;
+
+ final StringBuilder sb;
switch (formatting) {
case FORMAT_NONE:
return content;
case FORMAT_TEXT_INPUT:
content= HTMLPrinter.convertToHTMLContent(content);
- s= new StringBuilder(content.length() + 1000);
- s.append(content);
+ sb= new StringBuilder(content.length() + stylesheet.length() + 500);
+ sb.append(content);
+ break;
+ case FORMAT_HTMLBODY_INPUT:
+ sb= new StringBuilder(content.length() + stylesheet.length() + 500);
+ sb.append(content);
break;
case FORMAT_SOURCE_INPUT:
content= HTMLPrinter.convertToHTMLContent(content);
- final Matcher matcher= TAB_PATTERN.matcher(content);
- if (matcher.find()) {
- content= matcher.replaceAll(" "); //$NON-NLS-1$
+ //$FALL-THROUGH$
+ case FORMAT_HTMLSOURCE_INPUT:
+ sb= new StringBuilder((int)(content.length() * 1.066) + stylesheet.length() + 500);
+ sb.append("<pre>"); //$NON-NLS-1$
+ { final String spaces= " ".repeat(tabSize); //$NON-NLS-1$
+ int fromIdx= 0;
+ int tabIdx;
+ while ((tabIdx= content.indexOf('\t', fromIdx)) >= 0) {
+ sb.append(content, fromIdx, tabIdx);
+ sb.append(spaces);
+ fromIdx= tabIdx + 1;
+ }
+ sb.append(content, fromIdx, content.length());
}
- s= new StringBuilder(content.length() + 1000);
- s.append("<pre>"); //$NON-NLS-1$
- s.append(content);
- s.append("</pre>"); //$NON-NLS-1$
- break;
- case FORMAT_HTMLBODY_INPUT:
- s= new StringBuilder(content.length() + 1000);
- s.append(content);
+ sb.append("</pre>"); //$NON-NLS-1$
break;
default:
throw new IllegalArgumentException("Unsupported format"); //$NON-NLS-1$
}
- HTMLPrinter.insertPageProlog(s, 0, this.STYLE_SHEET);
- HTMLPrinter.addPageEpilog(s);
- return s.toString();
+ HTMLPrinter.insertPageProlog(sb, 0, this.stylesheet);
+ HTMLPrinter.addPageEpilog(sb);
+ return sb.toString();
}
}
- public static final int FORMAT_NONE= 0;
- public static final int FORMAT_HTMLBODY_INPUT= 1;
- public static final int FORMAT_TEXT_INPUT= 2;
- public static final int FORMAT_SOURCE_INPUT= 3;
+ private final String name;
+ private final String html;
- private final String fName;
- private final String fHtml;
-
-
- public DefaultBrowserInformationInput(final BrowserInformationControlInput previous, final String name, final String content, final int formatting) {
+ public DefaultBrowserInformationInput(final String name,
+ final String content, final int formatting,
+ final int tabSize,
+ final @Nullable BrowserInformationControlInput previous) {
super(previous);
- this.fName= name;
- this.fHtml= getFormatter().format(content, formatting);
+ this.name= nonNullAssert(name);
+ this.html= getFormatter().format(nonNullAssert(content), formatting, tabSize);
}
+ public DefaultBrowserInformationInput(final String name,
+ final String content, final int formatting,
+ final @Nullable BrowserInformationControlInput previous) {
+ this(name, content, formatting, 4, previous);
+ }
+
+ public DefaultBrowserInformationInput(final String name,
+ final String content, final int formatting,
+ final int tabSize) {
+ this(name, content, formatting, tabSize, null);
+ }
+
+ public DefaultBrowserInformationInput(final String name,
+ final String content, final int formatting) {
+ this(name, content, formatting, 4, null);
+ }
+
+
protected Formatter getFormatter() {
synchronized (DefaultBrowserInformationInput.class) {
- if (FORMATTER == null) {
- FORMATTER= new Formatter();
+ var formatter= FORMATTER;
+ if (formatter == null) {
+ formatter= new Formatter();
+ FORMATTER= formatter;
}
- return FORMATTER;
+ return formatter;
}
}
@Override
public String getInputName() {
- return this.fName;
+ return this.name;
}
@Override
public Object getInputElement() {
- return this.fHtml;
+ return this.html;
}
@Override
public String getHtml() {
- return this.fHtml;
+ return this.html;
}
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditorViewerConfiguration.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditorViewerConfiguration.java
index 6aa572f..be973c1 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditorViewerConfiguration.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditorViewerConfiguration.java
@@ -114,19 +114,14 @@
return new BrowserInformationControl(parent, JFaceResources.DIALOG_FONT, false) {
@Override
- public void setInformation(String content) {
+ public void setInformation(final String content) {
if (content.startsWith("...<br")) { // spell correction change proposal //$NON-NLS-1$
- content= content.replace("\\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
- final StringBuffer s= new StringBuffer(content.length()+1000);
- s.append("<pre>"); //$NON-NLS-1$
- s.append(content);
- s.append("</pre>"); //$NON-NLS-1$
- setInput(new DefaultBrowserInformationInput(null, "", s.toString(), //$NON-NLS-1$
- DefaultBrowserInformationInput.FORMAT_HTMLBODY_INPUT));
+ setInput(new DefaultBrowserInformationInput("", //$NON-NLS-1$
+ content, DefaultBrowserInformationInput.FORMAT_HTMLSOURCE_INPUT ));
}
else {
- setInput(new DefaultBrowserInformationInput(null, "", content, //$NON-NLS-1$
- DefaultBrowserInformationInput.FORMAT_TEXT_INPUT));
+ setInput(new DefaultBrowserInformationInput("", //$NON-NLS-1$
+ content, DefaultBrowserInformationInput.FORMAT_TEXT_INPUT ));
}
}
};
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/AssistInvocationContext.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/AssistInvocationContext.java
index 3e41612..1436b99 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/AssistInvocationContext.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/AssistInvocationContext.java
@@ -296,4 +296,8 @@
}
+ public int getTabSize() {
+ return 4;
+ }
+
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/CommandAssistProposal.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/CommandAssistProposal.java
index 7b8e37e..c8d4526 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/CommandAssistProposal.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/CommandAssistProposal.java
@@ -144,16 +144,21 @@
}
@Override
- public String getAdditionalProposalInfo() {
+ public @Nullable String getAdditionalProposalInfo() {
return this.description;
}
@Override
- public Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
- return new DefaultBrowserInformationInput(null, getDisplayString(), this.description,
- DefaultBrowserInformationInput.FORMAT_TEXT_INPUT);
+ public @Nullable Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
+ final var description= this.description;
+ if (description == null) {
+ return null;
+ }
+ return new DefaultBrowserInformationInput(getDisplayString(),
+ description, DefaultBrowserInformationInput.FORMAT_TEXT_INPUT );
}
+
@Override
public @Nullable IContextInformation getContextInformation() {
return null;
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/LinkedNamesAssistProposal.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/LinkedNamesAssistProposal.java
index 03839d9..9b40228 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/LinkedNamesAssistProposal.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/LinkedNamesAssistProposal.java
@@ -254,9 +254,13 @@
}
@Override
- public Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
- return new DefaultBrowserInformationInput(null, getDisplayString(), this.description,
- DefaultBrowserInformationInput.FORMAT_TEXT_INPUT);
+ public @Nullable Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
+ final var description= this.description;
+ if (description == null) {
+ return null;
+ }
+ return new DefaultBrowserInformationInput(getDisplayString(),
+ description, DefaultBrowserInformationInput.FORMAT_TEXT_INPUT );
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/TemplateProposal.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/TemplateProposal.java
index a12fe92..679cb18 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/TemplateProposal.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/assist/TemplateProposal.java
@@ -214,17 +214,19 @@
try {
final TemplateContext context= getContext();
context.setReadOnly(true);
+ final String preview;
if (context instanceof IWorkbenchTemplateContext) {
- return new DefaultBrowserInformationInput(
- null, getDisplayString(), ((IWorkbenchTemplateContext) context).evaluateInfo(getTemplate()),
- DefaultBrowserInformationInput.FORMAT_SOURCE_INPUT );
+ preview= ((IWorkbenchTemplateContext)context).evaluateInfo(getTemplate());
+ }
+ else {
+ final TemplateBuffer templateBuffer= context.evaluate(getTemplate());
+ preview= (templateBuffer != null) ? templateBuffer.toString() : null;
}
- final TemplateBuffer templateBuffer= context.evaluate(getTemplate());
- if (templateBuffer != null) {
- return new DefaultBrowserInformationInput(
- null, getDisplayString(), templateBuffer.toString(),
- DefaultBrowserInformationInput.FORMAT_SOURCE_INPUT );
+ if (preview != null) {
+ return new DefaultBrowserInformationInput(getDisplayString(),
+ preview, DefaultBrowserInformationInput.FORMAT_SOURCE_INPUT,
+ getInvocationContext().getTabSize() );
}
}
catch (final TemplateException | BadLocationException e) {}