diff --git a/org.eclipse.buildship.ui/.classpath b/org.eclipse.buildship.ui/.classpath
index dddac7bb9..4d0201e7b 100644
--- a/org.eclipse.buildship.ui/.classpath
+++ b/org.eclipse.buildship.ui/.classpath
@@ -4,5 +4,6 @@
+
diff --git a/org.eclipse.buildship.ui/build.gradle b/org.eclipse.buildship.ui/build.gradle
index d546fa4a3..44746f05b 100644
--- a/org.eclipse.buildship.ui/build.gradle
+++ b/org.eclipse.buildship.ui/build.gradle
@@ -4,3 +4,13 @@ dependencies {
compile withEclipseBundle("org.eclipse.swt.${ECLIPSE_WS}.${ECLIPSE_OS}.${ECLIPSE_ARCH}")
}
+// use java-e48 source dir for all Eclipse 4.8+ builds
+if (eclipsebuild.Config.on(project).targetPlatform.eclipseVersion =~ /48|49|41[0-9]|4[2-9][0-9]|[5-9][0-9][0-9]?/) {
+ sourceSets {
+ main {
+ java {
+ srcDirs += 'java-e48'
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.buildship.ui/build.properties b/org.eclipse.buildship.ui/build.properties
index c5878ad67..947349481 100644
--- a/org.eclipse.buildship.ui/build.properties
+++ b/org.eclipse.buildship.ui/build.properties
@@ -1,4 +1,5 @@
source.. = src/main/java/,\
+ src/main/java-e48,\
src/main/resources/
output.. = bin/
bin.includes = .,\
diff --git a/org.eclipse.buildship.ui/plugin.xml b/org.eclipse.buildship.ui/plugin.xml
index d96959e58..2a78d4996 100644
--- a/org.eclipse.buildship.ui/plugin.xml
+++ b/org.eclipse.buildship.ui/plugin.xml
@@ -598,4 +598,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/GradleEditorCodeMiningProvider.java b/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/GradleEditorCodeMiningProvider.java
new file mode 100644
index 000000000..06eeff690
--- /dev/null
+++ b/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/GradleEditorCodeMiningProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 the original author or authors.
+ * 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
+ */
+
+package org.eclipse.buildship.ui.internal.editor;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider;
+import org.eclipse.jface.text.codemining.ICodeMining;
+
+/**
+ * Contributes Gradle project synchronization to code mining.
+ *
+ * @author Donat Csikos
+ */
+public class GradleEditorCodeMiningProvider extends AbstractCodeMiningProvider {
+
+ @Override
+ public CompletableFuture> provideCodeMinings(ITextViewer viewer, IProgressMonitor monitor) {
+ return CompletableFuture.supplyAsync(() -> {
+ try {
+ return Arrays.asList(new ProjectSynchronizerCodeMining(viewer.getDocument(), this));
+ } catch (BadLocationException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/ProjectSynchronizerCodeMining.java b/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/ProjectSynchronizerCodeMining.java
new file mode 100644
index 000000000..2d9429db0
--- /dev/null
+++ b/org.eclipse.buildship.ui/src/main/java-e48/org/eclipse/buildship/ui/internal/editor/ProjectSynchronizerCodeMining.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019 the original author or authors.
+ * 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
+ */
+
+package org.eclipse.buildship.ui.internal.editor;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.codemining.ICodeMiningProvider;
+import org.eclipse.jface.text.codemining.LineHeaderCodeMining;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+import org.eclipse.buildship.core.GradleCore;
+import org.eclipse.buildship.core.internal.workspace.NewProjectHandler;
+import org.eclipse.buildship.core.internal.workspace.SynchronizationJob;
+import org.eclipse.buildship.ui.internal.PluginImage.ImageState;
+import org.eclipse.buildship.ui.internal.PluginImages;
+
+/**
+ * Adds synchronize action code mining.
+ *
+ * @author Donat Csikos
+ */
+public class ProjectSynchronizerCodeMining extends LineHeaderCodeMining {
+
+ private static final String REFRESH_LABEL = "Refresh Gradle build";
+
+ private final IDocument document;
+
+ public ProjectSynchronizerCodeMining(IDocument document, ICodeMiningProvider provider) throws BadLocationException {
+ super(0, document, provider);
+ this.document = document;
+ }
+
+ @Override
+ protected CompletableFuture doResolve(ITextViewer viewer, IProgressMonitor monitor) {
+ return CompletableFuture.runAsync(() -> {
+ super.setLabel(REFRESH_LABEL);
+ return;
+ });
+ }
+
+ @Override
+ public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) {
+ int imageSize = textWidget.getLineHeight(); // rectangular image
+ Image image = getImage();
+ Rectangle imageBounds = image.getBounds();
+ gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, x, y, imageSize, imageSize);
+ gc.drawText(REFRESH_LABEL, x + imageSize, y);
+ return new Point(imageSize + gc.textExtent(REFRESH_LABEL).x, imageSize);
+ }
+
+ private Image getImage() {
+ return PluginImages.REFRESH.withState(ImageState.DISABLED).getImage();
+ }
+
+ @Override
+ public Consumer getAction() {
+ return t -> executeSynchronization(t);
+ }
+
+ private void executeSynchronization(MouseEvent t) {
+ if (this.document != null) {
+ ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
+ if (manager != null) {
+ ITextFileBuffer buffer = manager.getTextFileBuffer(this.document);
+ if (buffer != null) {
+ IPath path = buffer.getLocation();
+ if (path != null) {
+ IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+ if (resource != null) {
+ IProject project = resource.getProject();
+ GradleCore.getWorkspace().getBuild(project).ifPresent(build -> new SynchronizationJob(NewProjectHandler.IMPORT_AND_MERGE, build).schedule());
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/internal/editor/GradleTextViewerConfiguration.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/internal/editor/GradleTextViewerConfiguration.java
index e63e00f46..496e53d97 100644
--- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/internal/editor/GradleTextViewerConfiguration.java
+++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/internal/editor/GradleTextViewerConfiguration.java
@@ -8,7 +8,6 @@
package org.eclipse.buildship.ui.internal.editor;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
-import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
@@ -34,11 +33,6 @@ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceVie
return reconciler;
}
- @Override
- public IReconciler getReconciler(ISourceViewer sourceViewer) {
- return null;
- }
-
@Override
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
return GradleEditorConstants.PARTITIONS;