| author | szarnekow | 2009-03-07 09:45:53 (EST) |
|---|---|---|
| committer | sefftinge | 2009-03-07 09:45:53 (EST) |
| commit | a26a3af393dbecad7102f9b2d21929abead1aea0 (patch) (side-by-side diff) | |
| tree | 770123342bdba4907d16cef453e99c6a881c0921 | |
| parent | 800517df58716acc722b93bfc328be326ce1ac38 (diff) | |
| download | org.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)
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 --- a/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>(); |

