diff options
Diffstat (limited to 'lsp4e-cpp')
-rw-r--r-- | lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLanguageServer.java | 4 | ||||
-rw-r--r-- | lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/LineBackgroundListenerCPP.java (renamed from lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLineBackgroundListener.java) | 42 | ||||
-rw-r--r-- | lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java | 142 | ||||
-rw-r--r-- | lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java | 170 | ||||
-rw-r--r-- | lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java | 3 |
5 files changed, 240 insertions, 121 deletions
diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLanguageServer.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLanguageServer.java index 80d637e82bb..a8977f83088 100644 --- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLanguageServer.java +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CqueryLanguageServer.java @@ -21,7 +21,9 @@ public class CqueryLanguageServer implements ICPPLanguageServer { @Override public Object getLSSpecificInitializationOptions(Object defaultInitOptions, URI rootPath) { -// TODO: Allow user to specify cache directory path + + // TODO: Allow user to specify cache directory path + IPath cacheDirectory = Path.fromOSString(rootPath.getPath()).append(".lsp4e-cpp/cquery_index"); //$NON-NLS-1$ JsonObject result = (defaultInitOptions instanceof JsonObject) ? (JsonObject) defaultInitOptions : new JsonObject(); result.addProperty("cacheDirectory", cacheDirectory.toString()); //$NON-NLS-1$ 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/LineBackgroundListenerCPP.java index 54c10cf39e8..387e15cedbd 100644 --- 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/LineBackgroundListenerCPP.java @@ -8,34 +8,22 @@ 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.BadPositionCategoryException; import org.eclipse.jface.text.IDocument; -import org.eclipse.lsp4e.LSPEclipseUtils; +import org.eclipse.jface.text.Position; 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<Range> inactiveRegions; +public class LineBackgroundListenerCPP implements LineBackgroundListener { private IDocument currentDocument; - private URI currentDocumentUri; private Color lineBackgroundColor; - // TODO: Remove mappings if not required - public static ConcurrentMap<URI, List<Range>> fileInactiveRegionsMap = new ConcurrentHashMap<>(16, 0.75f, 1); - public void setCurrentDocument(IDocument currentDocument) { this.currentDocument = currentDocument; } @@ -47,25 +35,25 @@ public class CqueryLineBackgroundListener implements LineBackgroundListener { return; } - IFile file = LSPEclipseUtils.getFile(currentDocument); - if (file == null) { - return; + Position[] inactivePositions = null; + try { + inactivePositions = currentDocument.getPositions(PresentationReconcilerCPP.INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY); + } catch (BadPositionCategoryException e) { + Activator.log(e); } - currentDocumentUri = LSPEclipseUtils.toUri(file); - inactiveRegions = fileInactiveRegionsMap.get(currentDocumentUri); - if (this.inactiveRegions == null) { + if (inactivePositions == null) { return; } try { - for (Range eachInactiveRange : this.inactiveRegions) { - int regionStartLine = eachInactiveRange.getStart().getLine(); - int regionEndLine = eachInactiveRange.getEnd().getLine(); + for (Position eachInactivePosition : inactivePositions) { + int regionStartLine = currentDocument.getLineOfOffset(eachInactivePosition.getOffset()); + int regionEndLine = currentDocument.getLineOfOffset(eachInactivePosition.getOffset() + eachInactivePosition.getLength()); if (event.lineOffset >= currentDocument.getLineOffset(regionStartLine) - && event.lineOffset <= currentDocument.getLineOffset(regionEndLine)) { - event.lineBackground = lineBackgroundColor; - break; + && event.lineOffset <= currentDocument.getLineOffset(regionEndLine)) { + event.lineBackground = lineBackgroundColor; + break; } } } catch (BadLocationException 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 0d732647d3b..e607c9d2700 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 @@ -19,6 +19,7 @@ package org.eclipse.lsp4e.cpp.language; import java.net.URI; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -27,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.model.ICLanguageKeywords; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.internal.ui.editor.CEditor.BracketInserter; +import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightedPosition; import org.eclipse.cdt.internal.ui.text.CCodeScanner; import org.eclipse.cdt.internal.ui.text.CCommentScanner; import org.eclipse.cdt.internal.ui.text.CPreprocessorScanner; @@ -36,7 +38,6 @@ import org.eclipse.cdt.internal.ui.text.SingleTokenCScanner; import org.eclipse.cdt.internal.ui.text.TokenStore; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.ILanguageUI; -import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.text.AbstractCScanner; import org.eclipse.cdt.ui.text.ICColorConstants; import org.eclipse.cdt.ui.text.ICPartitions; @@ -45,25 +46,20 @@ import org.eclipse.cdt.ui.text.ITokenStore; import org.eclipse.cdt.ui.text.ITokenStoreFactory; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferenceConverter; -import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; 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.Position; import org.eclipse.jface.text.TextPresentation; import org.eclipse.jface.text.TextViewer; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.RuleBasedScanner; import org.eclipse.jface.text.source.SourceViewer; -import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights; -import org.eclipse.lsp4e.cpp.language.cquery.HighlightSymbol; -import org.eclipse.lsp4j.Range; -import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.editors.text.TextEditor; @@ -78,11 +74,16 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { private CCommentScanner fMultilineCommentScanner; private SingleTokenCScanner fStringScanner; private AbstractCScanner fCodeScanner; - private CqueryLineBackgroundListener fLineBackgroundListener = new CqueryLineBackgroundListener(); + private LineBackgroundListenerCPP fLineBackgroundListener = new LineBackgroundListenerCPP(); private ITextViewer textViewer; private TextInputListenerCPP textInputListener; private BracketInserter fBracketInserter; + private DefaultPositionUpdater semanticHighlightingPositionUpdater; + public static final String SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY = "org.eclipse.lsp4e.cpp.semanticHighlight"; //$NON-NLS-1$ + public static final String INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY = "org.eclipse.lsp4e.cpp.inactiveCodeHighlight"; //$NON-NLS-1$ + + // A set containing all active objects of PresentationReconcilerCPP. public static Set<PresentationReconcilerCPP> presentationReconcilers = ConcurrentHashMap.newKeySet(); protected ITokenStoreFactory getTokenStoreFactory() { @@ -187,65 +188,37 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { return presentation; } - List<HighlightSymbol> semanticHighlights = CquerySemanticHighlights.uriToSemanticHighlightsMapping.get(uri); + Position[] returnedPositions = null; + List<StyleRange> styleRanges = new ArrayList<>(); + HighlightedPosition[] highlightedPositions; + + /* + * Adding Semantic Highlighting Position Category to so that we don't get a + * BadPositionCategoryException if this method is called before setupDocument() + * could the add new position category. + */ + addSemanticHighlightPositionCategory(doc); + + try { + returnedPositions = doc.getPositions(SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY); + } catch (BadPositionCategoryException e) { + Activator.log(e); + } - if(semanticHighlights == null) { + if (returnedPositions == null) { return presentation; } - IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore(); - List<StyleRange> styleRanges = new ArrayList<>(); - - for (HighlightSymbol highlight : semanticHighlights) { - - String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(), highlight.getParentKind(), highlight.getStorage()); - String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX - + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; + highlightedPositions = Arrays.copyOf(returnedPositions, returnedPositions.length, HighlightedPosition[].class); + int damageStartOffset = damage.getOffset(); + int damageEndOffset = damageStartOffset + damage.getLength(); - boolean isBold = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX - + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX); - boolean isItalic = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX - + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX); - boolean isUnderline = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX - + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX); - boolean isStrikethrough = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX - + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX); - - Color color = new Color(Display.getCurrent(), - PreferenceConverter.getColor(CUIPlugin.getDefault().getPreferenceStore(), colorKey)); - - int damageStartOffset = damage.getOffset(); - int damageEndOffset = damageStartOffset + damage.getLength(); - - List<Range> ranges = highlight.getRanges(); - for (Range range : ranges) { - - int offset = 0, length = 0; - try { - offset = doc.getLineOffset(range.getStart().getLine()) + range.getStart().getCharacter(); - length = doc.getLineOffset(range.getEnd().getLine()) + range.getEnd().getCharacter() - offset; - } catch (BadLocationException e) { - Activator.log(e); - } - if ((offset + length) >= damageStartOffset && offset < damageEndOffset) { - - StyleRange styleRange = new StyleRange(offset, length, color, null); - - if (isBold) { - styleRange.fontStyle = SWT.BOLD; - } - if (isItalic) { - styleRange.fontStyle |= SWT.ITALIC; - } - if (isUnderline) { - styleRange.underline = true; - } - if (isStrikethrough) { - styleRange.strikeout = true; - } - - styleRanges.add(styleRange); - } + for (HighlightedPosition eachPosition : highlightedPositions) { + // Find each position that resides in or overlaps the damage region and create StyleRange for it. + if ((eachPosition.getOffset() + eachPosition.getLength()) >= damageStartOffset + && eachPosition.getOffset() < damageEndOffset) { + StyleRange range = eachPosition.createStyleRange(); + styleRanges.add(range); } } @@ -265,8 +238,8 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { if (resource == null) { resource= ResourcesPlugin.getWorkspace().getRoot(); } -// IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getMultilineConfiguration(); -// fMultilineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory()); + // IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getMultilineConfiguration(); + // fMultilineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory()); if (fMultilineDocCommentScanner == null) { // fallback: normal comment highlighting fMultilineDocCommentScanner= fMultilineCommentScanner; @@ -286,8 +259,8 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { if (resource == null) { resource= ResourcesPlugin.getWorkspace().getRoot(); } -// IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getSinglelineConfiguration(); -// fSinglelineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory()); + // IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getSinglelineConfiguration(); + // fSinglelineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory()); if (fSinglelineDocCommentScanner == null) { // fallback: normal comment highlighting fSinglelineDocCommentScanner= fSinglelineCommentScanner; @@ -327,9 +300,31 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { } } + private void addSemanticHighlightPositionCategory(IDocument document) { + if (!document.containsPositionCategory(SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY)) { + document.addPositionCategory(SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY); + semanticHighlightingPositionUpdater = new DefaultPositionUpdater(SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY); + document.addPositionUpdater(semanticHighlightingPositionUpdater); + } + } + + private void addInactiveCodeHighlightingCategory(IDocument document) { + if (!document.containsPositionCategory(INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY)) { + document.addPositionCategory(INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY); + DefaultPositionUpdater inactiveCodeHighlightingPositionUpdater = new DefaultPositionUpdater(INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY); + document.addPositionUpdater(inactiveCodeHighlightingPositionUpdater); + } + } + public void setupDocument(IDocument newDocument) { if (newDocument != null) { fLineBackgroundListener.setCurrentDocument(newDocument); + + // Adding Semantic Highlighting Position Category and a DefaultPositionUpdater to the document. + addSemanticHighlightPositionCategory(newDocument); + + // Adding Inactive Code Highlighting Position Category and a DefaultPositionUpdater to the document. + addInactiveCodeHighlightingCategory(newDocument); } } @@ -337,6 +332,10 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { return textViewer; } + public DefaultPositionUpdater getSemanticHighlightingPositionUpdater() { + return semanticHighlightingPositionUpdater; + } + @Override public void install(ITextViewer viewer) { super.install(viewer); @@ -351,13 +350,12 @@ public class PresentationReconcilerCPP extends CPresentationReconciler { textWidget.addLineBackgroundListener(fLineBackgroundListener); presentationReconcilers.add(this); -// Using asyncExec() to make sure that by the time Runnable runs, -// the Editor is active and we don't get a NPE. + // Using asyncExec() to make sure that by the time Runnable runs, + // the Editor is active and we don't get a NPE. Display.getDefault().asyncExec(new Runnable() { @Override public void run() { -// To provide bracket auto-completion support of CEditor in Generic Editor of LSP4E-CPP - + // To provide bracket auto-completion support of CEditor in Generic Editor of LSP4E-CPP. TextEditor editor = (TextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); fBracketInserter = new BracketInserter(editor, true); fBracketInserter.setSourceViewer((SourceViewer) textViewer); 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 c2e913c25f2..0a23ce75388 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 @@ -12,20 +12,33 @@ import java.net.URI; import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightedPosition; +import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightingStyle; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.core.resources.IFile; import org.eclipse.jface.action.StatusLineContributionItem; import org.eclipse.jface.action.StatusLineManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.TextPresentation; import org.eclipse.lsp4e.LSPEclipseUtils; 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.HighlightSymbol; 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.SWT; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -60,31 +73,68 @@ public class Server2ClientProtocolExtension extends LanguageClientImpl { @JsonNotification("$cquery/setInactiveRegions") public final void setInactiveRegions(CqueryInactiveRegions regions) { - URI uri = regions.getUri(); + URI uriReceived = regions.getUri(); List<Range> inactiveRegions = regions.getInactiveRegions(); - CqueryLineBackgroundListener.fileInactiveRegionsMap.put(uri, inactiveRegions); - } + IDocument doc = null; - public static URI getUri(IDocument document) { - URI uri = null; - IFile file = LSPEclipseUtils.getFile(document); - if (file != null) { - uri = LSPEclipseUtils.toUri(file); + // To get the document for the received URI. + for (PresentationReconcilerCPP eachReconciler: PresentationReconcilerCPP.presentationReconcilers) { + IDocument currentReconcilerDoc = eachReconciler.getTextViewer().getDocument(); + URI currentReconcilerUri = getUri(currentReconcilerDoc); + + if (currentReconcilerUri == null) { + continue; + } + + if (uriReceived.equals(currentReconcilerUri)) { + doc = currentReconcilerDoc; + break; + } + } + + if (doc == null) { + return; + } + + // Removing inactive code highlighting position category and old positions from document. + try { + doc.removePositionCategory(PresentationReconcilerCPP.INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY); + } catch (BadPositionCategoryException e) { + Activator.log(e); + } + // Again add Inactive Code Position Category to the document. + doc.addPositionCategory(PresentationReconcilerCPP.INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY); + + for (Range region : inactiveRegions) { + int offset = 0, length = 0; + try { + offset = doc.getLineOffset(region.getStart().getLine()); + length = doc.getLineOffset(region.getEnd().getLine()) - offset; + } catch (BadLocationException e) { + Activator.log(e); + } + + Position inactivePosition = new Position(offset, length); + try { + doc.addPosition(PresentationReconcilerCPP.INACTIVE_CODE_HIGHLIGHTING_POSITION_CATEGORY, inactivePosition); + } catch (BadLocationException | BadPositionCategoryException e) { + Activator.log(e); + } } - return uri; } @JsonNotification("$cquery/publishSemanticHighlighting") public final void semanticHighlights(CquerySemanticHighlights highlights) { URI uriReceived = highlights.getUri(); - CquerySemanticHighlights.uriToSemanticHighlightsMapping.put(uriReceived, highlights.getSymbols()); + + // List of PresentationReconcilerCPP objects attached with same C++ source file. List<PresentationReconcilerCPP> matchingReconcilers = new ArrayList<>(); for (PresentationReconcilerCPP eachReconciler: PresentationReconcilerCPP.presentationReconcilers) { IDocument currentReconcilerDoc = eachReconciler.getTextViewer().getDocument(); URI currentReconcilerUri = getUri(currentReconcilerDoc); - if(currentReconcilerUri == null) { + if (currentReconcilerUri == null) { continue; } @@ -93,18 +143,102 @@ public class Server2ClientProtocolExtension extends LanguageClientImpl { } } + if (matchingReconcilers.size() == 0) { + return; + } + + // Using only first object of matchingReconcilers because all reconciler objects share same document object. + IDocument doc = matchingReconcilers.get(0).getTextViewer().getDocument(); + IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore(); + + // Removing semantic highlighting position category and old positions from document. + try { + doc.removePositionCategory(PresentationReconcilerCPP.SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY); + } catch (BadPositionCategoryException e) { + Activator.log(e); + } + // Again add Semantic Highlighting Position Category to the document. + doc.addPositionCategory(PresentationReconcilerCPP.SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY); + + for (HighlightSymbol highlight : highlights.getSymbols()) { + + String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(), highlight.getParentKind(), highlight.getStorage()); + String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; + + boolean isEnabled = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED_SUFFIX); + boolean isBold = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX); + boolean isItalic = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX); + boolean isUnderline = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX); + boolean isStrikethrough = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX); + + // TODO: Use IColorManager to cache Color objects so that only one object per color is created. + Color color = new Color(Display.getCurrent(), + PreferenceConverter.getColor(CUIPlugin.getDefault().getPreferenceStore(), colorKey)); + + List<Range> ranges = highlight.getRanges(); + for (Range range : ranges) { + + int offset = 0, length = 0; + try { + offset = doc.getLineOffset(range.getStart().getLine()) + range.getStart().getCharacter(); + length = doc.getLineOffset(range.getEnd().getLine()) + range.getEnd().getCharacter() - offset; + } catch (BadLocationException e) { + Activator.log(e); + } + + int textStyle = SWT.NORMAL; + + if (isBold) { + textStyle = SWT.BOLD; + } + if (isItalic) { + textStyle |= SWT.ITALIC; + } + if (isUnderline) { + textStyle |= TextAttribute.UNDERLINE; + } + if (isStrikethrough) { + textStyle |= TextAttribute.STRIKETHROUGH; + } + + TextAttribute textAttribute = new TextAttribute(color, null, textStyle); + HighlightingStyle highlightingStyle = new HighlightingStyle(textAttribute, isEnabled); + HighlightedPosition highlightedPosition = new HighlightedPosition(offset, length, highlightingStyle, matchingReconcilers.get(0).getSemanticHighlightingPositionUpdater()); + try { + doc.addPosition(PresentationReconcilerCPP.SEMANTIC_HIGHLIGHTING_POSITION_CATEGORY, highlightedPosition); + } catch (BadLocationException | BadPositionCategoryException e) { + Activator.log(e); + } + } + } + Display.getDefault().asyncExec(new Runnable() { @Override public void run() { - for (PresentationReconcilerCPP p: matchingReconcilers) { - IDocument currentReconcilerDoc = p.getTextViewer().getDocument(); - if (currentReconcilerDoc == null) { - continue; - } - TextPresentation textPresentation = p.createPresentation(new Region(0, currentReconcilerDoc.getLength()), currentReconcilerDoc); - p.getTextViewer().changeTextPresentation(textPresentation, false); + for (PresentationReconcilerCPP eachReconciler : matchingReconcilers) { + TextPresentation presentation = eachReconciler.createPresentation(new Region(0, doc.getLength()), doc); + eachReconciler.getTextViewer().changeTextPresentation(presentation, false); } } }); } + + /* + * Returns the URI of the Document provided. + * Can return null value. + */ + public static URI getUri(IDocument document) { + URI uri = null; + IFile file = LSPEclipseUtils.getFile(document); + if (file != null) { + uri = LSPEclipseUtils.toUri(file); + } + return uri; + } } diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java index 5b504a4a7cc..2917e9551cd 100644 --- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java +++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java @@ -10,13 +10,10 @@ package org.eclipse.lsp4e.cpp.language.cquery; import java.net.URI; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; public class CquerySemanticHighlights { private URI uri; private List<HighlightSymbol> symbols; - public static ConcurrentMap<URI, List<HighlightSymbol>> uriToSemanticHighlightsMapping = new ConcurrentHashMap<>(16, 0.75f, 1); public URI getUri() { return uri; |