From 15d0d12802084f3141bfdff8fe9136d1e3d691bb Mon Sep 17 00:00:00 2001 From: Lucas Bullen Date: Fri, 25 Aug 2017 15:13:15 -0400 Subject: Bug 521418 - [GE] support multiple reconcilers for same contentType Adds all reconcilers to the editor in ascending order of specificity Change-Id: I2abc3097b517176333a758b0a0025e12ac47a21e Signed-off-by: Lucas Bullen --- .../genericeditor/CompositeReconciler.java | 67 +++++++++++++++++++ .../genericeditor/CompositeReconcilerStrategy.java | 75 ++++++++++++++++++++++ .../ExtensionBasedTextViewerConfiguration.java | 2 +- .../internal/genericeditor/ReconcilerRegistry.java | 8 ++- 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconciler.java create mode 100644 org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java (limited to 'org.eclipse.ui.genericeditor') diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconciler.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconciler.java new file mode 100644 index 00000000000..eb3f9f07cc5 --- /dev/null +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconciler.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat Inc. and others. + * 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: + * Lucas Bullen (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor; + +import java.util.List; +import java.util.Objects; + +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.IReconcilerExtension; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; + +public class CompositeReconciler implements IReconciler, IReconcilerExtension { + private List fReconcilers; + + public CompositeReconciler(List reconcilers) { + fReconcilers = reconcilers; + } + + @Override + public String getDocumentPartitioning() { + boolean defaultFound = false; + String[] types = (String[]) fReconcilers.stream() + .filter(IReconcilerExtension.class::isInstance) + .map(IReconcilerExtension.class::cast) + .map(IReconcilerExtension::getDocumentPartitioning) + .filter(Objects::nonNull) + .toArray(); + for (String type : types) { + if (type.equals(IDocumentExtension3.DEFAULT_PARTITIONING)) { + defaultFound = true; + } else { + return type; + } + } + return defaultFound ? IDocumentExtension3.DEFAULT_PARTITIONING : null; + } + + @Override + public void install(ITextViewer textViewer) { + for (IReconciler iReconciler : fReconcilers) { + iReconciler.install(textViewer); + } + } + + @Override + public void uninstall() { + for (IReconciler iReconciler : fReconcilers) { + iReconciler.uninstall(); + } + } + + @Override + public IReconcilingStrategy getReconcilingStrategy(String contentType) { + return new CompositeReconcilerStrategy(fReconcilers, contentType); + + } +} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java new file mode 100644 index 00000000000..f302460a3e4 --- /dev/null +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat Inc. and others. + * 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: + * Lucas Bullen (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension; + +public class CompositeReconcilerStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension{ + private List fReconcilingStrategies; + + public CompositeReconcilerStrategy(List reconcilers, String contentType) { + this.fReconcilingStrategies = new ArrayList<>(); + for (IReconciler iReconciler : reconcilers) { + IReconcilingStrategy strategy = iReconciler.getReconcilingStrategy(contentType); + if(strategy != null) { + fReconcilingStrategies.add(strategy); + } + } + } + @Override + public void setProgressMonitor(IProgressMonitor monitor) { + for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) { + if (iReconcilingStrategy instanceof IReconcilingStrategyExtension) { + ((IReconcilingStrategyExtension) iReconcilingStrategy).setProgressMonitor(monitor); + } + } + } + + @Override + public void initialReconcile() { + for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) { + if (iReconcilingStrategy instanceof IReconcilingStrategyExtension) { + ((IReconcilingStrategyExtension) iReconcilingStrategy).initialReconcile(); + } + } + } + + @Override + public void setDocument(IDocument document) { + for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) { + iReconcilingStrategy.setDocument(document); + } + } + + @Override + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) { + iReconcilingStrategy.reconcile(dirtyRegion, subRegion); + } + } + + @Override + public void reconcile(IRegion partition) { + for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) { + iReconcilingStrategy.reconcile(partition); + } + } + +} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java index 47f7daf6690..ab43608f518 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java @@ -192,7 +192,7 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe ReconcilerRegistry registry = GenericEditorPlugin.getDefault().getReconcilerRegistry(); List reconciliers = registry.getReconcilers(sourceViewer, getContentTypes()); if (!reconciliers.isEmpty()) { - return reconciliers.get(0); + return new CompositeReconciler(reconciliers); } return null; } diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java index 28d1f39f751..5d52e3cfd65 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java @@ -57,17 +57,19 @@ public class ReconcilerRegistry { * to document content types. * @param sourceViewer the source viewer we're hooking completion to. * @param contentTypes the content types of the document we're editing. - * @return the list of {@link IReconciler} contributed for at least one of the content types. + * @return the list of {@link IReconciler} contributed for at least one of the content types, + * sorted by most generic content type to most specific. */ public List getReconcilers(ISourceViewer sourceViewer, Set contentTypes) { if (this.outOfSync) { sync(); } - return this.extensions.values().stream() + List reconcilers = this.extensions.values().stream() .filter(ext -> contentTypes.contains(ext.targetContentType)) - .sorted(new ContentTypeSpecializationComparator()) + .sorted(new ContentTypeSpecializationComparator().reversed()) .map(GenericContentTypeRelatedExtension::createDelegate) .collect(Collectors.toList()); + return reconcilers; } private void sync() { -- cgit v1.2.3