New boot-hints for Eclipse client
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
contributesToHeader="false"
|
||||
highlightPreferenceKey="STS4BootMarkerHighlighting"
|
||||
highlightPreferenceValue="true"
|
||||
icon="icons/boot-icon.png"
|
||||
label="Boot Dynamic Info"
|
||||
overviewRulerPreferenceKey="STS4BootMarkerIndicationInOverviewRuler"
|
||||
overviewRulerPreferenceValue="true"
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.commons;
|
||||
|
||||
import org.eclipse.jface.text.Position;
|
||||
import org.eclipse.jface.text.source.ISourceViewer;
|
||||
import org.eclipse.jface.text.source.inlined.LineContentAnnotation;
|
||||
import org.eclipse.swt.custom.StyledText;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.FontMetrics;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
/**
|
||||
* Boot icon inlined annotation
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class BootInlineAnnotation extends LineContentAnnotation {
|
||||
|
||||
private static final int SPACING = 2;
|
||||
|
||||
public BootInlineAnnotation(Position pos, ISourceViewer viewer) {
|
||||
super(pos, viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int drawAndComputeWidth(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
|
||||
FontMetrics fontMetrics = gc.getFontMetrics();
|
||||
int height = fontMetrics.getHeight();
|
||||
|
||||
Image bootImage = LanguageServerCommonsActivator.getInstance().getImageRegistry().get(LanguageServerCommonsActivator.BOOT_ICON_2X_KEY);
|
||||
Rectangle bootImgBounds = bootImage.getBounds();
|
||||
int width = (int) Math.round(bootImgBounds.width / (double) bootImgBounds.height * height);
|
||||
|
||||
Rectangle backgroundRect = new Rectangle(x, y, width + SPACING, fontMetrics.getHeight());
|
||||
gc.setBackground(textWidget.getBackground());
|
||||
gc.fillRectangle(backgroundRect);
|
||||
|
||||
gc.drawImage(bootImage, bootImgBounds.x, bootImgBounds.y, bootImgBounds.width, bootImgBounds.height, x, y, width, height);
|
||||
|
||||
return backgroundRect.width;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,8 @@ public class LanguageServerCommonsActivator extends AbstractUIPlugin {
|
||||
|
||||
public static final String PLUGIN_ID = "org.springframework.tooling.ls.eclipse.commons";
|
||||
|
||||
public static final String BOOT_ICON_2X_KEY = "boot-icon-key";
|
||||
|
||||
private static LanguageServerCommonsActivator instance;
|
||||
|
||||
public LanguageServerCommonsActivator() {
|
||||
@@ -35,6 +37,7 @@ public class LanguageServerCommonsActivator extends AbstractUIPlugin {
|
||||
public void start(BundleContext context) throws Exception {
|
||||
instance = this;
|
||||
super.start(context);
|
||||
getImageRegistry().put(BOOT_ICON_2X_KEY, getImageDescriptor("icons/boot-icon@2x.png"));
|
||||
}
|
||||
|
||||
public final static ImageDescriptor getImageDescriptor(String path) {
|
||||
|
||||
@@ -14,8 +14,11 @@ import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
@@ -24,11 +27,16 @@ import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.action.IStatusLineManager;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.ITextViewerExtension2;
|
||||
import org.eclipse.jface.text.Position;
|
||||
import org.eclipse.jface.text.source.Annotation;
|
||||
import org.eclipse.jface.text.source.AnnotationPainter;
|
||||
import org.eclipse.jface.text.source.IAnnotationAccess;
|
||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||
import org.eclipse.jface.text.source.IAnnotationModelExtension;
|
||||
import org.eclipse.jface.text.source.ISourceViewer;
|
||||
import org.eclipse.jface.text.source.inlined.AbstractInlinedAnnotation;
|
||||
import org.eclipse.jface.text.source.inlined.InlinedAnnotationSupport;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageClientImpl;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
@@ -114,7 +122,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
IDocument doc = sourceViewer.getDocument();
|
||||
if (sourceViewer!=null) {
|
||||
if (doc!=null && annotationModel instanceof IAnnotationModelExtension) {
|
||||
updateAnnotations(target, doc, (IAnnotationModelExtension) annotationModel);
|
||||
updateAnnotations(target, sourceViewer, (IAnnotationModelExtension) annotationModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,8 +145,11 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
*/
|
||||
private Map<String, Annotation[]> currentAnnotations = new HashMap<>();
|
||||
|
||||
private synchronized void updateAnnotations(String target, IDocument doc, IAnnotationModelExtension annotationModel) {
|
||||
private Map<ISourceViewer, InlinedAnnotationSupport> viewerInlinedAnnotationSupport = new WeakHashMap<>();
|
||||
|
||||
private synchronized void updateAnnotations(String target, ISourceViewer sourceViewer, IAnnotationModelExtension annotationModel) {
|
||||
if (target!=null) {
|
||||
IDocument doc = sourceViewer.getDocument();
|
||||
Collection<LSPDocumentInfo> infos = LanguageServiceAccessor.getLSPDocumentInfosFor(doc, (x) -> true);
|
||||
for (LSPDocumentInfo docInfo : infos) {
|
||||
URI uri = docInfo.getFileUri();
|
||||
@@ -147,14 +158,72 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
if (toRemove==null) {
|
||||
toRemove = new Annotation[0];
|
||||
}
|
||||
Map<Annotation, Position> newAnnotations = createAnnotations(doc, currentHighlights.get(target));
|
||||
List<Range> highlights = currentHighlights.get(target);
|
||||
Map<Annotation, Position> newAnnotations = createAnnotations(doc, highlights);
|
||||
annotationModel.replaceAnnotations(toRemove, newAnnotations);
|
||||
currentAnnotations.put(target, newAnnotations.keySet().toArray(new Annotation[newAnnotations.size()]));
|
||||
updateInlinedAnnotations(sourceViewer, highlights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInlinedAnnotations(final ISourceViewer sourceViewer, List<Range> highlights) {
|
||||
InlinedAnnotationSupport support = viewerInlinedAnnotationSupport.get(sourceViewer);
|
||||
if (support == null) {
|
||||
final InlinedAnnotationSupport inlinedSupport = new InlinedAnnotationSupport();
|
||||
inlinedSupport.install(sourceViewer, createAnnotationPainter(sourceViewer));
|
||||
viewerInlinedAnnotationSupport.put(sourceViewer, inlinedSupport);
|
||||
sourceViewer.getTextWidget().addDisposeListener((e) -> {
|
||||
inlinedSupport.uninstall();
|
||||
viewerInlinedAnnotationSupport.remove(sourceViewer);
|
||||
});
|
||||
support = inlinedSupport;
|
||||
}
|
||||
Set<AbstractInlinedAnnotation> annotations = new HashSet<>();
|
||||
if (highlights==null) {
|
||||
highlights = ImmutableList.of();
|
||||
}
|
||||
IDocument doc = sourceViewer.getDocument();
|
||||
for (Range rng : highlights) {
|
||||
try {
|
||||
int start = LSPEclipseUtils.toOffset(rng.getStart(), doc);
|
||||
Position colorPos = new Position(start, 0);
|
||||
BootInlineAnnotation colorAnnotation = support.findExistingAnnotation(colorPos);
|
||||
if (colorAnnotation == null) {
|
||||
colorAnnotation = new BootInlineAnnotation(colorPos, sourceViewer);
|
||||
}
|
||||
annotations.add(colorAnnotation);
|
||||
} catch (BadLocationException e) {
|
||||
//ignore invalid highlights
|
||||
}
|
||||
}
|
||||
support.updateAnnotations(annotations);
|
||||
}
|
||||
|
||||
private static AnnotationPainter createAnnotationPainter(ISourceViewer viewer) {
|
||||
IAnnotationAccess annotationAccess = new IAnnotationAccess() {
|
||||
@Override
|
||||
public Object getType(Annotation annotation) {
|
||||
return annotation.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiLine(Annotation annotation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTemporary(Annotation annotation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
AnnotationPainter painter = new AnnotationPainter(viewer, annotationAccess);
|
||||
((ITextViewerExtension2) viewer).addPainter(painter);
|
||||
return painter;
|
||||
}
|
||||
|
||||
private Map<Annotation, Position> createAnnotations(IDocument doc, List<Range> highlights) {
|
||||
ImmutableMap.Builder<Annotation, Position> annotations = ImmutableMap.builder();
|
||||
if (highlights==null) {
|
||||
|
||||
Reference in New Issue
Block a user