aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorszarnekow2009-03-07 09:45:53 (EST)
committersefftinge2009-03-07 09:45:53 (EST)
commita26a3af393dbecad7102f9b2d21929abead1aea0 (patch)
tree770123342bdba4907d16cef453e99c6a881c0921
parent800517df58716acc722b93bfc328be326ce1ac38 (diff)
downloadorg.eclipse.xtext-a26a3af393dbecad7102f9b2d21929abead1aea0.zip
org.eclipse.xtext-a26a3af393dbecad7102f9b2d21929abead1aea0.tar.gz
org.eclipse.xtext-a26a3af393dbecad7102f9b2d21929abead1aea0.tar.bz2
Fix: syntax highlighting: even local changes update necessary region (see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=262528)
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextDamagerRepairer.java108
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java10
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java10
3 files changed, 117 insertions, 11 deletions
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextDamagerRepairer.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextDamagerRepairer.java
new file mode 100644
index 0000000..b73d18d
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextDamagerRepairer.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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.xtext.ui.core.editor;
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.CompositeNode;
+import org.eclipse.xtext.parsetree.LeafNode;
+import org.eclipse.xtext.parsetree.Range;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
+import org.eclipse.xtext.ui.core.editor.model.XtextDocument;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public class XtextDamagerRepairer extends DefaultDamagerRepairer {
+
+ public XtextDamagerRepairer(ITokenScanner scanner) {
+ super(scanner);
+ }
+
+ protected XtextDocument getDocument() {
+ return (XtextDocument) fDocument;
+ }
+
+ @Override
+ public void setDocument(IDocument document) {
+ if (document != null && !(document instanceof XtextDocument))
+ throw new IllegalArgumentException("document is invalid: " + document);
+ super.setDocument(document);
+ }
+
+ @Override
+ public IRegion getDamageRegion(ITypedRegion partition, final DocumentEvent e, boolean documentPartitioningChanged) {
+ if (documentPartitioningChanged)
+ return partition;
+
+ IRegion result = getDocument().readOnly(new UnitOfWork<IRegion>(){
+ private final int offset = e.getOffset();
+ private final int endOffset = offset + e.getLength();
+
+ public IRegion exec(XtextResource resource) throws Exception {
+ AbstractNode node = resource.getParseResult().getRootNode();
+ AbstractNode start = null;
+ AbstractNode end = null;
+ // find latest node that covers the start of the change
+ while(node != null && start == null) {
+ if (node instanceof CompositeNode) {
+ for(AbstractNode child: ((CompositeNode) node).getChildren()) {
+ if (child.getTotalOffset() <= offset && child.getTotalOffset() + child.getTotalLength() >= offset) {
+ node = child;
+ if (node instanceof LeafNode || node.getTotalOffset() == offset)
+ start = node;
+ break;
+ }
+ }
+ } else {
+ throw new IllegalStateException("node is not in expected range but is not a composite.");
+ }
+ }
+ // search up to the first, deepest node, that covers the end
+ node = start;
+ while(node != null && end == null) {
+ if (node.getTotalLength() + node.getTotalOffset() >= endOffset) {
+ while(end == null) {
+ if (node instanceof CompositeNode) {
+ for(int i = ((CompositeNode) node).getChildren().size() - 1; i >= 0; i--) {
+ AbstractNode child = ((CompositeNode) node).getChildren().get(i);
+ if (child.getTotalOffset() + child.getTotalLength() >= endOffset && child.getTotalOffset() <= endOffset) {
+ node = child;
+ if (node instanceof LeafNode || node.getTotalOffset() + node.getTotalLength() == endOffset)
+ end = node;
+ break;
+ }
+ }
+ } else {
+ end = node;
+ }
+ }
+ } else {
+ node = node.getParent();
+ }
+ }
+ // include region with syntax errors
+ int startOffset = start != null ? start.getTotalOffset() : offset;
+ int endOffset = end != null ? end.getTotalOffset() + end.getTotalLength() : this.endOffset;
+ Range range = new Range(startOffset, endOffset);
+ range.mergeAllErrors(resource.getParseResult().getRootNode());
+ // cover the difference between inserted text and removed text
+ return new Region(range.getFromOffset(), range.getToOffset() - range.getFromOffset() + e.getText().length() - e.getLength());
+ }
+ });
+ return result;
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
index 51af8a7..63d5f90 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
@@ -99,20 +99,20 @@ public class XtextEditor extends TextEditor {
// source viewer setup
setSourceViewerConfiguration(sourceViewerConfiguration);
-
+
// NOTE: Outline CANNOT be initialized here, since we do not have access
// to the source viewer yet (it will be created later).
super.init(site, input);
}
-
+
/**
* Set key binding scope. Needed to make F3 work properly.
*/
+ @Override
protected void initializeKeyBindingScopes() {
setKeyBindingScopes(new String[] { "org.eclipse.xtext.ui.core.XtextEditorScope" }); //$NON-NLS-1$
}
-
public IResource getResource() {
Object adapter = getEditorInput().getAdapter(IResource.class);
@@ -161,7 +161,7 @@ public class XtextEditor extends TextEditor {
/**
* @return true if content assist is available
- *
+ *
*/
public boolean isContentAssistAvailable() {
return getSourceViewerConfiguration().getContentAssistant(getSourceViewer()) != null;
@@ -235,7 +235,7 @@ public class XtextEditor extends TextEditor {
}
/**
- *
+ *
*/
private void doExpensiveValidation() {
longRunningChecks.schedule();
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
index 077f63e..bce123f 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
@@ -30,7 +30,7 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
@Inject(optional = true)
private ITokenScanner tokenScanner;
-
+
@Inject
private IHyperlinkDetector detector;
@@ -56,16 +56,14 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
if (tokenScanner != null) {
PresentationReconciler reconciler = (PresentationReconciler) super.getPresentationReconciler(sourceViewer);
- DefaultDamagerRepairer defDR = new DefaultDamagerRepairer(tokenScanner);
+ DefaultDamagerRepairer defDR = new XtextDamagerRepairer(tokenScanner);
reconciler.setRepairer(defDR, IDocument.DEFAULT_CONTENT_TYPE);
reconciler.setDamager(defDR, IDocument.DEFAULT_CONTENT_TYPE);
return reconciler;
}
- else {
- return super.getPresentationReconciler(sourceViewer);
- }
+ return super.getPresentationReconciler(sourceViewer);
}
-
+
@Override
public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
List<IHyperlinkDetector> detectors = new LinkedList<IHyperlinkDetector>();