diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Activator.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Activator.java index 8485e477d01..2206de04bb8 100644 --- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Activator.java +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Activator.java @@ -8,6 +8,8 @@ package org.eclipse.lsp4e.cpp.language; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -35,4 +37,34 @@ public class Activator extends AbstractUIPlugin { public static Activator getDefault() { return plugin; } + + /** + * Creates an error status. + * + * @noreference This method is not intended to be referenced by clients. + */ + public static Status createErrorStatus(String message, Throwable e) { + return new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, e); + } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + public static void log(Throwable e) { + log("Error", e); //$NON-NLS-1$ + } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + public static void log(String message, Throwable e) { + log(createErrorStatus(message, e)); + } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + public static void log(IStatus status) { + getDefault().getLog().log(status); + } } diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLineBackgroundListener.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLineBackgroundListener.java new file mode 100644 index 00000000000..54c10cf39e8 --- /dev/null +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLineBackgroundListener.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2018 Manish Khurana , Nathan Ridge 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 + *******************************************************************************/ + +package org.eclipse.lsp4e.cpp.language; + +import java.net.URI; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.lsp4e.LSPEclipseUtils; +import org.eclipse.swt.custom.LineBackgroundEvent; +import org.eclipse.swt.custom.LineBackgroundListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; +import org.eclipse.lsp4j.Range; + +@SuppressWarnings("restriction") +public class CqueryLineBackgroundListener implements LineBackgroundListener { + private List inactiveRegions; + private IDocument currentDocument; + private URI currentDocumentUri; + private Color lineBackgroundColor; + + // TODO: Remove mappings if not required + public static ConcurrentMap> fileInactiveRegionsMap = new ConcurrentHashMap<>(16, 0.75f, 1); + + public void setCurrentDocument(IDocument currentDocument) { + this.currentDocument = currentDocument; + } + + @Override + public void lineGetBackground(LineBackgroundEvent event) { + lineBackgroundColor = new Color(Display.getCurrent(),PreferenceConverter.getColor(CUIPlugin.getDefault().getPreferenceStore(), CEditor.INACTIVE_CODE_COLOR)); + if (currentDocument == null) { + return; + } + + IFile file = LSPEclipseUtils.getFile(currentDocument); + if (file == null) { + return; + } + currentDocumentUri = LSPEclipseUtils.toUri(file); + inactiveRegions = fileInactiveRegionsMap.get(currentDocumentUri); + + if (this.inactiveRegions == null) { + return; + } + + try { + for (Range eachInactiveRange : this.inactiveRegions) { + int regionStartLine = eachInactiveRange.getStart().getLine(); + int regionEndLine = eachInactiveRange.getEnd().getLine(); + if (event.lineOffset >= currentDocument.getLineOffset(regionStartLine) + && event.lineOffset <= currentDocument.getLineOffset(regionEndLine)) { + event.lineBackground = lineBackgroundColor; + break; + } + } + } catch (BadLocationException e) { + Activator.log(e); + } + } +} diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java index f6fe57362f4..e50d187fbca 100644 --- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java @@ -11,6 +11,8 @@ * Anton Leherbauer (Wind River Systems) * Sergey Prigogin (Google) * Marc-Andre Laperle (Ericsson) - Mostly copied from CSourceViewerConfiguration + * Nathan Ridge + * Manish Khurana *******************************************************************************/ package org.eclipse.lsp4e.cpp.language; @@ -38,9 +40,12 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextPresentation; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.swt.custom.StyledText; /** * Hack-ish reconciler to get some colors in the generic editor using the C/C++ @@ -54,6 +59,9 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { private SingleTokenCScanner fStringScanner; private AbstractCScanner fCodeScanner; private boolean fSettingPartitioner = false; + private CqueryLineBackgroundListener fLineBackgroundListener = new CqueryLineBackgroundListener(); + private ITextViewer textViewer; + private TextInputListenerCPP textInputListener; protected ITokenStoreFactory getTokenStoreFactory() { return new ITokenStoreFactory() { @Override @@ -203,6 +211,7 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { } protected AbstractCScanner fPreprocessorScanner; + protected RuleBasedScanner getPreprocessorScanner(ILanguage language) { if (fPreprocessorScanner != null) { return fPreprocessorScanner; @@ -219,4 +228,43 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { fPreprocessorScanner= scanner; return fPreprocessorScanner; } + + class TextInputListenerCPP implements ITextInputListener { + + @Override + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + setupDocument(newInput); + } + + @Override + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + } + } + + public void setupDocument(IDocument newDocument) { + if (newDocument != null) { + fLineBackgroundListener.setCurrentDocument(newDocument); + } + } + + @Override + public void install(ITextViewer viewer) { + super.install(viewer); + this.textViewer = viewer; + textInputListener = new TextInputListenerCPP(); + viewer.addTextInputListener(textInputListener); + IDocument document= viewer.getDocument(); + if (document != null) { + textInputListener.inputDocumentChanged(null, document); + } + StyledText textWidget = textViewer.getTextWidget(); + textWidget.addLineBackgroundListener(fLineBackgroundListener); + } + + @Override + public void uninstall() { + super.uninstall(); + textViewer.getTextWidget().removeLineBackgroundListener(fLineBackgroundListener); + textViewer.removeTextInputListener(textInputListener); + } } diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java index 239aef54fc3..41dc5d5b80b 100644 --- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java @@ -8,12 +8,16 @@ package org.eclipse.lsp4e.cpp.language; +import java.net.URI; +import java.util.List; + import org.eclipse.jface.action.StatusLineContributionItem; import org.eclipse.jface.action.StatusLineManager; import org.eclipse.lsp4e.LanguageClientImpl; import org.eclipse.lsp4e.cpp.language.cquery.CqueryInactiveRegions; import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights; import org.eclipse.lsp4e.cpp.language.cquery.IndexingProgressStats; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; @@ -21,6 +25,7 @@ import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchWindow; + @SuppressWarnings("restriction") public class Server2ClientProtocolExtension extends LanguageClientImpl { @@ -50,7 +55,9 @@ public class Server2ClientProtocolExtension extends LanguageClientImpl { @JsonNotification("$cquery/setInactiveRegions") public final void setInactiveRegions(CqueryInactiveRegions regions) { - // TODO: Implement + URI uri = regions.getUri(); + List inactiveRegions = regions.getInactiveRegions(); + CqueryLineBackgroundListener.fileInactiveRegionsMap.put(uri, inactiveRegions); } @JsonNotification("$cquery/publishSemanticHighlighting")