Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project17
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml539
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml16
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project11
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product25
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch37
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml40
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project11
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml51
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jarbin0 -> 4743 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml154
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/.project28
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi26
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF54
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml19
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java47
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java36
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF17
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml11
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties6
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java30
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java28
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java85
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java28
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java49
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF49
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties5
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java52
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java104
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java75
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java453
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java193
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java157
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java32
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java18
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java19
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java15
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java178
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java375
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java535
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java30
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java25
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java34
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java16
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java183
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java49
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project28
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF6
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties4
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF47
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties5
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Storebin0 -> 6148 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java21
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java148
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java41
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java46
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java83
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java31
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java32
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java34
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java20
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/.project33
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF52
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties6
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java18
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java16
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java51
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java30
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java70
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java38
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java19
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java18
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java19
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java19
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project28
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF48
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties6
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi16
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.pngbin0 -> 888 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.pngbin0 -> 405 bytes
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml13
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java101
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java22
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/.project34
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF17
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties10
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore41
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties4
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml17
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore8
-rw-r--r--experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore2
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/.project28
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF50
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/build.properties4
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java401
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java46
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java42
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java56
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java42
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java47
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java33
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java12
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java94
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java133
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java182
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java124
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java731
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java621
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java62
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java105
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java27
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java60
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java595
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java112
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java75
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java80
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java231
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java7
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java41
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java32
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java5
-rw-r--r--experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java10
-rw-r--r--experimental/compensator/org.eclipse.fx.text/.classpath7
-rw-r--r--experimental/compensator/org.eclipse.fx.text/.gitignore1
-rw-r--r--experimental/compensator/org.eclipse.fx.text/.project28
-rw-r--r--experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF46
-rw-r--r--experimental/compensator/org.eclipse.fx.text/build.properties4
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java86
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java135
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java822
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java52
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java42
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java47
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java32
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java53
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java58
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java28
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java38
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java63
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java324
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java119
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java216
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java89
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java125
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java80
-rw-r--r--experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java174
207 files changed, 12452 insertions, 0 deletions
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project
new file mode 100644
index 000000000..2d03c15ec
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.app.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties
new file mode 100644
index 000000000..b045d3976
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml
new file mode 100644
index 000000000..ee1859a16
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.fx.code.compensator.app.feature"
+ label="CodeCompansator Application Feature"
+ version="1.0.0.qualifier"
+ provider-name="BestSolution.at">
+
+ <description url="http://www.efxclipse.org">
+ TODO FILL WITH CONTENT
+ </description>
+
+ <copyright url="http://www.efxclipse.org">
+ TODO FILL WITH CONTENT
+ </copyright>
+
+ <license url="http://www.efxclipse.org">
+ TODO FILL WITH CONTENT
+ </license>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.app"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.keybindings"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.keybindings.e4"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.keybindings.generic"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.core.databinding"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.databinding"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.core.fxml"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.di"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.dialogs"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.javafx"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.osgi"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ fragment="true"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.osgi.util"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.panes"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.controls"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.theme"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.workbench.base"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.workbench.fx"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.workbench.renderers.base"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.workbench.renderers.fx"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.ui.lifecycle"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.ibm.icu"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.annotation"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.inject"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.xml"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.commons.logging"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.commons.lang"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.commands"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.contenttype"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.databinding"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.databinding.observable"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.databinding.property"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.expressions"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.filesystem"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.jobs"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.resources"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.core.runtime"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.commands"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.contexts"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.di"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.di.extensions"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.di"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.model.workbench"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.emf.common"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.emf.databinding"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.emf.ecore"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.emf.ecore.change"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.emf.ecore.xmi"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.app"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.common"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.concurrent"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.ds"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.event"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.launcher"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.preferences"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.registry"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.util"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.osgi"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.osgi.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.equinox.console"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.felix.gogo.command"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.felix.gogo.runtime"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.felix.gogo.shell"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.freeedit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.editor"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.editor.contrib"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.editor.java"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.editor.js"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.editor.xml"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.fx.code.compensator.model"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml
new file mode 100644
index 000000000..6ee292e8f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <name>CodeCompansator - application feature</name>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.feature</artifactId>
+ <packaging>eclipse-feature</packaging>
+
+ <parent>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId>
+ <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+</project> \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project
new file mode 100644
index 000000000..d9bb836db
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.app.product</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product
new file mode 100644
index 000000000..6639e839c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="CodeCompansator" uid="org.eclipse.fx.code.compensator.app.product" id="org.eclipse.fx.code.compensator.app.product" application="org.eclipse.fx.ui.workbench.fx.application" version="1.0.0" useFeatures="true" includeLaunchers="false">
+
+ <configIni use="default">
+ </configIni>
+ <launcherArgs>
+ <programArgs>-nosplash</programArgs>
+ <vmArgs>-Dosgi.framework.extensions=org.eclipse.fx.osgi</vmArgs>
+ </launcherArgs>
+
+ <windowImages/>
+
+ <features>
+ <feature id="org.eclipse.fx.code.compensator.app.feature" version="1.0.0.qualifier"/>
+ </features>
+ <configurations>
+ <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
+ <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="1" />
+ <plugin id="org.eclipse.osgi" autoStart="true" startLevel="-1" />
+ </configurations>
+</product>
+
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch
new file mode 100644
index 000000000..f96da1547
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
+<setAttribute key="additional_plugins"/>
+<booleanAttribute key="append.args" value="true"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="automaticAdd" value="false"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="false"/>
+<booleanAttribute key="clearws" value="true"/>
+<booleanAttribute key="clearwslog" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/org.eclipse.fx.code.compensator.app.product.product"/>
+<booleanAttribute key="default" value="false"/>
+<stringAttribute key="featureDefaultLocation" value="workspace"/>
+<stringAttribute key="featurePluginResolution" value="workspace"/>
+<booleanAttribute key="includeOptional" value="true"/>
+<stringAttribute key="location" value="${workspace_loc}/../runtime-org.eclipse.fx.code.compensator.app.product"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nl ${target.nl} -consoleLog -nosplash"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dosgi.framework.extensions=org.eclipse.fx.osgi"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="org.eclipse.fx.code.compensator.app.product"/>
+<stringAttribute key="productFile" value="/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product"/>
+<setAttribute key="selected_features">
+<setEntry value="org.eclipse.fx.code.compensator.app.feature:default"/>
+</setAttribute>
+<booleanAttribute key="show_selected_only" value="false"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="true"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<booleanAttribute key="useDefaultConfigArea" value="true"/>
+<booleanAttribute key="useProduct" value="true"/>
+<booleanAttribute key="usefeatures" value="false"/>
+</launchConfiguration>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml
new file mode 100644
index 000000000..39b0f0436
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <name>CodeCompansator - application product</name>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.product</artifactId>
+ <packaging>eclipse-repository</packaging>
+
+ <parent>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId>
+ <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-director-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <executions>
+ <execution>
+ <id>materialize-products</id>
+ <goals>
+ <goal>materialize-products</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>archive-products</id>
+ <goals>
+ <goal>archive-products</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project
new file mode 100644
index 000000000..c932070c5
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.app.releng</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml
new file mode 100644
index 000000000..7943919cf
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml
@@ -0,0 +1,51 @@
+<project name="native-build" default="do-deploy" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
+ <property name="eclipse-app-dir" value="../org.eclipse.fx.code.compensator.app.product/target/products/org.eclipse.fx.code.compensator.app.product/noenv/noenv/noenv" />
+
+ <target name="init-fx-tasks">
+ <taskdef name="fxosgilauncher" classpath="org.eclipse.fx.ide.ant.jar" classname="org.eclipse.fx.ide.ant.FXOsgiLaunchTask" />
+ <path id="fxant">
+ <filelist>
+ <file name="${java.home}\..\lib\ant-javafx.jar"/>
+ <file name="${java.home}\lib\ant-jfxrt.jar"/>
+ </filelist>
+ </path>
+ <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
+ uri="javafx:com.sun.javafx.tools.ant"
+ classpathref="fxant"/>
+ </target>
+
+ <target name="do-deploy" depends="init-fx-tasks">
+ <fileset id="equinox-launcher" dir="../org.eclipse.fx.code.compensator.app.product/target/products/org.eclipse.fx.code.compensator.app.product/noenv/noenv/noenv">
+ <filename name="plugins/org.eclipse.equinox.launcher_*.jar"/>
+ </fileset>
+ <fxosgilauncher classpathref="fxant" equinoxlauncherjarref="equinox-launcher"/>
+
+ <fx:resources id="appRes">
+ <fx:fileset dir="." includes="fx-osgi-launch.jar"/>
+ <fx:fileset dir="${eclipse-app-dir}" includes="**/*"/>
+ </fx:resources>
+
+ <fx:application id="fxApplication"
+ name="CodeCompansator"
+ mainClass="org.eclipse.equinox.launcher.Main"
+ toolkit="swing"
+
+ />
+
+ <fx:deploy
+ embedJNLP="false"
+ extension="false"
+ includeDT="false"
+ offlineAllowed="true"
+ outdir="${basedir}/deploy"
+ outfile="fix-ide"
+ nativeBundles="all"
+ updatemode="background"
+ >
+
+ <fx:info title="CodeCompansator" vendor="BestSolution.at"/>
+ <fx:application refid="fxApplication"/>
+ <fx:resources refid="appRes"/>
+ </fx:deploy>
+ </target>
+</project> \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar
new file mode 100644
index 000000000..45ddf0390
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml
new file mode 100644
index 000000000..a28f2417f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <name>CodeCompansator - releng</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <properties>
+ <tycho-version>0.18.0</tycho-version>
+ <junit-version>4.8.1</junit-version>
+ <mockito-version>1.8.4</mockito-version>
+ <platform-version>4.2</platform-version>
+ <efx-version>0.9.0</efx-version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <modules>
+ <module>../org.eclipse.fx.code.compensator.app</module>
+ <module>../org.eclipse.fx.code.compensator.app.feature</module>
+ <module>../org.eclipse.fx.code.compensator.app.product</module>
+ </modules>
+
+ <repositories>
+ <repository>
+ <id>efxclipse-repo</id>
+ <layout>p2</layout>
+ <url>http://download.eclipse.org/efxclipse/runtime-nightly/site</url>
+ </repository>
+ <repository>
+ <id>efxclipse-addons</id>
+ <layout>p2</layout>
+ <url>http://downloads.efxclipse.org/efxclipse.bestsolution.at/p2-repos/runtime/nightly/site/</url>
+ </repository>
+
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>tycho</id>
+ <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <build>
+
+ <!-- build plugins -->
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-maven-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <resolver>p2</resolver>
+ <pomDependencies>consider</pomDependencies>
+ <environments>
+ <environment>
+ <os>noenv</os>
+ <ws>noenv</ws>
+ <arch>noenv</arch>
+ </environment>
+ </environments>
+ </configuration>
+ </plugin>
+ </plugins>
+
+
+ <!-- defines the default settings for the used plugins -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-compiler-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <encoding>UTF-8</encoding>
+ <source>1.7</source>
+ <target>1.7</target>
+ <extraClasspathElements>
+ <extraClasspathElement>
+ <groupId>javafx</groupId>
+ <artifactId>javafx.mvn</artifactId>
+ <version>2.2.0-SNAPSHOT</version>
+ </extraClasspathElement>
+ </extraClasspathElements>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <executions>
+ <execution>
+ <id>plugin-source</id>
+ <goals>
+ <goal>plugin-source</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-packaging-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <archiveSite>true</archiveSite>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${mockito-version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath
new file mode 100644
index 000000000..22f30643c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app/.project
new file mode 100644
index 000000000..dce0294c7
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.app</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi b/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi
new file mode 100644
index 000000000..ed874989b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_fFsNwPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.code.compensator.app" bindingContexts="_fFq_oPG6EeOigcR0oBysUg">
+ <children xsi:type="basic:TrimmedWindow" xmi:id="_xH6dEPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.code.compensator.app.trimmedwindow.0" x="10" y="10" width="800" height="600">
+ <children xsi:type="advanced:PerspectiveStack" xmi:id="_mym9kPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.perspectivestack.0"/>
+ <mainMenu xmi:id="_RTKZcPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.menu.0">
+ <children xsi:type="menu:Menu" xmi:id="_SXdvEPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.menu.1" label="File">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_U7ubkPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handledmenuitem.0" label="Open File ..." command="_NKFrQPNkEeOKm6R57HGa4g"/>
+ </children>
+ </mainMenu>
+ </children>
+ <handlers xmi:id="_FcDokPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handler.0" contributionURI="bundleclass://org.eclipse.fx.code.compensator.app/org.eclipse.fx.code.compensator.app.LoadFile" command="_NKFrQPNkEeOKm6R57HGa4g"/>
+ <handlers xmi:id="_R3Pi0POkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handler.1" contributionURI="bundleclass://org.eclipse.fx.code.compensator.app/org.eclipse.fx.code.compensator.app.OpenFile" command="_VwzOUPOkEeOKm6R57HGa4g"/>
+ <rootContext xmi:id="_fFq_oPG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialog and Windows">
+ <children xmi:id="_fFsNwfG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.window" name="In Windows"/>
+ <children xmi:id="_fFsNwvG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs"/>
+ </rootContext>
+ <commands xmi:id="_NKFrQPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.command.0" commandName="Load File"/>
+ <commands xmi:id="_VwzOUPOkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.command.1" commandName="Open File"/>
+ <addons xmi:id="_fFsNw_G6EeOigcR0oBysUg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
+ <addons xmi:id="_fFsNxPG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
+ <addons xmi:id="_fFsNxfG6EeOigcR0oBysUg" elementId="org.eclipse.fx.ui.keybindings.e4.service" contributionURI="bundleclass://org.eclipse.fx.ui.keybindings.e4/org.eclipse.fx.ui.keybindings.e4.BindingServiceAddon"/>
+ <addons xmi:id="_fFsNxvG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
+ <addons xmi:id="_fFsNx_G6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
+ <addons xmi:id="_fFsNyPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.ui.keybindings.e4.model" contributionURI="bundleclass://org.eclipse.fx.ui.keybindings.e4/org.eclipse.fx.ui.keybindings.e4.BindingProcessingAddon"/>
+ <addons xmi:id="_fFsNyfG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.addons.HandlerProcessingAddon" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon"/>
+</application:Application>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..905971556
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF
@@ -0,0 +1,54 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: My Sample App
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.app;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.fx.ui.workbench.fx,
+ org.eclipse.e4.ui.model.workbench,
+ org.eclipse.e4.core.services,
+ org.eclipse.e4.core.di,
+ org.eclipse.e4.ui.di,
+ org.eclipse.e4.core.di.extensions,
+ org.eclipse.fx.ui.theme,
+ org.eclipse.fx.ui.di,
+ org.eclipse.e4.core.contexts,
+ org.eclipse.fx.core.databinding,
+ org.eclipse.fx.ui.databinding,
+ org.eclipse.core.databinding,
+ org.eclipse.core.databinding.observable,
+ org.eclipse.core.databinding.property,
+ org.eclipse.e4.ui.workbench,
+ org.eclipse.e4.ui.services,
+ javax.inject,
+ org.eclipse.fx.code.compensator.model;bundle-version="0.1.0",
+ org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0"
+Import-Package: javafx.animation;version="2.0.0",
+ javafx.application;version="2.0.0",
+ javafx.beans;version="2.0.0",
+ javafx.beans.binding;version="2.0.0",
+ javafx.beans.property;version="2.0.0",
+ javafx.beans.value;version="2.0.0",
+ javafx.collections;version="2.0.0",
+ javafx.concurrent;version="2.0.0",
+ javafx.event;version="2.0.0",
+ javafx.fxml;version="2.0.0",
+ javafx.geometry;version="2.0.0",
+ javafx.scene;version="2.0.0",
+ javafx.scene.chart;version="2.0.0",
+ javafx.scene.control;version="2.0.0",
+ javafx.scene.control.cell;version="2.0.0",
+ javafx.scene.effect;version="2.0.0",
+ javafx.scene.image;version="2.0.0",
+ javafx.scene.input;version="2.0.0",
+ javafx.scene.layout;version="2.0.0",
+ javafx.scene.media;version="2.0.0",
+ javafx.scene.paint;version="2.0.0",
+ javafx.scene.shape;version="2.0.0",
+ javafx.scene.text;version="2.0.0",
+ javafx.scene.transform;version="2.0.0",
+ javafx.scene.web;version="2.0.0",
+ javafx.stage;version="2.0.0",
+ javafx.util;version="2.0.0",
+ javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore
new file mode 100644
index 000000000..cf1db2eed
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore
@@ -0,0 +1 @@
+/org/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties
new file mode 100644
index 000000000..db411bb01
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties
@@ -0,0 +1,7 @@
+bin.includes = .,\
+ META-INF/,\
+ plugin.xml,\
+css/,\
+ Application.e4xmi
+
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css b/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css
new file mode 100644
index 000000000..a38730ef4
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css
@@ -0,0 +1 @@
+/* Main CSS-File */ \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml
new file mode 100644
index 000000000..ba2e02bc0
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+<extension id="product" point="org.eclipse.core.runtime.products">
+ <product name="CodeCompansator" application="org.eclipse.fx.ui.workbench.fx.application" >
+ <property name="appName" value="CodeCompansator" />
+
+ <property name="applicationXMI" value="org.eclipse.fx.code.compensator.app/Application.e4xmi" />
+
+ <property name="cssTheme" value="theme.default" />
+
+ </product>
+
+</extension>
+<extension point="org.eclipse.fx.ui.theme">
+ <theme id="theme.default" basestylesheet="css/default.css" />
+
+</extension>
+</plugin>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml
new file mode 100644
index 000000000..e5b6605fd
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <name>CodeCompansator - application bundle</name>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app</artifactId>
+ <packaging>eclipse-plugin</packaging>
+
+ <parent>
+ <groupId>org.eclipse.fx.code.compensator</groupId>
+ <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId>
+ <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>META-INF/</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java
new file mode 100644
index 000000000..1648a33e2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.app;
+
+import java.util.Optional;
+
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.fx.code.compensator.model.workbench.Workbench;
+import org.eclipse.fx.code.compensator.model.workbench.WorkbenchFactory;
+
+
+public class LoadFile {
+ @Execute
+ public void execute(Stage parent, IEventBroker eventBroker, Workbench wb) {
+ FileChooser chooser = new FileChooser();
+ Optional.ofNullable(chooser.showOpenMultipleDialog(parent)).ifPresent((l) ->
+ {
+ l.forEach((f) -> {
+ try {
+ System.err.println("ATTACHING: " + f);
+ org.eclipse.fx.code.compensator.model.workbench.File wf = WorkbenchFactory.eINSTANCE.createFile();
+ wf.setUrl(f.toURI().toURL().toExternalForm());
+ wb.getResources().add(wf);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ });
+
+ }
+ );
+
+ }
+
+} \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java
new file mode 100644
index 000000000..59053c82e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.app;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.fx.code.compensator.editor.TextEditor;
+import org.eclipse.fx.code.compensator.model.workbench.File;
+
+public class OpenFile {
+ @Execute
+ public void openFile(MPerspective perspective, EModelService service, File file, EPartService partService) {
+ MPartStack element = (MPartStack) service.find("org.eclipse.fx.code.compensator.freeedit.partstack.1", perspective);
+
+ MPart p = service.createModelElement(MPart.class);
+ p.setContributionURI("bundleclass://org.eclipse.fx.code.compensator.editor/org.eclipse.fx.code.compensator.editor.TextEditor");
+ p.getPersistedState().put(TextEditor.DOCUMENT_URL, file.getUrl());
+ p.setLabel(URI.createURI(file.getUrl()).lastSegment());
+ element.getChildren().add(p);
+ partService.showPart(p, PartState.ACTIVATE);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project
new file mode 100644
index 000000000..546743442
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.editor.contrib</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..17e10d4a1
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Contrib
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.contrib
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="1.3.100",
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.1.0",
+ org.eclipse.text;bundle-version="3.5.300",
+ org.eclipse.fx.text;bundle-version="1.0.0",
+ org.eclipse.fx.text.ui;bundle-version="1.0.0",
+ org.eclipse.fx.code.compensator.model;bundle-version="0.1.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.10.0"
+Service-Component: OSGI-INF/services/servicecollector.xml,OSGI-INF/services/inputcf.xml,OSGI-INF/services/documentcf.xml,OSGI-INF/services/partitionercf.xml,OSGI-INF/services/sourceconfigcf.xml,
+ OSGI-INF/services/workbenchmodelcf.xml
+Bundle-ActivationPolicy: lazy
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml
new file mode 100644
index 000000000..a42bee538
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.documentcf">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.DocumentContextFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.jface.text.IDocument"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml
new file mode 100644
index 000000000..1129eb4cd
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.inputcf">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.InputContextFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.fx.code.compensator.editor.Input"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml
new file mode 100644
index 000000000..4aba18fac
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.partitionercf">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.PartitionerContextFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.jface.text.IDocumentPartitioner"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml
new file mode 100644
index 000000000..008d5f27c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.ServiceCollector"/>
+ <service>
+ <provide interface="org.eclipse.fx.code.compensator.editor.contrib.ServiceCollector"/>
+ </service>
+ <reference bind="addInputFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.InputFactory" name="InputFactory" policy="dynamic" unbind="removeInputFactory"/>
+ <reference bind="addDocumentFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.DocumentFactory" name="DocumentFactory" policy="dynamic" unbind="removeDocumentFactory"/>
+ <reference bind="addPartitionerFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory" name="PartitionerFactory" policy="dynamic" unbind="removePartitionerFactory"/>
+ <reference bind="addSourceViewerConfigurationFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory" name="SourceViewerConfigurationFactory" policy="dynamic" unbind="removeSourceViewerConfigurationFactory"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml
new file mode 100644
index 000000000..807b985d6
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.sourceconfig">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.SourceViewerConfigurationContextFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.jface.text.source.SourceViewerConfiguration"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml
new file mode 100644
index 000000000..16717f30e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.workbenchmodel">
+ <implementation class="org.eclipse.fx.code.compensator.editor.contrib.WorkbenchModelContextFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.fx.code.compensator.model.workbench.Workbench"/>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties
new file mode 100644
index 000000000..d722a551a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties
@@ -0,0 +1,6 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/,\
+ OSGI-INF/services/workbenchmodelcf.xml
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java
new file mode 100644
index 000000000..142ff5172
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.IDocument;
+
+public class DocumentContextFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ IDocument document = (IDocument) context.get("localDoc");
+ if( document == null ) {
+ Input<?> input = context.get(Input.class);
+ ServiceCollector collector = context.get(ServiceCollector.class);
+ document = collector.createDocument(input);
+ context.set("localDoc", document);
+ }
+ return document;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java
new file mode 100644
index 000000000..10d513bcb
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.TextEditor;
+
+public class InputContextFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ Input<?> input = (Input<?>) context.get("localInput");
+ if( input == null ) {
+ MPart part = context.get(MPart.class);
+ String url = part.getPersistedState().get(TextEditor.DOCUMENT_URL);
+
+ ServiceCollector collector = context.get(ServiceCollector.class);
+ input = collector.createInput(url);
+ context.set("localInput", input);
+ }
+ return input;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java
new file mode 100644
index 000000000..6abdf6434
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+public class PartitionerContextFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ IDocumentPartitioner partitioner = (IDocumentPartitioner) context.get("localPartitioner");
+ if( partitioner == null ) {
+ partitioner = context.get(ServiceCollector.class).createPartitioner(context.get(Input.class));
+ context.set("localPartitioner", partitioner);
+ }
+ return partitioner;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java
new file mode 100644
index 000000000..8bc2f197d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.services.DocumentFactory;
+import org.eclipse.fx.code.compensator.editor.services.InputFactory;
+import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory;
+import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class ServiceCollector {
+ private List<InputFactory> inputProviderList = new ArrayList<>();
+ private List<DocumentFactory> documentProvider = new ArrayList<>();
+ private List<PartitionerFactory> partitionerProvider = new ArrayList<>();
+ private List<SourceViewerConfigurationFactory> configurationProvider = new ArrayList<>();
+
+ public void addInputFactory(InputFactory provider) {
+ inputProviderList.add(provider);
+ }
+
+ public void removeInputFactory(InputFactory provider) {
+ inputProviderList.remove(provider);
+ }
+
+ public void addDocumentFactory(DocumentFactory provider) {
+ documentProvider.add(provider);
+ }
+
+ public void removeDocumentFactory(DocumentFactory provider) {
+ documentProvider.remove(provider);
+ }
+
+ public void addPartitionerFactory(PartitionerFactory provider) {
+ partitionerProvider.add(provider);
+ }
+
+ public void removePartitionerFactory(PartitionerFactory provider) {
+ partitionerProvider.remove(provider);
+ }
+
+ public void addSourceViewerConfigurationFactory(SourceViewerConfigurationFactory provider) {
+ configurationProvider.add(provider);
+ }
+
+ public void removeSourceViewerConfigurationFactory(SourceViewerConfigurationFactory provider) {
+ configurationProvider.remove(provider);
+ }
+
+ public <O> Input<O> createInput(String url) {
+ System.err.println("PROVIDER: " + inputProviderList);
+ Optional<Input<O>> map = inputProviderList.stream().filter((p) -> p.applies(url)).findFirst().map((p) -> p.createInput(url));
+ return map.get();
+ }
+
+ public IDocument createDocument(Input<?> input) {
+ Optional<IDocument> map = documentProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createDocument(input));
+ return map.get();
+ }
+
+ public IDocumentPartitioner createPartitioner(Input<?> input) {
+ System.err.println("PARTITIONER: " + partitionerProvider);
+ Optional<IDocumentPartitioner> map = partitionerProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createPartitioner(input));
+ return map.get();
+ }
+
+ public SourceViewerConfiguration createConfiguration(Input<?> input) {
+ Optional<SourceViewerConfiguration> map = configurationProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createConfiguration(input));
+ return map.get();
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java
new file mode 100644
index 000000000..3cb5617a7
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class SourceViewerConfigurationContextFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ SourceViewerConfiguration config = (SourceViewerConfiguration) context.get("localSourceConfig");
+ if( config == null ) {
+ config = context.get(ServiceCollector.class).createConfiguration(context.get(Input.class));
+ context.set("localSourceConfig", config);
+ }
+ return config;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java
new file mode 100644
index 000000000..d908b209d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.contrib;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.fx.code.compensator.model.workbench.Workbench;
+import org.eclipse.fx.code.compensator.model.workbench.WorkbenchFactory;
+
+public class WorkbenchModelContextFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ context = context.get(MApplication.class).getContext();
+ Workbench wb = (Workbench) context.get("LocalWorkbench");
+ if( wb == null ) {
+ File f = new File(System.getProperty("user.home")+"/.compensator/workbench.xmi");
+ if( f.exists() ) {
+ try {
+ Resource r = new XMIResourceImpl(URI.createFileURI(f.getAbsolutePath()));
+ r.load(null);
+ wb = (Workbench) r.getContents().get(0);
+ context.set("LocalWorkbench", wb);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } else {
+ wb = WorkbenchFactory.eINSTANCE.createWorkbench();
+ context.set("LocalWorkbench", wb);
+ }
+ }
+ return wb;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project
new file mode 100644
index 000000000..91ed6a18a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.editor.java</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..24191f667
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF
@@ -0,0 +1,49 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Java
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.java
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.text;bundle-version="3.5.300",
+ org.eclipse.fx.text;bundle-version="1.0.0",
+ org.eclipse.equinox.common;bundle-version="3.6.200",
+ org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0",
+ org.eclipse.fx.text.ui;bundle-version="1.0.0",
+ org.eclipse.fx.ui.controls;bundle-version="1.0.0"
+Service-Component: OSGI-INF/services/javacomponent.xml
+Bundle-ActivationPolicy: lazy
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0"
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml
new file mode 100644
index 000000000..f2b4bbd3e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.java.javacomponent">
+ <implementation class="org.eclipse.fx.code.compensator.editor.java.JavaComponent"/>
+ <service>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory"/>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory"/>
+ </service>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties
new file mode 100644
index 000000000..6de0e8c19
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/services/javacomponent.xml
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java
new file mode 100644
index 000000000..9e78beef7
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java;
+
+import org.eclipse.fx.code.compensator.editor.ContentTypeProvider;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory;
+import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory;
+import org.eclipse.jdt.internal.ui.text.FastJavaPartitionScanner;
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class JavaComponent implements PartitionerFactory, SourceViewerConfigurationFactory {
+ private final static String[] LEGAL_CONTENT_TYPES= new String[] {
+ IJavaPartitions.JAVA_DOC,
+ IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
+ IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
+ IJavaPartitions.JAVA_STRING,
+ IJavaPartitions.JAVA_CHARACTER
+ };
+ @Override
+ public SourceViewerConfiguration createConfiguration(Input<?> input) {
+ return new JavaSourceConfiguration();
+ }
+
+ @Override
+ public boolean applies(Input<?> input) {
+ if( input instanceof ContentTypeProvider ) {
+ String contentType = ((ContentTypeProvider) input).getContentType();
+ return ContentTypeProvider.JAVA.equals(contentType);
+ }
+ return false;
+ }
+
+ @Override
+ public IDocumentPartitioner createPartitioner(Input<?> input) {
+ return new FastPartitioner(
+ new FastJavaPartitionScanner(),
+ LEGAL_CONTENT_TYPES);
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java
new file mode 100644
index 000000000..f759b0bf3
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java;
+
+import org.eclipse.fx.code.compensator.editor.java.scanner.JavaCodeScanner;
+import org.eclipse.fx.code.compensator.editor.java.scanner.JavaCommentScanner;
+import org.eclipse.fx.code.compensator.editor.java.scanner.JavaDocScanner;
+import org.eclipse.fx.code.compensator.editor.java.scanner.SingleTokenJavaScanner;
+import org.eclipse.jdt.ui.text.IJavaColorConstants;
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class JavaSourceConfiguration extends SourceViewerConfiguration {
+
+ private JavaCodeScanner fCodeScanner;
+ private JavaDocScanner fJavaDocScanner;
+ private JavaCommentScanner fMultilineCommentScanner;
+ private JavaCommentScanner fSinglelineCommentScanner;
+ private SingleTokenJavaScanner fStringScanner;
+
+ public JavaSourceConfiguration() {
+ initializeScanners();
+ }
+
+ private void initializeScanners() {
+ fCodeScanner= new JavaCodeScanner();
+ fMultilineCommentScanner= new JavaCommentScanner(IJavaColorConstants.JAVA_MULTI_LINE_COMMENT);
+ fSinglelineCommentScanner= new JavaCommentScanner(IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT);
+ fStringScanner= new SingleTokenJavaScanner(IJavaColorConstants.JAVA_STRING);
+ fJavaDocScanner= new JavaDocScanner();
+ }
+
+ @Override
+ public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+ return IJavaPartitions.JAVA_PARTITIONING;
+ }
+
+ @Override
+ public IPresentationReconciler getPresentationReconciler(
+ ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler= new /*JavaPresentationReconciler*/ PresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(getCodeScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ dr= new DefaultDamagerRepairer(getJavaDocScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_DOC);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_DOC);
+
+ dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+
+ dr= new DefaultDamagerRepairer(getSinglelineCommentScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+
+ dr= new DefaultDamagerRepairer(getStringScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_STRING);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_STRING);
+
+ dr= new DefaultDamagerRepairer(getStringScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_CHARACTER);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_CHARACTER);
+
+ return reconciler;
+ }
+
+ private ITokenScanner getStringScanner() {
+ return fStringScanner;
+ }
+
+ private ITokenScanner getSinglelineCommentScanner() {
+ return fSinglelineCommentScanner;
+ }
+
+ private ITokenScanner getMultilineCommentScanner() {
+ return fMultilineCommentScanner;
+ }
+
+ private ITokenScanner getJavaDocScanner() {
+ return fJavaDocScanner;
+ }
+
+ private ITokenScanner getCodeScanner() {
+ return fCodeScanner;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java
new file mode 100644
index 000000000..a9c4616d4
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java.scanner;
+
+import java.util.List;
+
+import javafx.scene.paint.Color;
+
+import org.eclipse.jdt.ui.text.IJavaColorConstants;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.Token;
+
+public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner {
+
+ public AbstractJavaScanner() {
+ }
+
+ public final void initialize() {
+ initializeRules();
+ }
+
+ abstract protected List<IRule> createRules();
+
+ private void initializeRules() {
+ List<IRule> rules= createRules();
+ if (rules != null) {
+ IRule[] result= new IRule[rules.size()];
+ rules.toArray(result);
+ setRules(result);
+ }
+ }
+
+ protected Token getToken(String key) {
+ switch (key) {
+ case IJavaColorConstants.JAVA_STRING:
+ return new Token(new TextAttribute(Color.rgb(42, 0, 255)));
+ case IJavaColorConstants.JAVA_DEFAULT:
+ return new Token(new TextAttribute(Color.rgb(0,0,0)));
+ case JavaCodeScanner.ANNOTATION_COLOR_KEY:
+ return new Token(new TextAttribute(Color.rgb(200, 200, 200)));
+ case IJavaColorConstants.JAVA_KEYWORD:
+ return new Token(new TextAttribute(Color.rgb(127, 0, 85)));
+ case IJavaColorConstants.JAVA_OPERATOR:
+ return new Token(new TextAttribute(Color.rgb(0, 0, 0)));
+ case IJavaColorConstants.JAVA_BRACKET:
+ return new Token(new TextAttribute(Color.rgb(0, 0, 0)));
+ case IJavaColorConstants.JAVA_KEYWORD_RETURN:
+ return new Token(new TextAttribute(Color.rgb(127, 0, 85)));
+ case IJavaColorConstants.TASK_TAG:
+ return new Token(new TextAttribute(Color.rgb(127, 159, 191)));
+ case IJavaColorConstants.JAVADOC_LINK:
+ return new Token(new TextAttribute(Color.rgb(63, 63, 191)));
+ case IJavaColorConstants.JAVADOC_DEFAULT:
+ return new Token(new TextAttribute(Color.rgb(63, 95, 191)));
+ case IJavaColorConstants.JAVA_MULTI_LINE_COMMENT:
+ return new Token(new TextAttribute(Color.rgb(63, 127, 95)));
+ case IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT:
+ return new Token(new TextAttribute(Color.rgb(63, 127, 95)));
+ case IJavaColorConstants.JAVADOC_TAG:
+ return new Token(new TextAttribute(Color.rgb(127, 127, 159)));
+ default:
+ throw new IllegalStateException("Unknown key '"+ key+"'");
+ }
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java
new file mode 100644
index 000000000..5741ba216
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java
@@ -0,0 +1,453 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java.scanner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings;
+import org.eclipse.jdt.internal.ui.text.CombinedWordRule;
+import org.eclipse.jdt.internal.ui.text.ISourceVersionDependent;
+import org.eclipse.jdt.internal.ui.text.JavaWhitespaceDetector;
+import org.eclipse.jdt.internal.ui.text.JavaWordDetector;
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.text.IJavaColorConstants;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class JavaCodeScanner extends AbstractJavaScanner {
+
+ private static final String INTERFACE= "interface"; //$NON-NLS-1$
+ private static final String RETURN= "return"; //$NON-NLS-1$
+
+ private static final String ANNOTATION_BASE_KEY= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + SemanticHighlightings.ANNOTATION;
+ static final String ANNOTATION_COLOR_KEY= ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
+
+ private List<ISourceVersionDependent> fVersionDependentRules= new ArrayList<ISourceVersionDependent>(3);
+
+ private static String[] fgJava14Keywords= { "assert" }; //$NON-NLS-1$
+ private static String[] fgJava15Keywords= { "enum" }; //$NON-NLS-1$
+
+ static String[] fgKeywords= {
+ "abstract", //$NON-NLS-1$
+ "break", //$NON-NLS-1$
+ "case", "catch", "class", "const", "continue", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "default", "do", //$NON-NLS-2$ //$NON-NLS-1$
+ "else", "extends", //$NON-NLS-2$ //$NON-NLS-1$
+ "final", "finally", "for", //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "goto", //$NON-NLS-1$
+ "if", "implements", "import", "instanceof", "interface", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "native", "new", //$NON-NLS-2$ //$NON-NLS-1$
+ "package", "private", "protected", "public", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "static", "super", "switch", "synchronized", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "this", "throw", "throws", "transient", "try", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "volatile", //$NON-NLS-1$
+ "while" //$NON-NLS-1$
+ };
+
+ private static String[] fgTypes= { "void", "boolean", "char", "byte", "short", "strictfp", "int", "long", "float", "double" }; //$NON-NLS-1$ //$NON-NLS-5$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-2$
+ private static String[] fgConstants= { "false", "null", "true" }; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ public JavaCodeScanner() {
+ initialize();
+ }
+
+// @Override
+// public IToken nextToken() {
+// IToken nextToken = super.nextToken();
+// System.err.println("FIND TOKEN: " + nextToken.getData());
+// return nextToken;
+// }
+
+ @Override
+ protected List<IRule> createRules() {
+ List<IRule> rules= new ArrayList<IRule>();
+
+ Token token= getToken(IJavaColorConstants.JAVA_STRING);
+ rules.add(new SingleLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+ Token defaultToken= getToken(IJavaColorConstants.JAVA_DEFAULT);
+
+ // Add generic whitespace rule.
+ rules.add(new WhitespaceRule(new JavaWhitespaceDetector(), defaultToken));
+
+// String version= getPreferenceStore().getString(SOURCE_VERSION);
+ String version = JavaCore.VERSION_1_8;
+
+ token= getToken(ANNOTATION_COLOR_KEY);
+ AnnotationRule atInterfaceRule= new AnnotationRule(getToken(IJavaColorConstants.JAVA_KEYWORD), token, JavaCore.VERSION_1_5, version);
+ rules.add(atInterfaceRule);
+ fVersionDependentRules.add(atInterfaceRule);
+
+ // Add word rule for new keywords, see bug 4077
+ JavaWordDetector wordDetector= new JavaWordDetector();
+ CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, defaultToken);
+
+ VersionedWordMatcher j14Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_4, version);
+
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgJava14Keywords.length; i++)
+ j14Matcher.addWord(fgJava14Keywords[i], token);
+
+ combinedWordRule.addWordMatcher(j14Matcher);
+ fVersionDependentRules.add(j14Matcher);
+
+ VersionedWordMatcher j15Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_5, version);
+
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgJava15Keywords.length; i++)
+ j15Matcher.addWord(fgJava15Keywords[i], token);
+
+ combinedWordRule.addWordMatcher(j15Matcher);
+ fVersionDependentRules.add(j15Matcher);
+
+ // Add rule for operators
+ token= getToken(IJavaColorConstants.JAVA_OPERATOR);
+ rules.add(new OperatorRule(token));
+
+ // Add rule for brackets
+ token= getToken(IJavaColorConstants.JAVA_BRACKET);
+ rules.add(new BracketRule(token));
+
+ // Add word rule for keyword 'return'.
+ CombinedWordRule.WordMatcher returnWordRule= new CombinedWordRule.WordMatcher();
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD_RETURN);
+ returnWordRule.addWord(RETURN, token);
+ combinedWordRule.addWordMatcher(returnWordRule);
+
+ // Add word rule for keywords, types, and constants.
+ CombinedWordRule.WordMatcher wordRule= new CombinedWordRule.WordMatcher();
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgKeywords.length; i++)
+ wordRule.addWord(fgKeywords[i], token);
+ for (int i=0; i<fgTypes.length; i++)
+ wordRule.addWord(fgTypes[i], token);
+ for (int i=0; i<fgConstants.length; i++)
+ wordRule.addWord(fgConstants[i], token);
+
+ combinedWordRule.addWordMatcher(wordRule);
+
+ rules.add(combinedWordRule);
+
+ setDefaultReturnToken(defaultToken);
+ return rules;
+ }
+
+ /**
+ * An annotation rule matches the '@' symbol, any following whitespace and
+ * optionally a following <code>interface</code> keyword.
+ *
+ * It does not match if there is a comment between the '@' symbol and
+ * the identifier. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=82452
+ *
+ * @since 3.1
+ */
+ private static class AnnotationRule implements IRule, ISourceVersionDependent {
+ /**
+ * A resettable scanner supports marking a position in a scanner and
+ * unreading back to the marked position.
+ */
+ private static final class ResettableScanner implements ICharacterScanner {
+ private final ICharacterScanner fDelegate;
+ private int fReadCount;
+
+ /**
+ * Creates a new resettable scanner that will forward calls
+ * to <code>scanner</code>, but store a marked position.
+ *
+ * @param scanner the delegate scanner
+ */
+ public ResettableScanner(final ICharacterScanner scanner) {
+ Assert.isNotNull(scanner);
+ fDelegate= scanner;
+ mark();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#getColumn()
+ */
+ public int getColumn() {
+ return fDelegate.getColumn();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#getLegalLineDelimiters()
+ */
+ public char[][] getLegalLineDelimiters() {
+ return fDelegate.getLegalLineDelimiters();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#read()
+ */
+ public int read() {
+ int ch= fDelegate.read();
+ if (ch != ICharacterScanner.EOF)
+ fReadCount++;
+ return ch;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#unread()
+ */
+ public void unread() {
+ if (fReadCount > 0)
+ fReadCount--;
+ fDelegate.unread();
+ }
+
+ /**
+ * Marks an offset in the scanned content.
+ */
+ public void mark() {
+ fReadCount= 0;
+ }
+
+ /**
+ * Resets the scanner to the marked position.
+ */
+ public void reset() {
+ while (fReadCount > 0)
+ unread();
+
+ while (fReadCount < 0)
+ read();
+ }
+ }
+
+ private final IWhitespaceDetector fWhitespaceDetector= new JavaWhitespaceDetector();
+ private final IWordDetector fWordDetector= new JavaWordDetector();
+ private final IToken fInterfaceToken;
+ private final IToken fAtToken;
+ private final String fVersion;
+ private boolean fIsVersionMatch;
+
+ /**
+ * Creates a new rule.
+ *
+ * @param interfaceToken the token to return if
+ * <code>'@\s*interface'</code> is matched
+ * @param atToken the token to return if <code>'@'</code>
+ * is matched, but not <code>'@\s*interface'</code>
+ * @param version the lowest <code>JavaCore.COMPILER_SOURCE</code>
+ * version that this rule is enabled
+ * @param currentVersion the current
+ * <code>JavaCore.COMPILER_SOURCE</code> version
+ */
+ public AnnotationRule(IToken interfaceToken, Token atToken, String version, String currentVersion) {
+ fInterfaceToken= interfaceToken;
+ fAtToken= atToken;
+ fVersion= version;
+ setSourceVersion(currentVersion);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ if (!fIsVersionMatch)
+ return Token.UNDEFINED;
+
+ ResettableScanner resettable= new ResettableScanner(scanner);
+ if (resettable.read() == '@')
+ return readAnnotation(resettable);
+
+ resettable.reset();
+ return Token.UNDEFINED;
+ }
+
+ private IToken readAnnotation(ResettableScanner scanner) {
+ scanner.mark();
+ skipWhitespace(scanner);
+ if (readInterface(scanner)) {
+ return fInterfaceToken;
+ } else {
+ scanner.reset();
+ return fAtToken;
+ }
+ }
+
+ private boolean readInterface(ICharacterScanner scanner) {
+ int ch= scanner.read();
+ int i= 0;
+ while (i < INTERFACE.length() && INTERFACE.charAt(i) == ch) {
+ i++;
+ ch= scanner.read();
+ }
+ if (i < INTERFACE.length())
+ return false;
+
+ if (fWordDetector.isWordPart((char) ch))
+ return false;
+
+ if (ch != ICharacterScanner.EOF)
+ scanner.unread();
+
+ return true;
+ }
+
+ private boolean skipWhitespace(ICharacterScanner scanner) {
+ while (fWhitespaceDetector.isWhitespace((char) scanner.read())) {
+ // do nothing
+ }
+
+ scanner.unread();
+ return true;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+ */
+ public void setSourceVersion(String version) {
+ fIsVersionMatch= fVersion.compareTo(version) <= 0;
+ }
+
+ }
+
+ private static class VersionedWordMatcher extends CombinedWordRule.WordMatcher implements ISourceVersionDependent {
+
+ private final IToken fDefaultToken;
+ private final String fVersion;
+ private boolean fIsVersionMatch;
+
+ public VersionedWordMatcher(IToken defaultToken, String version, String currentVersion) {
+ fDefaultToken= defaultToken;
+ fVersion= version;
+ setSourceVersion(currentVersion);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+ */
+ public void setSourceVersion(String version) {
+ fIsVersionMatch= fVersion.compareTo(version) <= 0;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+ */
+ @Override
+ public IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+ IToken token= super.evaluate(scanner, word);
+
+ if (fIsVersionMatch || token.isUndefined())
+ return token;
+
+ return fDefaultToken;
+ }
+ }
+
+ private static final class OperatorRule implements IRule {
+
+ /** Java operators */
+ private final char[] JAVA_OPERATORS= { ';', '.', '=', '/', '\\', '+', '-', '*', '<', '>', ':', '?', '!', ',', '|', '&', '^', '%', '~'};
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new operator rule.
+ *
+ * @param token Token to use for this rule
+ */
+ public OperatorRule(IToken token) {
+ fToken= token;
+ }
+
+ /**
+ * Is this character an operator character?
+ *
+ * @param character Character to determine whether it is an operator character
+ * @return <code>true</code> iff the character is an operator, <code>false</code> otherwise.
+ */
+ public boolean isOperator(char character) {
+ for (int index= 0; index < JAVA_OPERATORS.length; index++) {
+ if (JAVA_OPERATORS[index] == character)
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+
+ int character= scanner.read();
+ if (isOperator((char) character)) {
+ do {
+ character= scanner.read();
+ } while (isOperator((char) character));
+ scanner.unread();
+ return fToken;
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+ }
+
+ private static final class BracketRule implements IRule {
+
+ /** Java brackets */
+ private final char[] JAVA_BRACKETS= { '(', ')', '{', '}', '[', ']' };
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new bracket rule.
+ *
+ * @param token Token to use for this rule
+ */
+ public BracketRule(IToken token) {
+ fToken= token;
+ }
+
+ /**
+ * Is this character a bracket character?
+ *
+ * @param character Character to determine whether it is a bracket character
+ * @return <code>true</code> iff the character is a bracket, <code>false</code> otherwise.
+ */
+ public boolean isBracket(char character) {
+ for (int index= 0; index < JAVA_BRACKETS.length; index++) {
+ if (JAVA_BRACKETS[index] == character)
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+
+ int character= scanner.read();
+ if (isBracket((char) character)) {
+ do {
+ character= scanner.read();
+ } while (isBracket((char) character));
+ scanner.unread();
+ return fToken;
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java
new file mode 100644
index 000000000..61b5bc0a2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java.scanner;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.internal.ui.text.CombinedWordRule;
+import org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer;
+import org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher;
+import org.eclipse.jdt.ui.text.IJavaColorConstants;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+
+public class JavaCommentScanner extends AbstractJavaScanner {
+ protected static final String TASK_TAG= IJavaColorConstants.TASK_TAG;
+ private TaskTagMatcher fTaskTagMatcher;
+ private String fDefaultTokenProperty;
+// private String[] fTokenProperties;
+
+ public JavaCommentScanner(String defaultTokenProperty) {
+ this(defaultTokenProperty, new String[] { defaultTokenProperty, TASK_TAG });
+ }
+
+ public JavaCommentScanner(String defaultTokenProperty, String[] tokenProperties) {
+ fDefaultTokenProperty= defaultTokenProperty;
+// fTokenProperties= tokenProperties;
+ initialize();
+ }
+
+ @Override
+ protected List<IRule> createRules() {
+ List<IRule> list= new ArrayList<IRule>();
+ Token defaultToken= getToken(fDefaultTokenProperty);
+
+ List<WordMatcher> matchers= createMatchers();
+ if (matchers.size() > 0) {
+ CombinedWordRule combinedWordRule= new CombinedWordRule(new AtJavaIdentifierDetector(), defaultToken);
+ for (int i= 0, n= matchers.size(); i < n; i++)
+ combinedWordRule.addWordMatcher(matchers.get(i));
+ list.add(combinedWordRule);
+ }
+
+ setDefaultReturnToken(defaultToken);
+
+ return list;
+ }
+
+ protected List<WordMatcher> createMatchers() {
+ List<WordMatcher> list= new ArrayList<WordMatcher>();
+
+ // Add rule for Task Tags.
+ boolean isCaseSensitive= true;
+ String tasks= "TODO";
+// if (getPreferenceStore().contains(COMPILER_TASK_TAGS)) {
+// tasks= getPreferenceStore().getString(COMPILER_TASK_TAGS);
+// isCaseSensitive= ENABLED.equals(getPreferenceStore().getString(COMPILER_TASK_CASE_SENSITIVE));
+// } else if (fCorePreferenceStore != null) {
+// tasks= fCorePreferenceStore.getString(COMPILER_TASK_TAGS);
+// isCaseSensitive= ENABLED.equals(fCorePreferenceStore.getString(COMPILER_TASK_CASE_SENSITIVE));
+// }
+ if (tasks != null) {
+ fTaskTagMatcher= new TaskTagMatcher(getToken(TASK_TAG));
+ fTaskTagMatcher.addTaskTags(tasks);
+ fTaskTagMatcher.setCaseSensitive(isCaseSensitive);
+ list.add(fTaskTagMatcher);
+ }
+
+ return list;
+ }
+
+ private class TaskTagMatcher extends CombinedWordRule.WordMatcher {
+
+ private IToken fToken;
+ /**
+ * Uppercase words
+ * @since 3.0
+ */
+ private Map<CharacterBuffer, IToken> fUppercaseWords= new HashMap<CharacterBuffer, IToken>();
+ /**
+ * <code>true</code> if task tag detection is case-sensitive.
+ * @since 3.0
+ */
+ private boolean fCaseSensitive= true;
+ /**
+ * Buffer for uppercase word
+ * @since 3.0
+ */
+ private CombinedWordRule.CharacterBuffer fBuffer= new CombinedWordRule.CharacterBuffer(16);
+
+ public TaskTagMatcher(IToken token) {
+ fToken= token;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#clearWords()
+ * @since 3.0
+ */
+ @Override
+ public synchronized void clearWords() {
+ super.clearWords();
+ fUppercaseWords.clear();
+ }
+
+ public synchronized void addTaskTags(String value) {
+ String[] tasks= split(value, ","); //$NON-NLS-1$
+ for (int i= 0; i < tasks.length; i++) {
+ if (tasks[i].length() > 0) {
+ addWord(tasks[i], fToken);
+ }
+ }
+ }
+
+ private String[] split(String value, String delimiters) {
+ StringTokenizer tokenizer= new StringTokenizer(value, delimiters);
+ int size= tokenizer.countTokens();
+ String[] tokens= new String[size];
+ int i= 0;
+ while (i < size)
+ tokens[i++]= tokenizer.nextToken();
+ return tokens;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#addWord(java.lang.String, org.eclipse.jface.text.rules.IToken)
+ * @since 3.0
+ */
+ @Override
+ public synchronized void addWord(String word, IToken token) {
+ Assert.isNotNull(word);
+ Assert.isNotNull(token);
+
+ super.addWord(word, token);
+ fUppercaseWords.put(new CombinedWordRule.CharacterBuffer(word.toUpperCase()), token);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+ * @since 3.0
+ */
+ @Override
+ public synchronized IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+ if (fCaseSensitive)
+ return super.evaluate(scanner, word);
+
+ fBuffer.clear();
+ for (int i= 0, n= word.length(); i < n; i++)
+ fBuffer.append(Character.toUpperCase(word.charAt(i)));
+
+ IToken token= fUppercaseWords.get(fBuffer);
+ if (token != null)
+ return token;
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Enables/disables the case-sensitivity of the task tag detection.
+ *
+ * @param caseSensitive <code>true</code> iff case-sensitivity should be enabled
+ * @since 3.0
+ */
+ public void setCaseSensitive(boolean caseSensitive) {
+ fCaseSensitive= caseSensitive;
+ }
+ }
+
+ private static class AtJavaIdentifierDetector implements IWordDetector {
+
+ public boolean isWordStart(char c) {
+ return c == '@' || Character.isJavaIdentifierStart(c);
+ }
+
+ public boolean isWordPart(char c) {
+ return c == '.' || Character.isJavaIdentifierPart(c);
+ }
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java
new file mode 100644
index 000000000..0c7557ca2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java.scanner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.ui.text.JavaWhitespaceDetector;
+import org.eclipse.jdt.ui.text.IJavaColorConstants;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+public class JavaDocScanner extends JavaCommentScanner {
+ private static String[] fgTokenProperties= {
+ IJavaColorConstants.JAVADOC_KEYWORD,
+ IJavaColorConstants.JAVADOC_TAG,
+ IJavaColorConstants.JAVADOC_LINK,
+ IJavaColorConstants.JAVADOC_DEFAULT,
+ TASK_TAG
+ };
+
+
+ public JavaDocScanner() {
+ super(IJavaColorConstants.JAVADOC_DEFAULT, fgTokenProperties);
+ }
+
+ public IDocument getDocument() {
+ return fDocument;
+ }
+
+ @Override
+ protected List<IRule> createRules() {
+
+ List<IRule> list= new ArrayList<IRule>();
+
+ // Add rule for tags
+ Token token= getToken(IJavaColorConstants.JAVADOC_TAG);
+ list.add(new TagRule(token));
+
+
+ // Add rule for HTML comments
+ WordRule wordRule= new WordRule(new HTMLCommentDetector(), token);
+ wordRule.addWord("<!--", token); //$NON-NLS-1$
+ wordRule.addWord("--!>", token); //$NON-NLS-1$
+ list.add(wordRule);
+
+
+ // Add rules for links
+ token= getToken(IJavaColorConstants.JAVADOC_LINK);
+ list.add(new MultiLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+ list.add(new MultiLineRule("{@value", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+ list.add(new MultiLineRule("{@inheritDoc", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add rules for @code and @literals
+ token= getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+ list.add(new MultiLineRule("{@code", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+ list.add(new MultiLineRule("{@literal", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add generic whitespace rule
+ token= getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+ list.add(new WhitespaceRule(new JavaWhitespaceDetector(), token));
+
+
+ list.addAll(super.createRules());
+ return list;
+ }
+
+ class TagRule extends SingleLineRule {
+
+ /*
+ * @see SingleLineRule
+ */
+ public TagRule(IToken token) {
+ super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ /*
+ * @see SingleLineRule
+ */
+ public TagRule(IToken token, char escapeCharacter) {
+ super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ private IToken evaluateToken() {
+ try {
+ final String token= getDocument().get(getTokenOffset(), getTokenLength()) + "."; //$NON-NLS-1$
+
+ int offset= 0;
+ char character= token.charAt(++offset);
+
+ if (character == '/')
+ character= token.charAt(++offset);
+
+ while (Character.isWhitespace(character))
+ character= token.charAt(++offset);
+
+ while (Character.isLetterOrDigit(character))
+ character= token.charAt(++offset);
+
+ while (Character.isWhitespace(character))
+ character= token.charAt(++offset);
+
+ if (offset >= 2 && token.charAt(offset) == fEndSequence[0])
+ return fToken;
+
+ } catch (BadLocationException exception) {
+ // Do nothing
+ }
+ return getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+ }
+
+ /*
+ * @see PatternRule#evaluate(ICharacterScanner)
+ */
+ @Override
+ public IToken evaluate(ICharacterScanner scanner) {
+ IToken result= super.evaluate(scanner);
+ if (result == fToken)
+ return evaluateToken();
+ return result;
+ }
+ }
+
+ static class HTMLCommentDetector implements IWordDetector {
+
+ /**
+ * @see IWordDetector#isWordStart(char)
+ */
+ public boolean isWordStart(char c) {
+ return (c == '<' || c == '-');
+ }
+
+ /**
+ * @see IWordDetector#isWordPart(char)
+ */
+ public boolean isWordPart(char c) {
+ return (c == '-' || c == '!' || c == '>');
+ }
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java
new file mode 100644
index 000000000..55508d6eb
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.java.scanner;
+
+import java.util.List;
+
+import org.eclipse.jface.text.rules.IRule;
+
+public class SingleTokenJavaScanner extends AbstractJavaScanner{
+ private String[] fProperty;
+
+ public SingleTokenJavaScanner(String property) {
+ super();
+ fProperty= new String[] { property };
+ initialize();
+ }
+
+ @Override
+ protected List<IRule> createRules() {
+ setDefaultReturnToken(getToken(fProperty[0]));
+ return null;
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java
new file mode 100644
index 000000000..5ecb57830
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+public class JavaCore {
+ public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$
+ public static final String VERSION_1_5 = "1.5"; //$NON-NLS-1$
+ public static final String VERSION_1_8 = "1.8"; //$NON-NLS-1$
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java
new file mode 100644
index 000000000..b789e0e78
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui;
+
+public class JavaPlugin {
+
+ public static void logErrorMessage(String string) {
+ System.err.println(string);
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java
new file mode 100644
index 000000000..1cd813215
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.javaeditor;
+
+public class SemanticHighlightings {
+ public static final String ANNOTATION="annotation"; //$NON-NLS-1$
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java
new file mode 100644
index 000000000..3060ae5ff
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+
+
+/**
+ * A buffered document scanner. The buffer always contains a section
+ * of a fixed size of the document to be scanned.
+ */
+
+public final class BufferedDocumentScanner implements ICharacterScanner {
+
+ /** The document being scanned. */
+ private IDocument fDocument;
+ /** The offset of the document range to scan. */
+ private int fRangeOffset;
+ /** The length of the document range to scan. */
+ private int fRangeLength;
+ /** The delimiters of the document. */
+ private char[][] fDelimiters;
+
+ /** The buffer. */
+ private final char[] fBuffer;
+ /** The offset of the buffer within the document. */
+ private int fBufferOffset;
+ /** The valid length of the buffer for access. */
+ private int fBufferLength;
+ /** The offset of the scanner within the buffer. */
+ private int fOffset;
+
+
+ /**
+ * Creates a new buffered document scanner.
+ * The buffer size is set to the given number of characters.
+ *
+ * @param size the buffer size
+ */
+ public BufferedDocumentScanner(int size) {
+ Assert.isTrue(size >= 1);
+ fBuffer= new char[size];
+ }
+
+ /**
+ * Fills the buffer with the contents of the document starting at the given offset.
+ *
+ * @param offset the document offset at which the buffer starts
+ */
+ private final void updateBuffer(int offset) {
+
+ fBufferOffset= offset;
+
+ if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength)
+ fBufferLength= fRangeLength - (fBufferOffset - fRangeOffset);
+ else
+ fBufferLength= fBuffer.length;
+
+ try {
+ final String content= fDocument.get(fBufferOffset, fBufferLength);
+ content.getChars(0, fBufferLength, fBuffer, 0);
+ } catch (BadLocationException e) {
+ }
+ }
+
+ /**
+ * Configures the scanner by providing access to the document range over which to scan.
+ *
+ * @param document the document to scan
+ * @param offset the offset of the document range to scan
+ * @param length the length of the document range to scan
+ */
+ public final void setRange(IDocument document, int offset, int length) {
+
+ fDocument= document;
+ fRangeOffset= offset;
+ fRangeLength= length;
+
+ String[] delimiters= document.getLegalLineDelimiters();
+ fDelimiters= new char[delimiters.length][];
+ for (int i= 0; i < delimiters.length; i++)
+ fDelimiters[i]= delimiters[i].toCharArray();
+
+ updateBuffer(offset);
+ fOffset= 0;
+ }
+
+ /*
+ * @see ICharacterScanner#read()
+ */
+ public final int read() {
+
+ if (fOffset == fBufferLength) {
+ int end= fBufferOffset + fBufferLength;
+ if (end == fDocument.getLength() || end == fRangeOffset + fRangeLength)
+ return EOF;
+ else {
+ updateBuffer(fBufferOffset + fBufferLength);
+ fOffset= 0;
+ }
+ }
+
+ try {
+ return fBuffer[fOffset++];
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ StringBuffer buf= new StringBuffer();
+ buf.append("Detailed state of 'BufferedDocumentScanner:'"); //$NON-NLS-1$
+ buf.append("\n\tfOffset= "); //$NON-NLS-1$
+ buf.append(fOffset);
+ buf.append("\n\tfBufferOffset= "); //$NON-NLS-1$
+ buf.append(fBufferOffset);
+ buf.append("\n\tfBufferLength= "); //$NON-NLS-1$
+ buf.append(fBufferLength);
+ buf.append("\n\tfRangeOffset= "); //$NON-NLS-1$
+ buf.append(fRangeOffset);
+ buf.append("\n\tfRangeLength= "); //$NON-NLS-1$
+ buf.append(fRangeLength);
+ JavaPlugin.logErrorMessage(buf.toString());
+ throw ex;
+ }
+ }
+
+ /*
+ * @see ICharacterScanner#unread
+ */
+ public final void unread() {
+
+ if (fOffset == 0) {
+ if (fBufferOffset == fRangeOffset) {
+ // error: BOF
+ } else {
+ updateBuffer(fBufferOffset - fBuffer.length);
+ fOffset= fBuffer.length - 1;
+ }
+ } else {
+ --fOffset;
+ }
+ }
+
+ /*
+ * @see ICharacterScanner#getColumn()
+ */
+ public final int getColumn() {
+
+ try {
+ final int offset= fBufferOffset + fOffset;
+ final int line= fDocument.getLineOfOffset(offset);
+ final int start= fDocument.getLineOffset(line);
+ return offset - start;
+ } catch (BadLocationException e) {
+ }
+
+ return -1;
+ }
+
+ /*
+ * @see ICharacterScanner#getLegalLineDelimiters()
+ */
+ public final char[][] getLegalLineDelimiters() {
+ return fDelimiters;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java
new file mode 100644
index 000000000..0add2a854
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting words.
+ * <p>
+ * Word rules also allow for the association of tokens with specific words.
+ * That is, not only can the rule be used to provide tokens for exact matches,
+ * but also for the generalized notion of a word in the context in which it is used.
+ * A word rules uses a word detector to determine what a word is.</p>
+ * <p>
+ * This word rule allows a word detector to be shared among different word matchers.
+ * Its up to the word matchers to decide if a word matches and, in this a case, which
+ * token is associated with that word.
+ * </p>
+ *
+ * @see IWordDetector
+ * @since 3.0
+ */
+public class CombinedWordRule implements IRule {
+
+ /**
+ * Word matcher, that associates matched words with tokens.
+ */
+ public static class WordMatcher {
+
+ /** The table of predefined words and token for this matcher */
+ private Map<CharacterBuffer, IToken> fWords= new HashMap<CharacterBuffer, IToken>();
+
+ /**
+ * Adds a word and the token to be returned if it is detected.
+ *
+ * @param word the word this rule will search for, may not be <code>null</code>
+ * @param token the token to be returned if the word has been found, may not be <code>null</code>
+ */
+ public void addWord(String word, IToken token) {
+ Assert.isNotNull(word);
+ Assert.isNotNull(token);
+
+ fWords.put(new CharacterBuffer(word), token);
+ }
+
+ /**
+ * Returns the token associated to the given word and the scanner state.
+ *
+ * @param scanner the scanner
+ * @param word the word
+ * @return the token or <code>null</code> if none is associated by this matcher
+ */
+ public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+ IToken token= fWords.get(word);
+ if (token != null)
+ return token;
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Removes all words.
+ */
+ public void clearWords() {
+ fWords.clear();
+ }
+ }
+
+ /**
+ * Character buffer, mutable <b>or</b> suitable for use as key in hash maps.
+ */
+ public static class CharacterBuffer {
+
+ /** Buffer content */
+ private char[] fContent;
+ /** Buffer content size */
+ private int fLength= 0;
+
+ /** Is hash code cached? */
+ private boolean fIsHashCached= false;
+ /** The hash code */
+ private int fHashCode;
+
+ /**
+ * Initialize with the given capacity.
+ *
+ * @param capacity the initial capacity
+ */
+ public CharacterBuffer(int capacity) {
+ fContent= new char[capacity];
+ }
+
+ /**
+ * Initialize with the given content.
+ *
+ * @param content the initial content
+ */
+ public CharacterBuffer(String content) {
+ fContent= content.toCharArray();
+ fLength= content.length();
+ }
+
+ /**
+ * Empties this buffer.
+ */
+ public void clear() {
+ fIsHashCached= false;
+ fLength= 0;
+ }
+
+ /**
+ * Appends the given character to the buffer.
+ *
+ * @param c the character
+ */
+ public void append(char c) {
+ fIsHashCached= false;
+ if (fLength == fContent.length) {
+ char[] old= fContent;
+ fContent= new char[old.length << 1];
+ System.arraycopy(old, 0, fContent, 0, old.length);
+ }
+ fContent[fLength++]= c;
+ }
+
+ /**
+ * Returns the length of the content.
+ *
+ * @return the length
+ */
+ public int length() {
+ return fLength;
+ }
+
+ /**
+ * Returns the content as string.
+ *
+ * @return the content
+ */
+ @Override
+ public String toString() {
+ return new String(fContent, 0, fLength);
+ }
+
+ /**
+ * Returns the character at the given position.
+ *
+ * @param i the position
+ * @return the character at position <code>i</code>
+ */
+ public char charAt(int i) {
+ return fContent[i];
+ }
+
+ /*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ if (fIsHashCached)
+ return fHashCode;
+
+ int hash= 0;
+ for (int i= 0, n= fLength; i < n; i++)
+ hash= 29*hash + fContent[i];
+ fHashCode= hash;
+ fIsHashCached= true;
+ return hash;
+ }
+
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof CharacterBuffer))
+ return false;
+ CharacterBuffer buffer= (CharacterBuffer) obj;
+ int length= buffer.length();
+ if (length != fLength)
+ return false;
+ for (int i= 0; i < length; i++)
+ if (buffer.charAt(i) != fContent[i])
+ return false;
+ return true;
+ }
+
+ /**
+ * Is the content equal to the given string?
+ *
+ * @param string the string
+ * @return <code>true</code> iff the content is the same character sequence as in the string
+ */
+ public boolean equals(String string) {
+ int length= string.length();
+ if (length != fLength)
+ return false;
+ for (int i= 0; i < length; i++)
+ if (string.charAt(i) != fContent[i])
+ return false;
+ return true;
+ }
+ }
+
+ /** Internal setting for the uninitialized column constraint */
+ private static final int UNDEFINED= -1;
+
+ /** The word detector used by this rule */
+ private IWordDetector fDetector;
+ /** The default token to be returned on success and if nothing else has been specified. */
+ private IToken fDefaultToken;
+ /** The column constraint */
+ private int fColumn= UNDEFINED;
+ /** Buffer used for pattern detection */
+ private CharacterBuffer fBuffer= new CharacterBuffer(16);
+
+ /** List of word matchers */
+ private List<WordMatcher> fMatchers= new ArrayList<WordMatcher>();
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the scanner
+ * will be rolled back and an undefined token will be returned in order to allow
+ * any subsequent rules to analyze the characters.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector) {
+ this(detector, null, Token.UNDEFINED);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, IToken defaultToken) {
+ this(detector, null, defaultToken);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the scanner
+ * will be rolled back and an undefined token will be returned in order to allow
+ * any subsequent rules to analyze the characters.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param matcher the initial word matcher
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, WordMatcher matcher) {
+ this(detector, matcher, Token.UNDEFINED);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param matcher the initial word matcher
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, WordMatcher matcher, IToken defaultToken) {
+
+ Assert.isNotNull(detector);
+ Assert.isNotNull(defaultToken);
+
+ fDetector= detector;
+ fDefaultToken= defaultToken;
+ if (matcher != null)
+ addWordMatcher(matcher);
+ }
+
+
+ /**
+ * Adds the given matcher.
+ *
+ * @param matcher the matcher
+ */
+ public void addWordMatcher(WordMatcher matcher) {
+ fMatchers.add(matcher);
+ }
+
+ /**
+ * Sets a column constraint for this rule. If set, the rule's token
+ * will only be returned if the pattern is detected starting at the
+ * specified column. If the column is smaller then 0, the column
+ * constraint is considered removed.
+ *
+ * @param column the column in which the pattern starts
+ */
+ public void setColumnConstraint(int column) {
+ if (column < 0)
+ column= UNDEFINED;
+ fColumn= column;
+ }
+
+ /*
+ * @see IRule#evaluate(ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ int c= scanner.read();
+ if (fDetector.isWordStart((char) c)) {
+ if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+ fBuffer.clear();
+ do {
+ fBuffer.append((char) c);
+ c= scanner.read();
+ } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+ scanner.unread();
+
+ for (int i= 0, n= fMatchers.size(); i < n; i++) {
+ IToken token= fMatchers.get(i).evaluate(scanner, fBuffer);
+ if (!token.isUndefined())
+ return token;
+ }
+
+ if (fDefaultToken.isUndefined())
+ unreadBuffer(scanner);
+
+ return fDefaultToken;
+ }
+ }
+
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Returns the characters in the buffer to the scanner.
+ *
+ * @param scanner the scanner to be used
+ */
+ private void unreadBuffer(ICharacterScanner scanner) {
+ for (int i= fBuffer.length() - 1; i >= 0; i--)
+ scanner.unread();
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java
new file mode 100644
index 000000000..a45c23e63
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java
@@ -0,0 +1,535 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+
+
+/**
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
+ * Java strings and Java characters.
+ */
+public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaPartitions {
+
+ // states
+ private static final int JAVA= 0;
+ private static final int SINGLE_LINE_COMMENT= 1;
+ private static final int MULTI_LINE_COMMENT= 2;
+ private static final int JAVADOC= 3;
+ private static final int CHARACTER= 4;
+ private static final int STRING= 5;
+
+ // beginning of prefixes and postfixes
+ private static final int NONE= 0;
+ private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
+ private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
+ private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
+
+ /** The scanner. */
+ private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation
+
+ /** The offset of the last returned token. */
+ private int fTokenOffset;
+ /** The length of the last returned token. */
+ private int fTokenLength;
+
+ /** The state of the scanner. */
+ private int fState;
+ /** The last significant characters read. */
+ private int fLast;
+ /** The amount of characters already read on first call to nextToken(). */
+ private int fPrefixLength;
+
+ // emulate JavaPartitionScanner
+ private boolean fEmulate= false;
+ private int fJavaOffset;
+ private int fJavaLength;
+
+ private final IToken[] fTokens= new IToken[] {
+ new Token(null),
+ new Token(JAVA_SINGLE_LINE_COMMENT),
+ new Token(JAVA_MULTI_LINE_COMMENT),
+ new Token(JAVA_DOC),
+ new Token(JAVA_CHARACTER),
+ new Token(JAVA_STRING)
+ };
+
+ public FastJavaPartitionScanner(boolean emulate) {
+ fEmulate= emulate;
+ }
+
+ public FastJavaPartitionScanner() {
+ this(false);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+ */
+ public IToken nextToken() {
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
+ fTokenOffset += fTokenLength;
+ return fTokens[JAVA];
+ } else {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+
+ while (true) {
+ final int ch= fScanner.read();
+
+ // characters
+ switch (ch) {
+ case ICharacterScanner.EOF:
+ if (fTokenLength > 0) {
+ fLast= NONE; // ignore last
+ return preFix(fState, JAVA, NONE, 0);
+
+ } else {
+ fLast= NONE;
+ fPrefixLength= 0;
+ return Token.EOF;
+ }
+
+ case '\r':
+ // emulate JavaPartitionScanner
+ if (!fEmulate && fLast != CARRIAGE_RETURN) {
+ fLast= CARRIAGE_RETURN;
+ fTokenLength++;
+ continue;
+
+ } else {
+
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+ if (fTokenLength > 0) {
+ IToken token= fTokens[fState];
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fTokenLength++;
+ fLast= NONE;
+ fPrefixLength= 0;
+ } else {
+ fLast= CARRIAGE_RETURN;
+ fPrefixLength= 1;
+ }
+
+ fState= JAVA;
+ return token;
+
+ } else {
+ consume();
+ continue;
+ }
+
+ default:
+ consume();
+ continue;
+ }
+ }
+
+ case '\n':
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+ // assert(fTokenLength > 0);
+ return postFix(fState);
+
+ default:
+ consume();
+ continue;
+ }
+
+ default:
+ if (!fEmulate && fLast == CARRIAGE_RETURN) {
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+
+ int last;
+ int newState;
+ switch (ch) {
+ case '/':
+ last= SLASH;
+ newState= JAVA;
+ break;
+
+ case '*':
+ last= STAR;
+ newState= JAVA;
+ break;
+
+ case '\'':
+ last= NONE;
+ newState= CHARACTER;
+ break;
+
+ case '"':
+ last= NONE;
+ newState= STRING;
+ break;
+
+ case '\r':
+ last= CARRIAGE_RETURN;
+ newState= JAVA;
+ break;
+
+ case '\\':
+ last= BACKSLASH;
+ newState= JAVA;
+ break;
+
+ default:
+ last= NONE;
+ newState= JAVA;
+ break;
+ }
+
+ fLast= NONE; // ignore fLast
+ return preFix(fState, newState, last, 1);
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // states
+ switch (fState) {
+ case JAVA:
+ switch (ch) {
+ case '/':
+ if (fLast == SLASH) {
+ if (fTokenLength - getLastLength(fLast) > 0) {
+ return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+ } else {
+ preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ } else {
+ fTokenLength++;
+ fLast= SLASH;
+ break;
+ }
+
+ case '*':
+ if (fLast == SLASH) {
+ if (fTokenLength - getLastLength(fLast) > 0)
+ return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+ else {
+ preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ } else {
+ consume();
+ break;
+ }
+
+ case '\'':
+ fLast= NONE; // ignore fLast
+ if (fTokenLength > 0)
+ return preFix(JAVA, CHARACTER, NONE, 1);
+ else {
+ preFix(JAVA, CHARACTER, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ case '"':
+ fLast= NONE; // ignore fLast
+ if (fTokenLength > 0)
+ return preFix(JAVA, STRING, NONE, 1);
+ else {
+ preFix(JAVA, STRING, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case SINGLE_LINE_COMMENT:
+ consume();
+ break;
+
+ case JAVADOC:
+ switch (ch) {
+ case '/':
+ switch (fLast) {
+ case SLASH_STAR_STAR:
+ return postFix(MULTI_LINE_COMMENT);
+
+ case STAR:
+ return postFix(JAVADOC);
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case '*':
+ fTokenLength++;
+ fLast= STAR;
+ break;
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case MULTI_LINE_COMMENT:
+ switch (ch) {
+ case '*':
+ if (fLast == SLASH_STAR) {
+ fLast= SLASH_STAR_STAR;
+ fTokenLength++;
+ fState= JAVADOC;
+ } else {
+ fTokenLength++;
+ fLast= STAR;
+ }
+ break;
+
+ case '/':
+ if (fLast == STAR) {
+ return postFix(MULTI_LINE_COMMENT);
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case STRING:
+ switch (ch) {
+ case '\\':
+ fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+ fTokenLength++;
+ break;
+
+ case '\"':
+ if (fLast != BACKSLASH) {
+ return postFix(STRING);
+
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case CHARACTER:
+ switch (ch) {
+ case '\\':
+ fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+ fTokenLength++;
+ break;
+
+ case '\'':
+ if (fLast != BACKSLASH) {
+ return postFix(CHARACTER);
+
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ private static final int getLastLength(int last) {
+ switch (last) {
+ default:
+ return -1;
+
+ case NONE:
+ return 0;
+
+ case CARRIAGE_RETURN:
+ case BACKSLASH:
+ case SLASH:
+ case STAR:
+ return 1;
+
+ case SLASH_STAR:
+ return 2;
+
+ case SLASH_STAR_STAR:
+ return 3;
+ }
+ }
+
+ private final void consume() {
+ fTokenLength++;
+ fLast= NONE;
+ }
+
+ private final IToken postFix(int state) {
+ fTokenLength++;
+ fLast= NONE;
+ fState= JAVA;
+ fPrefixLength= 0;
+ return fTokens[state];
+ }
+
+ private final IToken preFix(int state, int newState, int last, int prefixLength) {
+ // emulate JavaPartitionScanner
+ if (fEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
+ fTokenLength -= getLastLength(fLast);
+ fJavaOffset= fTokenOffset;
+ fJavaLength= fTokenLength;
+ fTokenLength= 1;
+ fState= newState;
+ fPrefixLength= prefixLength;
+ fLast= last;
+ return fTokens[state];
+
+ } else {
+ fTokenLength -= getLastLength(fLast);
+ fLast= last;
+ fPrefixLength= prefixLength;
+ IToken token= fTokens[state];
+ fState= newState;
+ return token;
+ }
+ }
+
+ private static int getState(String contentType) {
+
+ if (contentType == null)
+ return JAVA;
+
+ else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
+ return SINGLE_LINE_COMMENT;
+
+ else if (contentType.equals(JAVA_MULTI_LINE_COMMENT))
+ return MULTI_LINE_COMMENT;
+
+ else if (contentType.equals(JAVA_DOC))
+ return JAVADOC;
+
+ else if (contentType.equals(JAVA_STRING))
+ return STRING;
+
+ else if (contentType.equals(JAVA_CHARACTER))
+ return CHARACTER;
+
+ else
+ return JAVA;
+ }
+
+ /*
+ * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+ */
+ public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+
+ fScanner.setRange(document, offset, length);
+ fTokenOffset= partitionOffset;
+ fTokenLength= 0;
+ fPrefixLength= offset - partitionOffset;
+ fLast= NONE;
+
+ if (offset == partitionOffset) {
+ // restart at beginning of partition
+ fState= JAVA;
+ } else {
+ fState= getState(contentType);
+ }
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ /*
+ * @see ITokenScanner#setRange(IDocument, int, int)
+ */
+ public void setRange(IDocument document, int offset, int length) {
+
+ fScanner.setRange(document, offset, length);
+ fTokenOffset= offset;
+ fTokenLength= 0;
+ fPrefixLength= 0;
+ fLast= NONE;
+ fState= JAVA;
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ /*
+ * @see ITokenScanner#getTokenLength()
+ */
+ public int getTokenLength() {
+ return fTokenLength;
+ }
+
+ /*
+ * @see ITokenScanner#getTokenOffset()
+ */
+ public int getTokenOffset() {
+ return fTokenOffset;
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java
new file mode 100644
index 000000000..0f6bd6aae
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+
+/**
+ * Mix-in for any rule that changes its behavior based on the Java source
+ * version.
+ *
+ * @since 3.1
+ */
+public interface ISourceVersionDependent {
+
+ /**
+ * Sets the configured java source version to one of the
+ * <code>JavaCore.VERSION_X_Y</code> values.
+ *
+ * @param version the new java source version
+ * @see org.eclipse.jdt.core.JavaCore
+ */
+ void setSourceVersion(String version);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java
new file mode 100644
index 000000000..c8e4ae289
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+
+/**
+ * A java aware white space detector.
+ */
+public class JavaWhitespaceDetector implements IWhitespaceDetector {
+
+ public boolean isWhitespace(char c) {
+ return Character.isWhitespace(c);
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java
new file mode 100644
index 000000000..35142f494
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text;
+
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A Java aware word detector.
+ */
+public class JavaWordDetector implements IWordDetector {
+
+ /*
+ * @see IWordDetector#isWordStart
+ */
+ public boolean isWordStart(char c) {
+ return Character.isJavaIdentifierStart(c);
+ }
+
+ /*
+ * @see IWordDetector#isWordPart
+ */
+ public boolean isWordPart(char c) {
+ return Character.isJavaIdentifierPart(c);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java
new file mode 100644
index 000000000..e2b6e8ad3
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui;
+
+public class PreferenceConstants {
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX="semanticHighlighting."; //$NON-NLS-1$
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX=".color"; //$NON-NLS-1$
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java
new file mode 100644
index 000000000..6972a0184
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.text;
+
+/**
+ * Color keys used for syntax highlighting Java
+ * code and Javadoc compliant comments.
+ * A <code>IColorManager</code> is responsible for mapping
+ * concrete colors to these keys.
+ * <p>
+ * This interface declares static final fields only; it is not intended to be
+ * implemented.
+ * </p>
+ *
+ * @see org.eclipse.jdt.ui.text.IColorManager
+ * @see org.eclipse.jdt.ui.text.IColorManagerExtension
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IJavaColorConstants {
+
+ /**
+ * Note: This constant is for internal use only. Clients should not use this constant. The
+ * prefix all color constants start with (value <code>"java_"</code>).
+ */
+ String PREFIX= "java_"; //$NON-NLS-1$
+
+ /** The color key for multi-line comments in Java code
+ * (value <code>"java_multi_line_comment"</code>).
+ */
+ String JAVA_MULTI_LINE_COMMENT= "java_multi_line_comment"; //$NON-NLS-1$
+
+ /** The color key for single-line comments in Java code
+ * (value <code>"java_single_line_comment"</code>).
+ */
+ String JAVA_SINGLE_LINE_COMMENT= "java_single_line_comment"; //$NON-NLS-1$
+
+ /** The color key for Java keywords in Java code
+ * (value <code>"java_keyword"</code>).
+ */
+ String JAVA_KEYWORD= "java_keyword"; //$NON-NLS-1$
+
+ /** The color key for string and character literals in Java code
+ * (value <code>"java_string"</code>).
+ */
+ String JAVA_STRING= "java_string"; //$NON-NLS-1$
+
+ /** The color key for method names in Java code
+ * (value <code>"java_method_name"</code>).
+ *
+ * @since 3.0
+ * @deprecated replaced as of 3.1 by an equivalent semantic highlighting, see {@link org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings#METHOD}
+ */
+ String JAVA_METHOD_NAME= "java_method_name"; //$NON-NLS-1$
+
+ /** The color key for keyword 'return' in Java code
+ * (value <code>"java_keyword_return"</code>).
+ *
+ * @since 3.0
+ */
+ String JAVA_KEYWORD_RETURN= "java_keyword_return"; //$NON-NLS-1$
+
+ /** The color key for operators in Java code
+ * (value <code>"java_operator"</code>).
+ *
+ * @since 3.0
+ */
+ String JAVA_OPERATOR= "java_operator"; //$NON-NLS-1$
+
+ /** The color key for brackets in Java code
+ * (value <code>"java_bracket"</code>).
+ *
+ * @since 3.3
+ */
+ String JAVA_BRACKET= "java_bracket"; //$NON-NLS-1$
+
+ /**
+ * The color key for everything in Java code for which no other color is specified
+ * (value <code>"java_default"</code>).
+ */
+ String JAVA_DEFAULT= "java_default"; //$NON-NLS-1$
+
+ /**
+ * The color key for the Java built-in types such as <code>int</code> and <code>char</code> in Java code
+ * (value <code>"java_type"</code>).
+ *
+ * @deprecated no longer used, replaced by <code>JAVA_KEYWORD</code>
+ */
+ String JAVA_TYPE= "java_type"; //$NON-NLS-1$
+
+ /**
+ * The color key for annotations
+ * (value <code>"java_annotation"</code>).
+ *
+ * @since 3.1
+ * @deprecated replaced as of 3.2 by an equivalent semantic highlighting, see {@link org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings#ANNOTATION}
+ */
+ String JAVA_ANNOTATION= "java_annotation"; //$NON-NLS-1$
+
+ /**
+ * The color key for task tags in java comments
+ * (value <code>"java_comment_task_tag"</code>).
+ *
+ * @since 2.1
+ */
+ String TASK_TAG= "java_comment_task_tag"; //$NON-NLS-1$
+
+ /**
+ * The color key for JavaDoc keywords (<code>@foo</code>) in JavaDoc comments
+ * (value <code>"java_doc_keyword"</code>).
+ */
+ String JAVADOC_KEYWORD= "java_doc_keyword"; //$NON-NLS-1$
+
+ /**
+ * The color key for HTML tags (<code>&lt;foo&gt;</code>) in JavaDoc comments
+ * (value <code>"java_doc_tag"</code>).
+ */
+ String JAVADOC_TAG= "java_doc_tag"; //$NON-NLS-1$
+
+ /**
+ * The color key for JavaDoc links (<code>{foo}</code>) in JavaDoc comments
+ * (value <code>"java_doc_link"</code>).
+ */
+ String JAVADOC_LINK= "java_doc_link"; //$NON-NLS-1$
+
+ /**
+ * The color key for everything in JavaDoc comments for which no other color is specified
+ * (value <code>"java_doc_default"</code>).
+ */
+ String JAVADOC_DEFAULT= "java_doc_default"; //$NON-NLS-1$
+
+ //---------- Properties File Editor ----------
+
+ /**
+ * The color key for keys in a properties file
+ * (value <code>"pf_coloring_key"</code>).
+ *
+ * @since 3.1
+ */
+ String PROPERTIES_FILE_COLORING_KEY= "pf_coloring_key"; //$NON-NLS-1$
+
+ /**
+ * The color key for comments in a properties file
+ * (value <code>"pf_coloring_comment"</code>).
+ *
+ * @since 3.1
+ */
+
+ String PROPERTIES_FILE_COLORING_COMMENT= "pf_coloring_comment"; //$NON-NLS-1$
+
+ /**
+ * The color key for values in a properties file
+ * (value <code>"pf_coloring_value"</code>).
+ *
+ * @since 3.1
+ */
+ String PROPERTIES_FILE_COLORING_VALUE= "pf_coloring_value"; //$NON-NLS-1$
+
+ /**
+ * The color key for assignment in a properties file.
+ * (value <code>"pf_coloring_assignment"</code>).
+ *
+ * @since 3.1
+ */
+ String PROPERTIES_FILE_COLORING_ASSIGNMENT= "pf_coloring_assignment"; //$NON-NLS-1$
+
+ /**
+ * The color key for arguments in values in a properties file.
+ * (value <code>"pf_coloring_argument"</code>).
+ *
+ * @since 3.1
+ */
+ String PROPERTIES_FILE_COLORING_ARGUMENT= "pf_coloring_argument"; //$NON-NLS-1$
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java
new file mode 100644
index 000000000..f59ab396e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.text;
+
+/**
+ * Definition of Java partitioning and its partitions.
+ *
+ * @since 3.1
+ */
+public interface IJavaPartitions {
+
+ /**
+ * The identifier of the Java partitioning.
+ */
+ String JAVA_PARTITIONING= "___java_partitioning"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the single-line (JLS2: EndOfLineComment) end comment partition content type.
+ */
+ String JAVA_SINGLE_LINE_COMMENT= "__java_singleline_comment"; //$NON-NLS-1$
+
+ /**
+ * The identifier multi-line (JLS2: TraditionalComment) comment partition content type.
+ */
+ String JAVA_MULTI_LINE_COMMENT= "__java_multiline_comment"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Javadoc (JLS2: DocumentationComment) partition content type.
+ */
+ String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Java string partition content type.
+ */
+ String JAVA_STRING= "__java_string"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Java character partition content type.
+ */
+ String JAVA_CHARACTER= "__java_character"; //$NON-NLS-1$
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project
new file mode 100644
index 000000000..74a2cb024
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.editor.js</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..d988f2c09
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Js
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.js
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store
new file mode 100644
index 000000000..81229e8d2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project
new file mode 100644
index 000000000..2ab33e92d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.editor.xml</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..02f34ceaa
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF
@@ -0,0 +1,47 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Xml
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.xml
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0",
+ org.eclipse.fx.text;bundle-version="1.0.0",
+ org.eclipse.fx.text.ui;bundle-version="1.0.0",
+ org.eclipse.fx.ui.controls;bundle-version="1.0.0"
+Service-Component: OSGI-INF/services/xmlcomponent.xml
+Bundle-ActivationPolicy: lazy
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0"
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml
new file mode 100644
index 000000000..9358e4c16
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.xml.xmlcomponent">
+ <implementation class="org.eclipse.fx.code.compensator.editor.xml.XMLComponent"/>
+ <service>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory"/>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory"/>
+ </service>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties
new file mode 100644
index 000000000..11d7f1a1b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/services/xmlcomponent.xml
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store
new file mode 100644
index 000000000..75302fef4
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store
new file mode 100644
index 000000000..d5581d0b3
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store
new file mode 100644
index 000000000..39c1da9ce
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store
new file mode 100644
index 000000000..3c779262d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store
new file mode 100644
index 000000000..d5d042447
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store
new file mode 100644
index 000000000..841f408a3
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store
new file mode 100644
index 000000000..d8dcc41fa
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java
new file mode 100644
index 000000000..3d56b75e4
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import javafx.scene.paint.Color;
+
+public interface IXMLColorConstants {
+ Color XML_COMMENT = Color.rgb(128, 0, 0);
+ Color PROC_INSTR = Color.rgb(128, 128, 128);
+ Color STRING = Color.rgb(0, 128, 0);
+ Color DEFAULT = Color.rgb(0, 0, 0);
+ Color TAG = Color.rgb(0, 0, 128);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java
new file mode 100644
index 000000000..1bfe309c8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+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.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+
+public class NonRuleBasedDamagerRepairer
+ implements IPresentationDamager, IPresentationRepairer {
+
+ /** The document this object works on */
+ protected IDocument fDocument;
+ /** The default text attribute if non is returned as data by the current token */
+ protected TextAttribute fDefaultTextAttribute;
+
+ /**
+ * Constructor for NonRuleBasedDamagerRepairer.
+ */
+ public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
+ Assert.isNotNull(defaultTextAttribute);
+
+ fDefaultTextAttribute = defaultTextAttribute;
+ }
+
+ /**
+ * @see IPresentationRepairer#setDocument(IDocument)
+ */
+ public void setDocument(IDocument document) {
+ fDocument = document;
+ }
+
+ /**
+ * Returns the end offset of the line that contains the specified offset or
+ * if the offset is inside a line delimiter, the end offset of the next line.
+ *
+ * @param offset the offset whose line end offset must be computed
+ * @return the line end offset for the given offset
+ * @exception BadLocationException if offset is invalid in the current document
+ */
+ protected int endOfLineOf(int offset) throws BadLocationException {
+
+ IRegion info = fDocument.getLineInformationOfOffset(offset);
+ if (offset <= info.getOffset() + info.getLength())
+ return info.getOffset() + info.getLength();
+
+ int line = fDocument.getLineOfOffset(offset);
+ try {
+ info = fDocument.getLineInformation(line + 1);
+ return info.getOffset() + info.getLength();
+ } catch (BadLocationException x) {
+ return fDocument.getLength();
+ }
+ }
+
+ /**
+ * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+ */
+ public IRegion getDamageRegion(
+ ITypedRegion partition,
+ DocumentEvent event,
+ boolean documentPartitioningChanged) {
+ if (!documentPartitioningChanged) {
+ try {
+
+ IRegion info =
+ fDocument.getLineInformationOfOffset(event.getOffset());
+ int start = Math.max(partition.getOffset(), info.getOffset());
+
+ int end =
+ event.getOffset()
+ + (event.getText() == null
+ ? event.getLength()
+ : event.getText().length());
+
+ if (info.getOffset() <= end
+ && end <= info.getOffset() + info.getLength()) {
+ // optimize the case of the same line
+ end = info.getOffset() + info.getLength();
+ } else
+ end = endOfLineOf(end);
+
+ end =
+ Math.min(
+ partition.getOffset() + partition.getLength(),
+ end);
+ return new Region(start, end - start);
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ return partition;
+ }
+
+ /**
+ * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+ */
+ public void createPresentation(
+ TextPresentation presentation,
+ ITypedRegion region) {
+ addRange(
+ presentation,
+ region.getOffset(),
+ region.getLength(),
+ fDefaultTextAttribute);
+ }
+
+ /**
+ * Adds style information to the given text presentation.
+ *
+ * @param presentation the text presentation to be extended
+ * @param offset the offset of the range to be styled
+ * @param length the length of the range to be styled
+ * @param attr the attribute describing the style of the range to be styled
+ */
+ protected void addRange(
+ TextPresentation presentation,
+ int offset,
+ int length,
+ TextAttribute attr) {
+ if (attr != null)
+ presentation.addStyleRange(
+ new StyleRange(
+ offset,
+ length,
+ attr.getForeground(),
+ attr.getBackground(),
+ attr.getStyle()));
+ }
+} \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java
new file mode 100644
index 000000000..ba497f708
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.rules.*;
+
+public class TagRule extends MultiLineRule {
+
+ public TagRule(IToken token) {
+ super("<", ">", token);
+ }
+ protected boolean sequenceDetected(
+ ICharacterScanner scanner,
+ char[] sequence,
+ boolean eofAllowed) {
+ int c = scanner.read();
+ if (sequence[0] == '<') {
+ if (c == '?') {
+ // processing instruction - abort
+ scanner.unread();
+ return false;
+ }
+ if (c == '!') {
+ scanner.unread();
+ // comment - abort
+ return false;
+ }
+ } else if (sequence[0] == '>') {
+ scanner.unread();
+ }
+ return super.sequenceDetected(scanner, sequence, eofAllowed);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java
new file mode 100644
index 000000000..4e9cc9642
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.fx.code.compensator.editor.ContentTypeProvider;
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory;
+import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class XMLComponent implements PartitionerFactory, SourceViewerConfigurationFactory {
+
+ @Override
+ public SourceViewerConfiguration createConfiguration(Input<?> input) {
+ return new XMLConfiguration();
+ }
+
+ @Override
+ public boolean applies(Input<?> input) {
+ if( input instanceof ContentTypeProvider ) {
+ String contentType = ((ContentTypeProvider) input).getContentType();
+ return ContentTypeProvider.XML.equals(contentType);
+ }
+ return false;
+ }
+
+ @Override
+ public IDocumentPartitioner createPartitioner(Input<?> input) {
+ return new FastPartitioner(
+ new XMLPartitionScanner(),
+ new String[] {
+ XMLPartitionScanner.XML_TAG,
+ XMLPartitionScanner.XML_COMMENT });
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java
new file mode 100644
index 000000000..cc977d8f9
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class XMLConfiguration extends SourceViewerConfiguration {
+// private XMLDoubleClickStrategy doubleClickStrategy;
+ private XMLTagScanner tagScanner;
+ private XMLScanner scanner;
+
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ return new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ XMLPartitionScanner.XML_COMMENT,
+ XMLPartitionScanner.XML_TAG };
+ }
+// public ITextDoubleClickStrategy getDoubleClickStrategy(
+// ISourceViewer sourceViewer,
+// String contentType) {
+// if (doubleClickStrategy == null)
+// doubleClickStrategy = new XMLDoubleClickStrategy();
+// return doubleClickStrategy;
+// }
+
+ protected XMLScanner getXMLScanner() {
+ if (scanner == null) {
+ scanner = new XMLScanner();
+ scanner.setDefaultReturnToken(
+ new Token(
+ new TextAttribute(IXMLColorConstants.DEFAULT)));
+ }
+ return scanner;
+ }
+ protected XMLTagScanner getXMLTagScanner() {
+ if (tagScanner == null) {
+ tagScanner = new XMLTagScanner();
+ tagScanner.setDefaultReturnToken(
+ new Token(
+ new TextAttribute(
+ IXMLColorConstants.TAG)));
+ }
+ return tagScanner;
+ }
+
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler = new PresentationReconciler();
+
+ DefaultDamagerRepairer dr =
+ new DefaultDamagerRepairer(getXMLTagScanner());
+ reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+ reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+ dr = new DefaultDamagerRepairer(getXMLScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ NonRuleBasedDamagerRepairer ndr =
+ new NonRuleBasedDamagerRepairer(
+ new TextAttribute(
+ IXMLColorConstants.XML_COMMENT));
+ reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT);
+ reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT);
+
+ return reconciler;
+ }
+
+} \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java
new file mode 100644
index 000000000..d61c8ce96
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.rules.*;
+
+public class XMLPartitionScanner extends RuleBasedPartitionScanner {
+ public final static String XML_COMMENT = "__xml_comment";
+ public final static String XML_TAG = "__xml_tag";
+
+ public XMLPartitionScanner() {
+
+ IToken xmlComment = new Token(XML_COMMENT);
+ IToken tag = new Token(XML_TAG);
+
+ IPredicateRule[] rules = new IPredicateRule[2];
+
+ rules[0] = new MultiLineRule("<!--", "-->", xmlComment);
+ rules[1] = new TagRule(tag);
+
+ setPredicateRules(rules);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java
new file mode 100644
index 000000000..9fc1e1b0b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.rules.*;
+import org.eclipse.jface.text.*;
+
+public class XMLScanner extends RuleBasedScanner {
+
+ public XMLScanner() {
+ IToken procInstr =
+ new Token(
+ new TextAttribute(
+ IXMLColorConstants.PROC_INSTR));
+
+ IRule[] rules = new IRule[2];
+ //Add rule for processing instructions
+ rules[0] = new SingleLineRule("<?", "?>", procInstr);
+ // Add generic whitespace rule.
+ rules[1] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+ setRules(rules);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java
new file mode 100644
index 000000000..7b51b8cfa
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.*;
+import org.eclipse.jface.text.rules.*;
+
+public class XMLTagScanner extends RuleBasedScanner {
+
+ public XMLTagScanner() {
+ IToken string =
+ new Token(
+ new TextAttribute(IXMLColorConstants.STRING));
+
+ IRule[] rules = new IRule[3];
+
+ // Add rule for double quotes
+ rules[0] = new SingleLineRule("\"", "\"", string, '\\');
+ // Add a rule for single quotes
+ rules[1] = new SingleLineRule("'", "'", string, '\\');
+ // Add generic whitespace rule.
+ rules[2] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+ setRules(rules);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java
new file mode 100644
index 000000000..8e74c7f4f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.xml;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+public class XMLWhitespaceDetector implements IWhitespaceDetector {
+
+ public boolean isWhitespace(char c) {
+ return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project
new file mode 100644
index 000000000..c7cfd2686
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..a54c995ec
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,52 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Editor
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0",
+ javax.annotation;version="1.2.0",
+ javax.inject;version="1.0.0"
+Require-Bundle: org.eclipse.fx.ui.controls;bundle-version="1.0.0",
+ org.eclipse.text;bundle-version="3.5.300",
+ org.eclipse.fx.text;bundle-version="1.0.0",
+ org.eclipse.fx.text.ui;bundle-version="1.0.0"
+Export-Package: org.eclipse.fx.code.compensator.editor,
+ org.eclipse.fx.code.compensator.editor.services
+Service-Component: OSGI-INF/services/fileinputprovider.xml,
+ OSGI-INF/services/defaultdocumentfactory.xml
+Bundle-ActivationPolicy: lazy
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml
new file mode 100644
index 000000000..3ffb0736a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.defaultdocumentfactory">
+ <implementation class="org.eclipse.fx.code.compensator.editor.internal.DefaultDocumentFactory"/>
+ <service>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.DocumentFactory"/>
+ </service>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml
new file mode 100644
index 000000000..15ced386a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.fileinputprovider">
+ <implementation class="org.eclipse.fx.code.compensator.editor.internal.FileInputFactory"/>
+ <service>
+ <provide interface="org.eclipse.fx.code.compensator.editor.services.InputFactory"/>
+ </service>
+</scr:component>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties
new file mode 100644
index 000000000..d2d37a30e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties
@@ -0,0 +1,6 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/,\
+ OSGI-INF/services/defaultdocumentfactory.xml
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java
new file mode 100644
index 000000000..5eb5ca97f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor;
+
+public interface ContentTypeProvider {
+ public static final String XML = "text/xml";
+ public static final String JAVA = "text/java";
+ public static final String JAVASCRIPT = "text/javascript";
+ public String getContentType();
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java
new file mode 100644
index 000000000..69d8d3e1c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor;
+
+public interface Input<O> {
+ public O getData();
+ public void setData(O data);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java
new file mode 100644
index 000000000..07382da8a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor;
+
+import javafx.scene.layout.BorderPane;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class TextEditor {
+ public static final String DOCUMENT_URL = "documentUrl";
+
+ @Inject
+ IDocument document;
+
+ @Inject
+ SourceViewerConfiguration configuration;
+
+ @Inject
+ IDocumentPartitioner partitioner;
+
+ @PostConstruct
+ public void initUI(BorderPane pane) {
+ SourceViewer viewer = new SourceViewer();
+ if( document instanceof IDocumentExtension3 ) {
+ ((IDocumentExtension3)document).setDocumentPartitioner(configuration.getConfiguredDocumentPartitioning(viewer),partitioner);
+ } else {
+ document.setDocumentPartitioner(partitioner);
+ }
+ document.setDocumentPartitioner(partitioner);
+ partitioner.connect(document);
+
+ viewer.configure(configuration);
+ viewer.setDocument(document);
+ pane.setCenter(viewer);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java
new file mode 100644
index 000000000..5240eed45
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.internal;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.services.DocumentFactory;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+
+public class DefaultDocumentFactory implements DocumentFactory {
+
+ @Override
+ public boolean applies(Input<?> input) {
+ return input instanceof FileInput;
+ }
+
+ @Override
+ public IDocument createDocument(Input<?> input) {
+ return new Document(((FileInput)input).getData());
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java
new file mode 100644
index 000000000..2f715f09d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.internal;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.fx.code.compensator.editor.ContentTypeProvider;
+import org.eclipse.fx.code.compensator.editor.Input;
+
+public class FileInput implements Input<String>, ContentTypeProvider {
+ private Path path;
+
+ public FileInput(Path path) {
+ this.path = path;
+ }
+
+ @Override
+ public String getData() {
+ try(BufferedReader reader = Files.newBufferedReader(path)) {
+ StringBuilder b = new StringBuilder();
+ String line;
+ while( (line = reader.readLine()) != null ) {
+ b.append(line);
+ }
+ reader.close();
+ return b.toString();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ @Override
+ public void setData(String data) {
+ try(BufferedWriter writer = Files.newBufferedWriter(path)) {
+ writer.write(data);
+ writer.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String getContentType() {
+ //FIXME Need suffix => type mapping
+ System.err.println("PATH: " + path);
+ if( path.toString().endsWith(".xml") ) {
+ return ContentTypeProvider.XML;
+ } else if( path.toString().endsWith(".java") ) {
+ return ContentTypeProvider.JAVA;
+ } else if( path.toString().endsWith(".js") ) {
+ return ContentTypeProvider.JAVASCRIPT;
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java
new file mode 100644
index 000000000..674c96d57
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.internal;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.fx.code.compensator.editor.services.InputFactory;
+
+public class FileInputFactory implements InputFactory {
+ @Override
+ public boolean applies(String url) {
+ System.err.println("CHECKING: " + url);
+ return url.startsWith("file:");
+ }
+
+ @Override
+ public <O> Input<O> createInput(String url) {
+ try {
+ return (Input<O>) new FileInput(Paths.get(new URI(url)));
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java
new file mode 100644
index 000000000..413e5ab2b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.services;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.IDocument;
+
+public interface DocumentFactory {
+ public boolean applies(Input<?> input);
+ public IDocument createDocument(Input<?> input);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java
new file mode 100644
index 000000000..a3778631b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.services;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+
+public interface InputFactory {
+ public boolean applies(String url);
+ public <O> Input<O> createInput(String url);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java
new file mode 100644
index 000000000..0424d6f26
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.services;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+public interface PartitionerFactory {
+ public boolean applies(Input<?> input);
+ public IDocumentPartitioner createPartitioner(Input<?> input);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java
new file mode 100644
index 000000000..4ec14eb96
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.editor.services;
+
+import org.eclipse.fx.code.compensator.editor.Input;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public interface SourceViewerConfigurationFactory {
+ public boolean applies(Input<?> input);
+ public SourceViewerConfiguration createConfiguration(Input<?> input);
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project
new file mode 100644
index 000000000..045afcaff
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.freeedit</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..a3e89d2d8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF
@@ -0,0 +1,48 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Freeedit
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.freeedit;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.1.0.v20140512-1820",
+ org.eclipse.fx.code.compensator.model;bundle-version="0.1.0",
+ org.eclipse.e4.core.commands;bundle-version="0.10.2",
+ org.eclipse.core.commands;bundle-version="3.6.100",
+ org.eclipse.e4.core.contexts;bundle-version="1.3.100"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0",
+ javax.annotation;version="1.2.0",
+ javax.inject;version="1.0.0"
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties
new file mode 100644
index 000000000..a14e838a6
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties
@@ -0,0 +1,6 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ fragment.e4xmi,\
+ plugin.xml
+source.. = src/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi
new file mode 100644
index 000000000..a5ef9b374
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_JIaJEPNlEeOKm6R57HGa4g">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_R9qSgPNlEeOKm6R57HGa4g" featurename="children" parentElementId="org.eclipse.fx.code.compensator.app.perspectivestack.0">
+ <elements xsi:type="advanced:Perspective" xmi:id="_Zg4MUPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.perspective.0" label="Free edit">
+ <children xsi:type="basic:PartSashContainer" xmi:id="_ejlRMPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partsashcontainer.0" horizontal="true">
+ <children xsi:type="basic:PartStack" xmi:id="_fgaF0PNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.0" containerData="20">
+ <children xsi:type="basic:Part" xmi:id="_iX7skPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.part.0" contributionURI="bundleclass://org.eclipse.fx.code.compensator.freeedit/org.eclipse.fx.code.compensator.freeedit.FileList" label="Files" iconURI="platform:/plugin/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png"/>
+ </children>
+ <children xsi:type="basic:PartStack" xmi:id="_f6c9gPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.1" containerData="60"/>
+ <children xsi:type="basic:PartStack" xmi:id="_gQ-nIPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.2" containerData="20">
+ <children xsi:type="basic:Part" xmi:id="_tzdUsPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.part.1" contributionURI="bundleclass://org.eclipse.fx.code.compensator.freeedit/org.eclipse.fx.code.compensator.freeedit.FileOutline" label="Outline" iconURI="platform:/plugin/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png"/>
+ </children>
+ </children>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png
new file mode 100644
index 000000000..225aca941
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png
new file mode 100644
index 000000000..b1dde396c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png
Binary files differ
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml
new file mode 100644
index 000000000..53fd90f33
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin>
+
+ <extension
+ id="org.eclipse.fx.code.compensator.freeedit.fragment"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ apply="notexists"
+ uri="fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java
new file mode 100644
index 000000000..5e7c41794
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.freeedit;
+
+import java.util.Collections;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.fx.code.compensator.model.workbench.File;
+import org.eclipse.fx.code.compensator.model.workbench.Resource;
+import org.eclipse.fx.code.compensator.model.workbench.Workbench;
+import org.eclipse.fx.code.compensator.model.workbench.WorkbenchPackage;
+
+@SuppressWarnings("restriction")
+public class FileList {
+ @Inject
+ private Workbench workbench;
+
+ @Inject
+ private ECommandService commandService;
+
+ @Inject
+ private EHandlerService handlerService;
+
+ private ObservableList<Resource> inputList = FXCollections.observableArrayList();
+
+ private ListView<Resource> view;
+
+ @PostConstruct
+ public void initUI(BorderPane parent) {
+ view = new ListView<>();
+ view.setCellFactory(FileList::listCell);
+ view.setItems(inputList);
+ view.setOnMouseClicked(this::open);
+ parent.setCenter(view);
+ workbench.eAdapters().add(new AdapterImpl() {
+ @Override
+ public void notifyChanged(Notification msg) {
+ if( msg.getFeature() == WorkbenchPackage.Literals.WORKBENCH_ELEMENT__RESOURCES ) {
+ if( msg.getEventType() == Notification.ADD ) {
+ inputList.add((Resource) msg.getNewValue());
+ }
+ }
+ }
+ });
+ }
+
+ private void open(MouseEvent event) {
+ if( event.getClickCount() == 2 ) {
+ Command cmd = commandService.getCommand("org.eclipse.fx.code.compensator.app.command.1");
+ IEclipseContext staticCtx = EclipseContextFactory.create();
+ staticCtx.set(File.class, (File)view.getSelectionModel().getSelectedItem());
+ ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(cmd, Collections.emptyMap());
+ handlerService.executeHandler(pCmd, staticCtx);
+ staticCtx.dispose();
+ }
+ }
+
+ private static ListCell<Resource> listCell(ListView<Resource> param) {
+ return new ListCell<Resource>() {
+ @Override
+ protected void updateItem(Resource item, boolean empty) {
+ if( item != null && ! empty ) {
+ if( item instanceof File ) {
+ URI uri = URI.createURI(((File) item).getUrl());
+ setText(uri.lastSegment());
+ }
+ } else {
+ setText(null);
+ setGraphic(null);
+ }
+ super.updateItem(item, empty);
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java
new file mode 100644
index 000000000..48d30818a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.freeedit;
+
+import javafx.scene.layout.BorderPane;
+
+import javax.annotation.PostConstruct;
+
+public class FileOutline {
+ @PostConstruct
+ public void initUI(BorderPane parent) {
+
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath
new file mode 100644
index 000000000..2534a1484
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="src-gen"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.project b/experimental/compensator/org.eclipse.fx.code.compensator.model/.project
new file mode 100644
index 000000000..82aecc346
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.code.compensator.model</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..3c1457770
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.fx.code.compensator.model;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: org.eclipse.fx.code.compensator.model.workbench,
+ org.eclipse.fx.code.compensator.model.workbench.impl,
+ org.eclipse.fx.code.compensator.model.workbench.util
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.xtext.xbase.lib;resolution:=optional;visibility:=reexport,
+ org.eclipse.emf.ecore.xcore.lib;resolution:=optional;visibility:=reexport
+Bundle-ActivationPolicy: lazy
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties
new file mode 100644
index 000000000..697ca9645
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties
@@ -0,0 +1,10 @@
+#
+
+bin.includes = .,\
+ model/,\
+ META-INF/,\
+ plugin.xml,\
+ plugin.properties
+jars.compile.order = .
+source.. = src-gen/
+output.. = bin/
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore b/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore
new file mode 100644
index 000000000..647d68c3f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright (c) 2014 BestSolution.at 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:
+* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+*******************************************************************************/
+package org.eclipse.fx.code.compensator.model.workbench
+
+abstract class WorkbenchElement {
+ contains WorkbenchElement[0..*] elements
+ contains Resource[0..*] resources
+}
+
+class Workbench extends WorkbenchElement {
+
+}
+
+abstract class Resource {
+
+}
+
+class File extends Resource {
+ String url
+}
+
+class Folder extends Resource {
+ String url
+}
+
+class ResourceGroup extends Resource {
+ String name
+ contains Resource[0..*] resources
+}
+
+/*class Project extends Resource {
+ String url
+}*/ \ No newline at end of file
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties
new file mode 100644
index 000000000..ae615624d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties
@@ -0,0 +1,4 @@
+#
+
+pluginName = Workbench Model
+providerName = www.example.org
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml
new file mode 100644
index 000000000..c64319704
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+-->
+
+<plugin>
+
+ <extension point="org.eclipse.emf.ecore.generated_package">
+ <!-- @generated Workbench -->
+ <package
+ uri="org.eclipse.fx.code.compensator.model.workbench"
+ class="org.eclipse.fx.code.compensator.model.workbench.WorkbenchPackage"
+ genModel="model/Workbench.xcore"/>
+ </extension>
+
+</plugin>
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore
new file mode 100644
index 000000000..1e98cf7ac
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore
@@ -0,0 +1,8 @@
+/File.java
+/Folder.java
+/Resource.java
+/ResourceGroup.java
+/Workbench.java
+/WorkbenchElement.java
+/WorkbenchFactory.java
+/WorkbenchPackage.java
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore
new file mode 100644
index 000000000..bbca9eaff
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore
@@ -0,0 +1,8 @@
+/FileImpl.java
+/FolderImpl.java
+/ResourceGroupImpl.java
+/ResourceImpl.java
+/WorkbenchElementImpl.java
+/WorkbenchFactoryImpl.java
+/WorkbenchImpl.java
+/WorkbenchPackageImpl.java
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore
new file mode 100644
index 000000000..1d3804e90
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore
@@ -0,0 +1,2 @@
+/WorkbenchAdapterFactory.java
+/WorkbenchSwitch.java
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.classpath b/experimental/compensator/org.eclipse.fx.text.ui/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.gitignore b/experimental/compensator/org.eclipse.fx.text.ui/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.project b/experimental/compensator/org.eclipse.fx.text.ui/.project
new file mode 100644
index 000000000..817056f57
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.text.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..81fab4a9e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,50 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Ui
+Bundle-SymbolicName: org.eclipse.fx.text.ui
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.fx.ui.controls;bundle-version="1.0.0",
+ org.eclipse.text;bundle-version="3.5.300",
+ org.eclipse.fx.text;bundle-version="1.0.0"
+Export-Package: org.eclipse.jface.text,
+ org.eclipse.jface.text.presentation,
+ org.eclipse.jface.text.reconciler,
+ org.eclipse.jface.text.rules,
+ org.eclipse.jface.text.source,
+ org.eclipse.jface.viewers
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0"
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/build.properties b/experimental/compensator/org.eclipse.fx.text.ui/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java
new file mode 100644
index 000000000..462db1fd5
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java
@@ -0,0 +1,401 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.fx.ui.controls.styledtext.TextChangedEvent;
+import org.eclipse.fx.ui.controls.styledtext.TextChangingEvent;
+
+
+/**
+ * Default implementation of {@link org.eclipse.jface.text.IDocumentAdapter}.
+ * <p>
+ * <strong>Note:</strong> This adapter does not work if the widget auto-wraps the text.
+ * </p>
+ */
+class DefaultDocumentAdapter implements IDocumentAdapter, IDocumentListener, IDocumentAdapterExtension {
+
+ /** The adapted document. */
+ private IDocument fDocument;
+ /** The document clone for the non-forwarding case. */
+ private IDocument fDocumentClone;
+ /** The original content */
+ private String fOriginalContent;
+ /** The original line delimiters */
+ private String[] fOriginalLineDelimiters;
+ /** The registered text change listeners */
+ private List fTextChangeListeners= new ArrayList(1);
+ /**
+ * The remembered document event
+ * @since 2.0
+ */
+ private DocumentEvent fEvent;
+ /** The line delimiter */
+ private String fLineDelimiter= null;
+ /**
+ * Indicates whether this adapter is forwarding document changes
+ * @since 2.0
+ */
+ private boolean fIsForwarding= true;
+ /**
+ * Length of document at receipt of <code>documentAboutToBeChanged</code>
+ * @since 2.1
+ */
+ private int fRememberedLengthOfDocument;
+ /**
+ * Length of first document line at receipt of <code>documentAboutToBeChanged</code>
+ * @since 2.1
+ */
+ private int fRememberedLengthOfFirstLine;
+ /**
+ * The data of the event at receipt of <code>documentAboutToBeChanged</code>
+ * @since 2.1
+ */
+ private DocumentEvent fOriginalEvent= new DocumentEvent();
+
+
+ /**
+ * Creates a new document adapter which is initially not connected to
+ * any document.
+ */
+ public DefaultDocumentAdapter() {
+ }
+
+ /**
+ * Sets the given document as the document to be adapted.
+ *
+ * @param document the document to be adapted or <code>null</code> if there is no document
+ */
+ public void setDocument(IDocument document) {
+
+ if (fDocument != null)
+ fDocument.removePrenotifiedDocumentListener(this);
+
+ fDocument= document;
+ fLineDelimiter= null;
+
+ if (!fIsForwarding) {
+ fDocumentClone= null;
+ if (fDocument != null) {
+ fOriginalContent= fDocument.get();
+ fOriginalLineDelimiters= fDocument.getLegalLineDelimiters();
+ } else {
+ fOriginalContent= null;
+ fOriginalLineDelimiters= null;
+ }
+ }
+
+ if (fDocument != null)
+ fDocument.addPrenotifiedDocumentListener(this);
+ }
+
+ /*
+ * @see StyledTextContent#addTextChangeListener(TextChangeListener)
+ */
+ public void addTextChangeListener(TextChangeListener listener) {
+ Assert.isNotNull(listener);
+ if (!fTextChangeListeners.contains(listener))
+ fTextChangeListeners.add(listener);
+ }
+
+ /*
+ * @see StyledTextContent#removeTextChangeListener(TextChangeListener)
+ */
+ public void removeTextChangeListener(TextChangeListener listener) {
+ Assert.isNotNull(listener);
+ fTextChangeListeners.remove(listener);
+ }
+
+ /**
+ * Tries to repair the line information.
+ *
+ * @param document the document
+ * @see IRepairableDocument#repairLineInformation()
+ * @since 3.0
+ */
+ private void repairLineInformation(IDocument document) {
+ if (document instanceof IRepairableDocument) {
+ IRepairableDocument repairable= (IRepairableDocument) document;
+ repairable.repairLineInformation();
+ }
+ }
+
+ /**
+ * Returns the line for the given line number.
+ *
+ * @param document the document
+ * @param line the line number
+ * @return the content of the line of the given number in the given document
+ * @throws BadLocationException if the line number is invalid for the adapted document
+ * @since 3.0
+ */
+ private String doGetLine(IDocument document, int line) throws BadLocationException {
+ IRegion r= document.getLineInformation(line);
+ return document.get(r.getOffset(), r.getLength());
+ }
+
+ private IDocument getDocumentForRead() {
+ if (!fIsForwarding) {
+ if (fDocumentClone == null) {
+ String content= fOriginalContent == null ? "" : fOriginalContent; //$NON-NLS-1$
+ String[] delims= fOriginalLineDelimiters == null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters;
+ fDocumentClone= new DocumentClone(content, delims);
+ }
+ return fDocumentClone;
+ }
+
+ return fDocument;
+ }
+
+ public String getLine(int line) {
+
+ IDocument document= getDocumentForRead();
+ try {
+ return doGetLine(document, line);
+ } catch (BadLocationException x) {
+ repairLineInformation(document);
+ try {
+ return doGetLine(document, line);
+ } catch (BadLocationException x2) {
+ }
+ }
+
+ //TODO Log it
+ System.err.println("invalid argument");
+ return null;
+ }
+
+ public int getLineAtOffset(int offset) {
+ IDocument document= getDocumentForRead();
+ try {
+ return document.getLineOfOffset(offset);
+ } catch (BadLocationException x) {
+ repairLineInformation(document);
+ try {
+ return document.getLineOfOffset(offset);
+ } catch (BadLocationException x2) {
+ }
+ }
+
+ //TODO Log it
+ System.err.println("invalid argument");
+ return -1;
+ }
+
+ public int getLineCount() {
+ return getDocumentForRead().getNumberOfLines();
+ }
+
+ public int getOffsetAtLine(int line) {
+ IDocument document= getDocumentForRead();
+ try {
+ return document.getLineOffset(line);
+ } catch (BadLocationException x) {
+ repairLineInformation(document);
+ try {
+ return document.getLineOffset(line);
+ } catch (BadLocationException x2) {
+ }
+ }
+
+ //TODO Log it
+ System.err.println("invalid argument");
+ return -1;
+ }
+
+ public String getTextRange(int offset, int length) {
+ try {
+ return getDocumentForRead().get(offset, length);
+ } catch (BadLocationException x) {
+ //TODO Log it
+ x.printStackTrace();
+ return null;
+ }
+ }
+
+ public void replaceTextRange(int pos, int length, String text) {
+ try {
+ fDocument.replace(pos, length, text);
+ } catch (BadLocationException x) {
+ //TODO Log it
+ x.printStackTrace();
+ }
+ }
+
+ public void setText(String text) {
+ fDocument.set(text);
+ }
+
+ /*
+ * @see StyledTextContent#getCharCount()
+ */
+ public int getCharCount() {
+ return getDocumentForRead().getLength();
+ }
+
+ /*
+ * @see StyledTextContent#getLineDelimiter()
+ */
+ public String getLineDelimiter() {
+ if (fLineDelimiter == null)
+ fLineDelimiter= TextUtilities.getDefaultLineDelimiter(fDocument);
+ return fLineDelimiter;
+ }
+
+ /*
+ * @see IDocumentListener#documentChanged(DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ // check whether the given event is the one which was remembered
+ if (fEvent == null || event != fEvent)
+ return;
+
+ if (isPatchedEvent(event) || (event.getOffset() == 0 && event.getLength() == fRememberedLengthOfDocument)) {
+ fLineDelimiter= null;
+ fireTextSet();
+ } else {
+ if (event.getOffset() < fRememberedLengthOfFirstLine)
+ fLineDelimiter= null;
+ fireTextChanged();
+ }
+ }
+
+ /*
+ * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+
+ fRememberedLengthOfDocument= fDocument.getLength();
+ try {
+ fRememberedLengthOfFirstLine= fDocument.getLineLength(0);
+ } catch (BadLocationException e) {
+ fRememberedLengthOfFirstLine= -1;
+ }
+
+ fEvent= event;
+ rememberEventData(fEvent);
+ fireTextChanging();
+ }
+
+ /**
+ * Checks whether this event has been changed between <code>documentAboutToBeChanged</code> and
+ * <code>documentChanged</code>.
+ *
+ * @param event the event to be checked
+ * @return <code>true</code> if the event has been changed, <code>false</code> otherwise
+ */
+ private boolean isPatchedEvent(DocumentEvent event) {
+ return fOriginalEvent.fOffset != event.fOffset || fOriginalEvent.fLength != event.fLength || fOriginalEvent.fText != event.fText;
+ }
+
+ /**
+ * Makes a copy of the given event and remembers it.
+ *
+ * @param event the event to be copied
+ */
+ private void rememberEventData(DocumentEvent event) {
+ fOriginalEvent.fOffset= event.fOffset;
+ fOriginalEvent.fLength= event.fLength;
+ fOriginalEvent.fText= event.fText;
+ }
+
+ /**
+ * Sends a text changed event to all registered listeners.
+ */
+ private void fireTextChanged() {
+
+ if (!fIsForwarding)
+ return;
+
+ TextChangedEvent event = TextChangedEvent.textChanged(this);
+
+ if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) {
+ Iterator e= new ArrayList(fTextChangeListeners).iterator();
+ while (e.hasNext())
+ ((TextChangeListener) e.next()).textChanged(event);
+ }
+ }
+
+ /**
+ * Sends a text set event to all registered listeners.
+ */
+ private void fireTextSet() {
+
+ if (!fIsForwarding)
+ return;
+
+ TextChangedEvent event = TextChangedEvent.textSet(this);
+
+ if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) {
+ Iterator e= new ArrayList(fTextChangeListeners).iterator();
+ while (e.hasNext())
+ ((TextChangeListener) e.next()).textSet(event);
+ }
+ }
+
+ /**
+ * Sends the text changing event to all registered listeners.
+ */
+ private void fireTextChanging() {
+
+ if (!fIsForwarding)
+ return;
+
+ try {
+ IDocument document= fEvent.getDocument();
+ if (document == null)
+ return;
+
+ TextChangingEvent event= TextChangingEvent.textChanging(this,
+ fEvent.fOffset,
+ fEvent.fLength,
+ document.getNumberOfLines(fEvent.fOffset, fEvent.fLength) - 1,
+ fEvent.fText,
+ (fEvent.fText == null ? 0 : fEvent.fText.length()),
+ (fEvent.fText == null ? 0 : document.computeNumberOfLines(fEvent.fText)));
+
+ if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) {
+ Iterator e= new ArrayList(fTextChangeListeners).iterator();
+ while (e.hasNext())
+ ((TextChangeListener) e.next()).textChanging(event);
+ }
+
+ } catch (BadLocationException e) {
+ }
+ }
+
+ /*
+ * @see IDocumentAdapterExtension#resumeForwardingDocumentChanges()
+ * @since 2.0
+ */
+ public void resumeForwardingDocumentChanges() {
+ fIsForwarding= true;
+ fDocumentClone= null;
+ fOriginalContent= null;
+ fOriginalLineDelimiters= null;
+ fireTextSet();
+ }
+
+ /*
+ * @see IDocumentAdapterExtension#stopForwardingDocumentChanges()
+ * @since 2.0
+ */
+ public void stopForwardingDocumentChanges() {
+ fDocumentClone= null;
+ fOriginalContent= fDocument.get();
+ fOriginalLineDelimiters= fDocument.getLegalLineDelimiters();
+ fIsForwarding= false;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java
new file mode 100644
index 000000000..55a9b094b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import org.eclipse.fx.ui.controls.styledtext.StyledTextContent;
+
+
+/**
+ * Adapts an {@link org.eclipse.jface.text.IDocument}to the
+ * {@link org.eclipse.swt.custom.StyledTextContent} interface. The document
+ * adapter is used by {@link org.eclipse.jface.text.TextViewer} to translate
+ * document changes into styled text content changes and vice versa.
+ * <p>
+ * Clients may implement this interface and override
+ * <code>TextViewer.createDocumentAdapter</code> if they want to intercept the
+ * communication between the viewer's text widget and the viewer's document.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IDocumentAdapter</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link org.eclipse.jface.text.IDocumentAdapterExtension} since version
+ * 2.0 introducing a way of batching a sequence of document changes into a
+ * single styled text content notification</li>
+ * </ul>
+ *
+ * @see org.eclipse.jface.text.IDocumentAdapterExtension
+ * @see org.eclipse.jface.text.IDocument
+ */
+public interface IDocumentAdapter extends StyledTextContent {
+
+ /**
+ * Sets the adapters document.
+ *
+ * @param document the document to be adapted
+ */
+ void setDocument(IDocument document);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java
new file mode 100644
index 000000000..160ee3e40
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text;
+
+/**
+ * Extension interface for {@link org.eclipse.jface.text.IDocumentAdapter}.
+ * <p>
+ * Introduces the concepts of batching a series of document changes into a
+ * single styled text content change notification. Batching start when a client
+ * calls <code>stopForwardingDocumentChanges</code>. After that call this
+ * document adapter does not send out styled text content change notifications
+ * until <code>resumeForwardingDocumentChanges</code> is called. On
+ * <code>resumeForwardingDocumentChanges</code>, it sends out one styled text
+ * content change notification that covers all changes that have been applied to
+ * the document since calling <code>stopForwardingDocumentChanges</code>.
+ *
+ * @since 2.0
+ */
+public interface IDocumentAdapterExtension {
+
+ /**
+ * Stops forwarding document changes to the styled text.
+ */
+ void stopForwardingDocumentChanges();
+
+ /**
+ * Resumes forwarding document changes to the styled text.
+ * Also forces the styled text to catch up with all the changes
+ * that have been applied since <code>stopForwardingDocumentChanges</code>
+ * has been called.
+ */
+ void resumeForwardingDocumentChanges();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java
new file mode 100644
index 000000000..0f698dc77
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+ /**
+ * A target publishing the required functions to modify a document that is displayed
+ * in a text viewer. It provides access to the document and control
+ * over the redraw behavior and the grouping of document changes into undo commands.
+ *
+ * @see org.eclipse.jface.text.ITextViewer
+ * @see org.eclipse.jface.text.IDocument
+ * @see org.eclipse.jface.text.IUndoManager
+ * @since 2.0
+ */
+public interface IRewriteTarget {
+
+ /**
+ * Returns the document of this target.
+ *
+ * @return the document of this target
+ */
+ IDocument getDocument();
+
+ /**
+ * Disables/enables redrawing while modifying the target's document.
+ *
+ * @param redraw <code>true</code> if the document's visible presentation
+ * should be updated, <code>false</code> otherwise
+ */
+ void setRedraw(boolean redraw);
+
+ /**
+ * If an undo manager is connected to the document's visible presentation,
+ * this method tells the undo manager to fold all subsequent changes into
+ * one single undo command until <code>endCompoundChange</code> is called.
+ */
+ void beginCompoundChange();
+
+ /**
+ * If an undo manager is connected to the document's visible presentation,
+ * this method tells the undo manager to stop the folding of changes into a
+ * single undo command. After this call, all subsequent changes are
+ * considered to be individually undo-able.
+ */
+ void endCompoundChange();
+}
+
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java
new file mode 100644
index 000000000..44f6d3739
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+
+/**
+ * Text input listeners registered with an
+ * {@link org.eclipse.jface.text.ITextViewer} are informed if the document
+ * serving as the text viewer's model is replaced.
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see org.eclipse.jface.text.ITextViewer
+ * @see org.eclipse.jface.text.IDocument
+ */
+public interface ITextInputListener {
+
+ /**
+ * Called before the input document is replaced.
+ *
+ * @param oldInput the text viewer's previous input document
+ * @param newInput the text viewer's new input document
+ */
+ void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput);
+
+ /**
+ * Called after the input document has been replaced.
+ *
+ * @param oldInput the text viewer's previous input document
+ * @param newInput the text viewer's new input document
+ */
+ void inputDocumentChanged(IDocument oldInput, IDocument newInput);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java
new file mode 100644
index 000000000..64d944166
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+
+/**
+ * Text listeners registered with a text viewer are informed about all
+ * modifications of an {@link org.eclipse.jface.text.ITextViewer} by means of
+ * text events. A text event describes a change as a replace operation.
+ * <p>
+ * The changes described in the event are the changes applied to the text
+ * viewer's widget (i.e., its visual representation) and not those applied to the
+ * text viewer's document. The text event can be asked to return the
+ * corresponding document event. If the text event does not contain a document
+ * event, the modification of the text viewer is a presentation change. For
+ * example, changing the visible region of a text viewer, is a presentation
+ * change. A completely empty text event represents a change of the viewer's
+ * redraw state.</p>
+ * <p>
+ * If a text listener receives a text event, it is guaranteed that both the
+ * document and the viewer's visual representation are synchronized.</p>
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see org.eclipse.jface.text.ITextViewer
+ * @see org.eclipse.jface.text.TextEvent
+ * @see org.eclipse.jface.text.DocumentEvent
+ */
+public interface ITextListener {
+
+ /**
+ * The visual representation of a text viewer this listener is registered with
+ * has been changed.
+ *
+ * @param event the description of the change
+ */
+ void textChanged(TextEvent event);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java
new file mode 100644
index 000000000..839c87477
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+/**
+ * Text presentation listeners registered with an
+ * {@link org.eclipse.jface.text.ITextViewer} are informed when a
+ * {@link org.eclipse.jface.text.TextPresentation} is about to be applied to the
+ * text viewer. The listener can apply changes to the text presentation and thus
+ * participate in the process of text presentation creation.
+ *
+ * @since 3.0
+ */
+public interface ITextPresentationListener {
+
+ /**
+ * This method is called when a text presentation is about to be applied to
+ * the text viewer. The receiver is allowed to change the text presentation
+ * during that call.
+ *
+ * @param textPresentation the current text presentation
+ */
+ public void applyTextPresentation(TextPresentation textPresentation);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java
new file mode 100644
index 000000000..5508c2ac4
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java
@@ -0,0 +1,12 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewer {
+ public IDocument getDocument();
+ public void setDocument(IDocument document);
+ public IRegion getVisibleRegion();
+ void addTextListener(ITextListener listener);
+ public void removeTextListener(ITextListener listener);
+ void addTextInputListener(ITextInputListener listener);
+ void removeTextInputListener(ITextInputListener listener);
+ void changeTextPresentation(TextPresentation presentation, boolean controlRedraw);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java
new file mode 100644
index 000000000..ab8ff8b3d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java
new file mode 100644
index 000000000..80730e025
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension2 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java
new file mode 100644
index 000000000..82adc0d3f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+/**
+ * Extension interface for {@link org.eclipse.jface.text.ITextViewer}. <p>
+ * This interface has been replaced by {@link org.eclipse.jface.text.ITextViewerExtension5}.
+ * Clients are not supposed to use this interface any longer.
+ *
+ * @since 2.1
+ * @deprecated replaced by {@link org.eclipse.jface.text.ITextViewerExtension5}
+ */
+public interface ITextViewerExtension3 {
+
+
+ /**
+ * Returns the minimal region of the viewer's document that completely comprises everything that is
+ * visible in the viewer's widget or <code>null</code> if there is no such region.
+ *
+ * @return the minimal region of the viewer's document comprising the contents of the viewer's widget or <code>null</code>
+ */
+ IRegion getModelCoverage();
+
+
+ /**
+ * Returns the widget line that corresponds to the given line of the viewer's document or <code>-1</code> if there is no such line.
+ *
+ * @param modelLine the line of the viewer's document
+ * @return the corresponding widget line or <code>-1</code>
+ */
+ int modelLine2WidgetLine(int modelLine);
+
+ /**
+ * Returns the widget offset that corresponds to the given offset in the viewer's document
+ * or <code>-1</code> if there is no such offset
+ *
+ * @param modelOffset the offset in the viewer's document
+ * @return the corresponding widget offset or <code>-1</code>
+ */
+ int modelOffset2WidgetOffset(int modelOffset);
+
+ /**
+ * Returns the minimal region of the viewer's widget that completely comprises the given region of the
+ * viewer's document or <code>null</code> if there is no such region.
+ *
+ * @param modelRange the region of the viewer's document
+ * @return the minimal region of the widget comprising <code>modelRange</code> or <code>null</code>
+ */
+ IRegion modelRange2WidgetRange(IRegion modelRange);
+
+
+ /**
+ * Returns the offset of the viewer's document that corresponds to the given widget offset
+ * or <code>-1</code> if there is no such offset
+ *
+ * @param widgetOffset the widget offset
+ * @return the corresponding offset in the viewer's document or <code>-1</code>
+ */
+ int widgetOffset2ModelOffset(int widgetOffset);
+
+ /**
+ * Returns the minimal region of the viewer's document that completely comprises the given widget region
+ * or <code>null</code> if there is no such region.
+ *
+ * @param widgetRange the widget region
+ * @return the minimal region of the viewer's document comprising <code>widgetRange</code> or <code>null</code>
+ */
+ IRegion widgetRange2ModelRange(IRegion widgetRange);
+
+ /**
+ * Returns the line of the viewer's document that corresponds to the given widget line or <code>-1</code> if there is no such line.
+ *
+ * @param widgetLine the widget line
+ * @return the corresponding line of the viewer's document or <code>-1</code>
+ */
+ int widgetlLine2ModelLine(int widgetLine);
+
+ /**
+ * Returns the widget line of the given widget offset.
+ *
+ * @param widgetOffset the widget offset
+ * @return the widget line of the widget offset
+ */
+ int widgetLineOfWidgetOffset(int widgetOffset);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java
new file mode 100644
index 000000000..e04cb953b
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension4 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java
new file mode 100644
index 000000000..206cfc3ce
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+/**
+ * Extension interface for {@link org.eclipse.jface.text.ITextViewer}. Defines
+ * a conceptual replacement of the original visible region concept. This interface
+ * replaces {@link org.eclipse.jface.text.ITextViewerExtension3}.
+ * <p>
+ * Introduces the explicit concept of model and widget coordinates. For example,
+ * a selection returned by the text viewer's control is a widget selection. A
+ * widget selection always maps to a certain range of the viewer's document.
+ * This range is considered the model selection.
+ * <p>
+ * All model ranges that have a corresponding widget ranges are considered
+ * "exposed model ranges". The viewer can be requested to expose a given model
+ * range. Thus, a visible region is a particular degeneration of exposed model
+ * ranges.
+ * <p>
+ * This interface allows implementers to follow a sophisticated presentation
+ * model in which the visible presentation is a complex projection of the
+ * viewer's input document.
+ *
+ * @since 3.0
+ */
+public interface ITextViewerExtension5 extends ITextViewerExtension3 {
+
+ /**
+ * Returns the minimal region of the viewer's input document that completely
+ * comprises everything that is visible in the viewer's widget or
+ * <code>null</code> if there is no such region.
+ *
+ * @return the minimal region of the viewer's document comprising the
+ * contents of the viewer's widget or <code>null</code>
+ */
+ IRegion getModelCoverage();
+
+ /**
+ * Returns the widget line that corresponds to the given line of the
+ * viewer's input document or <code>-1</code> if there is no such line.
+ *
+ * @param modelLine the line of the viewer's document
+ * @return the corresponding widget line or <code>-1</code>
+ */
+ int modelLine2WidgetLine(int modelLine);
+
+ /**
+ * Returns the widget offset that corresponds to the given offset in the
+ * viewer's input document or <code>-1</code> if there is no such offset
+ *
+ * @param modelOffset the offset in the viewer's document
+ * @return the corresponding widget offset or <code>-1</code>
+ */
+ int modelOffset2WidgetOffset(int modelOffset);
+
+ /**
+ * Returns the minimal region of the viewer's widget that completely
+ * comprises the given region of the viewer's input document or
+ * <code>null</code> if there is no such region.
+ *
+ * @param modelRange the region of the viewer's document
+ * @return the minimal region of the widget comprising
+ * <code>modelRange</code> or <code>null</code>
+ */
+ IRegion modelRange2WidgetRange(IRegion modelRange);
+
+ /**
+ * Returns the offset of the viewer's input document that corresponds to the
+ * given widget offset or <code>-1</code> if there is no such offset
+ *
+ * @param widgetOffset the widget offset
+ * @return the corresponding offset in the viewer's document or
+ * <code>-1</code>
+ */
+ int widgetOffset2ModelOffset(int widgetOffset);
+
+ /**
+ * Returns the minimal region of the viewer's input document that completely
+ * comprises the given widget region or <code>null</code> if there is no
+ * such region.
+ *
+ * @param widgetRange the widget region
+ * @return the minimal region of the viewer's document comprising
+ * <code>widgetlRange</code> or <code>null</code>
+ */
+ IRegion widgetRange2ModelRange(IRegion widgetRange);
+
+ /**
+ * Returns the line of the viewer's input document that corresponds to the
+ * given widget line or <code>-1</code> if there is no such line.
+ *
+ * @param widgetLine the widget line
+ * @return the corresponding line of the viewer's document or
+ * <code>-1</code>
+ */
+ int widgetLine2ModelLine(int widgetLine);
+
+ /**
+ * Returns the widget line of the given widget offset.
+ *
+ * @param widgetOffset the widget offset
+ * @return the widget line of the widget offset
+ */
+ int widgetLineOfWidgetOffset(int widgetOffset);
+
+
+ /**
+ * Returns the maximal subranges of the given model range thus that there is
+ * no offset inside a subrange for which there is no image offset.
+ *
+ * @param modelRange the model range
+ * @return the list of subranges
+ */
+ IRegion[] getCoveredModelRanges(IRegion modelRange);
+
+ /**
+ * Exposes the given model range. Returns whether this call caused a change
+ * of the set of exposed model ranges.
+ *
+ * @param modelRange the model range to be exposed
+ * @return <code>true</code> if the set of exposed model ranges changed,
+ * <code>false</code> otherwise
+ */
+ boolean exposeModelRange(IRegion modelRange);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java
new file mode 100644
index 000000000..9024869b6
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension6 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java
new file mode 100644
index 000000000..4cf21ff40
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension7 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java
new file mode 100644
index 000000000..bb4b986f7
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text;
+
+public interface ITextViewerExtension8 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java
new file mode 100644
index 000000000..573183899
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+
+
+/**
+ * Description of textual attributes such as color and style. Text attributes
+ * are considered value objects.
+ * <p>
+ * Clients usually instantiate object of the class.</p>
+ */
+public class TextAttribute {
+
+ /**
+ * Text attribute for strikethrough style.
+ * (value <code>1 << 29</code>).
+ * @since 3.1
+ */
+ public static final int STRIKETHROUGH= 1 << 29;
+
+ /**
+ * Text attribute for underline style.
+ * (value <code>1 << 30</code>)
+ * @since 3.1
+ */
+ public static final int UNDERLINE= 1 << 30;
+
+
+ /** Foreground color */
+ private Color foreground;
+
+ /** Background color */
+ private Color background;
+
+ /** The text style */
+ private int style;
+
+ /**
+ * The text font.
+ * @since 3.3
+ */
+ private Font font;
+
+ /**
+ * Cached hash code.
+ * @since 3.3
+ */
+ private int fHashCode;
+
+ /**
+ * Creates a text attribute with the given colors and style.
+ *
+ * @param foreground the foreground color, <code>null</code> if none
+ * @param background the background color, <code>null</code> if none
+ * @param style the style
+ */
+ public TextAttribute(Color foreground, Color background, int style) {
+ this.foreground= foreground;
+ this.background= background;
+ this.style= style;
+ }
+
+ /**
+ * Creates a text attribute with the given colors and style.
+ *
+ * @param foreground the foreground color, <code>null</code> if none
+ * @param background the background color, <code>null</code> if none
+ * @param style the style
+ * @param font the font, <code>null</code> if none
+ * @since 3.3
+ */
+ public TextAttribute(Color foreground, Color background, int style, Font font) {
+ this.foreground= foreground;
+ this.background= background;
+ this.style= style;
+ this.font= font;
+ }
+
+ /**
+ * Creates a text attribute for the given foreground color, no background color and
+ * with the SWT normal style.
+ *
+ * @param foreground the foreground color, <code>null</code> if none
+ */
+ public TextAttribute(Color foreground) {
+ this(foreground, null, StyleRange.NORMAL);
+ }
+
+ /*
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+
+ if (object == this)
+ return true;
+
+ if (!(object instanceof TextAttribute))
+ return false;
+ TextAttribute a= (TextAttribute)object;
+
+ return (a.style == style && equals(a.foreground, foreground) && equals(a.background, background) && equals(a.font, font));
+ }
+
+ /**
+ * Returns whether the two given objects are equal.
+ *
+ * @param o1 the first object, can be <code>null</code>
+ * @param o2 the second object, can be <code>null</code>
+ * @return <code>true</code> if the given objects are equals
+ * @since 2.0
+ */
+ private boolean equals(Object o1, Object o2) {
+ if (o1 != null)
+ return o1.equals(o2);
+ return (o2 == null);
+ }
+
+ /*
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ if (fHashCode == 0) {
+ int multiplier= 37; // some prime
+ fHashCode= 13; // some random value
+ fHashCode= multiplier * fHashCode + (font == null ? 0 : font.hashCode());
+ fHashCode= multiplier * fHashCode + (background == null ? 0 : background.hashCode());
+ fHashCode= multiplier * fHashCode + (foreground == null ? 0 : foreground.hashCode());
+ fHashCode= multiplier * fHashCode + style;
+ }
+ return fHashCode;
+ }
+
+ /**
+ * Returns the attribute's foreground color.
+ *
+ * @return the attribute's foreground color or <code>null</code> if not set
+ */
+ public Color getForeground() {
+ return foreground;
+ }
+
+ /**
+ * Returns the attribute's background color.
+ *
+ * @return the attribute's background color or <code>null</code> if not set
+ */
+ public Color getBackground() {
+ return background;
+ }
+
+ /**
+ * Returns the attribute's style.
+ *
+ * @return the attribute's style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Returns the attribute's font.
+ *
+ * @return the attribute's font or <code>null</code> if not set
+ * @since 3.3
+ */
+ public Font getFont() {
+ return font;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java
new file mode 100644
index 000000000..617d0e23e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+
+/**
+ * This event is sent to implementers of
+ * {@link org.eclipse.jface.text.ITextListener}. It represents a change applied
+ * to text viewer. The change is specified as a replace command using offset,
+ * length, inserted text, and replaced text. The text viewer issues a text event
+ * after the viewer has been changed either in response to a change of the
+ * viewer's document or when the viewer's visual content has been changed. In
+ * the first case, the text event also carries the original document event.
+ * Depending on the viewer's presentation mode, the text event coordinates are
+ * different from the document event's coordinates.
+ * <p>
+ * An empty text event usually indicates a change of the viewer's redraw state.</p>
+ * <p>
+ * Clients other than text viewer's don't create instances of this class.</p>
+ *
+ * @see org.eclipse.jface.text.ITextListener
+ * @see org.eclipse.jface.text.ITextViewer
+ * @see org.eclipse.jface.text.DocumentEvent
+ */
+public class TextEvent {
+
+ /** Start offset of the change */
+ private int fOffset;
+ /** The length of the change */
+ private int fLength;
+ /** Inserted text */
+ private String fText;
+ /** Replaced text */
+ private String fReplacedText;
+ /** The original document event, may by null */
+ private DocumentEvent fDocumentEvent;
+ /**
+ * The redraw state of the viewer issuing this event
+ * @since 2.0
+ */
+ private boolean fViewerRedrawState;
+
+ /**
+ * Creates a new <code>TextEvent</code> based on the specification.
+ *
+ * @param offset the offset
+ * @param length the length
+ * @param text the inserted text
+ * @param replacedText the replaced text
+ * @param event the associated document event or <code>null</code> if none
+ * @param viewerRedrawState the redraw state of the viewer
+ */
+ protected TextEvent(int offset, int length, String text, String replacedText, DocumentEvent event, boolean viewerRedrawState) {
+ fOffset= offset;
+ fLength= length;
+ fText= text;
+ fReplacedText= replacedText;
+ fDocumentEvent= event;
+ fViewerRedrawState= viewerRedrawState;
+ }
+
+ /**
+ * Returns the offset of the event.
+ *
+ * @return the offset of the event
+ */
+ public int getOffset() {
+ return fOffset;
+ }
+
+ /**
+ * Returns the length of the event.
+ *
+ * @return the length of the event
+ */
+ public int getLength() {
+ return fLength;
+ }
+
+ /**
+ * Returns the text of the event.
+ *
+ * @return the text of the event
+ */
+ public String getText() {
+ return fText;
+ }
+
+ /**
+ * Returns the text replaced by this event.
+ *
+ * @return the text replaced by this event
+ */
+ public String getReplacedText() {
+ return fReplacedText;
+ }
+
+ /**
+ * Returns the corresponding document event that caused the viewer change
+ *
+ * @return the corresponding document event, <code>null</code> if a visual change only
+ */
+ public DocumentEvent getDocumentEvent() {
+ return fDocumentEvent;
+ }
+
+ /**
+ * Returns the viewer's redraw state.
+ *
+ * @return <code>true</code> if the viewer's redraw state is <code>true</code>
+ * @since 2.0
+ */
+ public boolean getViewerRedrawState() {
+ return fViewerRedrawState;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java
new file mode 100644
index 000000000..92b982f80
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java
@@ -0,0 +1,731 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+import org.eclipse.fx.ui.controls.styledtext.StyledTextArea;
+
+
+/**
+ * Describes the presentation styles for a section of an indexed text such as a
+ * document or string. A text presentation defines a default style for the whole
+ * section and in addition style differences for individual subsections. Text
+ * presentations can be narrowed down to a particular result window. All methods
+ * are result window aware, i.e. ranges outside the result window are always
+ * ignored.
+ * <p>
+ * All iterators provided by a text presentation assume that they enumerate non
+ * overlapping, consecutive ranges inside the default range. Thus, all these
+ * iterators do not include the default range. The default style range must be
+ * explicitly asked for using <code>getDefaultStyleRange</code>.
+ */
+public class TextPresentation {
+
+ /**
+ * Applies the given presentation to the given text widget. Helper method.
+ *
+ * @param presentation the style information
+ * @param text the widget to which to apply the style information
+ * @since 2.0
+ */
+ public static void applyTextPresentation(TextPresentation presentation, StyledTextArea text) {
+
+ StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];
+
+ int i= 0;
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext())
+ ranges[i++]= (StyleRange) e.next();
+
+ text.setStyleRanges(ranges);
+ }
+
+
+
+
+ /**
+ * Enumerates all the <code>StyleRange</code>s included in the presentation.
+ */
+ class FilterIterator implements Iterator {
+
+ /** The index of the next style range to be enumerated */
+ protected int fIndex;
+ /** The upper bound of the indices of style ranges to be enumerated */
+ protected int fLength;
+ /** Indicates whether ranges similar to the default range should be enumerated */
+ protected boolean fSkipDefaults;
+ /** The result window */
+ protected IRegion fWindow;
+
+ /**
+ * <code>skipDefaults</code> tells the enumeration to skip all those style ranges
+ * which define the same style as the presentation's default style range.
+ *
+ * @param skipDefaults <code>false</code> if ranges similar to the default range should be enumerated
+ */
+ protected FilterIterator(boolean skipDefaults) {
+
+ fSkipDefaults= skipDefaults;
+
+ fWindow= fResultWindow;
+ fIndex= getFirstIndexInWindow(fWindow);
+ fLength= getFirstIndexAfterWindow(fWindow);
+
+ if (fSkipDefaults)
+ computeIndex();
+ }
+
+ /*
+ * @see Iterator#next()
+ */
+ public Object next() {
+ try {
+ StyleRange r= (StyleRange) fRanges.get(fIndex++);
+ return createWindowRelativeRange(fWindow, r);
+ } catch (ArrayIndexOutOfBoundsException x) {
+ throw new NoSuchElementException();
+ } finally {
+ if (fSkipDefaults)
+ computeIndex();
+ }
+ }
+
+ /*
+ * @see Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return fIndex < fLength;
+ }
+
+ /*
+ * @see Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns whether the given object should be skipped.
+ *
+ * @param o the object to be checked
+ * @return <code>true</code> if the object should be skipped by the iterator
+ */
+ protected boolean skip(Object o) {
+ StyleRange r= (StyleRange) o;
+ return r.similarTo(fDefaultRange);
+ }
+
+ /**
+ * Computes the index of the styled range that is the next to be enumerated.
+ */
+ protected void computeIndex() {
+ while (fIndex < fLength && skip(fRanges.get(fIndex)))
+ ++ fIndex;
+ }
+ }
+
+ /** The style information for the range covered by the whole presentation */
+ private StyleRange fDefaultRange;
+ /** The member ranges of the presentation */
+ private ArrayList fRanges;
+ /** A clipping region against which the presentation can be clipped when asked for results */
+ private IRegion fResultWindow;
+ /**
+ * The optional extent for this presentation.
+ * @since 3.0
+ */
+ private IRegion fExtent;
+
+
+ /**
+ * Creates a new empty text presentation.
+ */
+ public TextPresentation() {
+ fRanges= new ArrayList(50);
+ }
+
+ /**
+ * Creates a new empty text presentation. <code>sizeHint</code> tells the expected size of this
+ * presentation.
+ *
+ * @param sizeHint the expected size of this presentation, must be positive
+ */
+ public TextPresentation(int sizeHint) {
+ Assert.isTrue(sizeHint > 0);
+ fRanges= new ArrayList(sizeHint);
+ }
+
+ /**
+ * Creates a new empty text presentation with the given extent. <code>sizeHint</code> tells the
+ * expected size of this presentation.
+ *
+ * @param extent the extent of the created <code>TextPresentation</code>
+ * @param sizeHint the expected size of this presentation, must be positive
+ * @since 3.0
+ */
+ public TextPresentation(IRegion extent, int sizeHint) {
+ this(sizeHint);
+ Assert.isNotNull(extent);
+ fExtent= extent;
+ }
+
+ /**
+ * Sets the result window for this presentation. When dealing with
+ * this presentation all ranges which are outside the result window
+ * are ignored. For example, the size of the presentation is 0
+ * when there is no range inside the window even if there are ranges
+ * outside the window. All methods are aware of the result window.
+ *
+ * @param resultWindow the result window
+ */
+ public void setResultWindow(IRegion resultWindow) {
+ fResultWindow= resultWindow;
+ }
+
+ /**
+ * Set the default style range of this presentation.
+ * The default style range defines the overall area covered
+ * by this presentation and its style information.
+ *
+ * @param range the range describing the default region
+ */
+ public void setDefaultStyleRange(StyleRange range) {
+ fDefaultRange= range;
+ }
+
+ /**
+ * Returns this presentation's default style range. The returned <code>StyleRange</code>
+ * is relative to the start of the result window.
+ *
+ * @return this presentation's default style range
+ */
+ public StyleRange getDefaultStyleRange() {
+ StyleRange range= createWindowRelativeRange(fResultWindow, fDefaultRange);
+ if (range == null)
+ return null;
+ return (StyleRange)range.clone();
+
+ }
+
+ /**
+ * Add the given range to the presentation. The range must be a
+ * subrange of the presentation's default range.
+ *
+ * @param range the range to be added
+ */
+ public void addStyleRange(StyleRange range) {
+ checkConsistency(range);
+ fRanges.add(range);
+ }
+
+ /**
+ * Replaces the given range in this presentation. The range must be a
+ * subrange of the presentation's default range.
+ *
+ * @param range the range to be added
+ * @since 3.0
+ */
+ public void replaceStyleRange(StyleRange range) {
+ applyStyleRange(range, false);
+ }
+
+ /**
+ * Merges the given range into this presentation. The range must be a
+ * subrange of the presentation's default range.
+ *
+ * @param range the range to be added
+ * @since 3.0
+ */
+ public void mergeStyleRange(StyleRange range) {
+ applyStyleRange(range, true);
+ }
+
+ /**
+ * Applies the given range to this presentation. The range must be a
+ * subrange of the presentation's default range.
+ *
+ * @param range the range to be added
+ * @param merge <code>true</code> if the style should be merged instead of replaced
+ * @since 3.0
+ */
+ private void applyStyleRange(StyleRange range, boolean merge) {
+ if (range.length == 0)
+ return;
+
+ checkConsistency(range);
+
+ int start= range.start;
+ int length= range.length;
+ int end= start + length;
+
+ if (fRanges.size() == 0) {
+ StyleRange defaultRange= getDefaultStyleRange();
+ if (defaultRange == null)
+ defaultRange= range;
+
+ defaultRange.start= start;
+ defaultRange.length= length;
+ applyStyle(range, defaultRange, merge);
+ fRanges.add(defaultRange);
+ } else {
+ IRegion rangeRegion= new Region(start, length);
+ int first= getFirstIndexInWindow(rangeRegion);
+
+ if (first == fRanges.size()) {
+ StyleRange defaultRange= getDefaultStyleRange();
+ if (defaultRange == null)
+ defaultRange= range;
+ defaultRange.start= start;
+ defaultRange.length= length;
+ applyStyle(range, defaultRange, merge);
+ fRanges.add(defaultRange);
+ return;
+ }
+
+ int last= getFirstIndexAfterWindow(rangeRegion);
+ for (int i= first; i < last && length > 0; i++) {
+
+ StyleRange current= (StyleRange)fRanges.get(i);
+ int currentStart= current.start;
+ int currentEnd= currentStart + current.length;
+
+ if (end <= currentStart) {
+ fRanges.add(i, range);
+ return;
+ }
+
+ if (start >= currentEnd)
+ continue;
+
+ StyleRange currentCopy= null;
+ if (end < currentEnd)
+ currentCopy= (StyleRange)current.clone();
+
+ if (start < currentStart) {
+ // Apply style to new default range and add it
+ StyleRange defaultRange= getDefaultStyleRange();
+ if (defaultRange == null)
+ defaultRange= new StyleRange();
+
+ defaultRange.start= start;
+ defaultRange.length= currentStart - start;
+ applyStyle(range, defaultRange, merge);
+ fRanges.add(i, defaultRange);
+ i++; last++;
+
+
+ // Apply style to first part of current range
+ current.length= Math.min(end, currentEnd) - currentStart;
+ applyStyle(range, current, merge);
+ }
+
+ if (start >= currentStart) {
+ // Shorten the current range
+ current.length= start - currentStart;
+
+ // Apply the style to the rest of the current range and add it
+ if (current.length > 0) {
+ current= (StyleRange)current.clone();
+ i++; last++;
+ fRanges.add(i, current);
+ }
+ applyStyle(range, current, merge);
+ current.start= start;
+ current.length= Math.min(end, currentEnd) - start;
+ }
+
+ if (end < currentEnd) {
+ // Add rest of current range
+ currentCopy.start= end;
+ currentCopy.length= currentEnd - end;
+ i++; last++;
+ fRanges.add(i, currentCopy);
+ }
+
+ // Update range
+ range.start= currentEnd;
+ range.length= Math.max(end - currentEnd, 0);
+ start= range.start;
+ length= range.length;
+ }
+ if (length > 0) {
+ // Apply style to new default range and add it
+ StyleRange defaultRange= getDefaultStyleRange();
+ if (defaultRange == null)
+ defaultRange= range;
+ defaultRange.start= start;
+ defaultRange.length= end - start;
+ applyStyle(range, defaultRange, merge);
+ fRanges.add(last, defaultRange);
+ }
+ }
+ }
+
+ /**
+ * Replaces the given ranges in this presentation. Each range must be a
+ * subrange of the presentation's default range. The ranges must be ordered
+ * by increasing offset and must not overlap (but may be adjacent).
+ *
+ * @param ranges the ranges to be added
+ * @since 3.0
+ */
+ public void replaceStyleRanges(StyleRange[] ranges) {
+ applyStyleRanges(ranges, false);
+ }
+
+ /**
+ * Merges the given ranges into this presentation. Each range must be a
+ * subrange of the presentation's default range. The ranges must be ordered
+ * by increasing offset and must not overlap (but may be adjacent).
+ *
+ * @param ranges the ranges to be added
+ * @since 3.0
+ */
+ public void mergeStyleRanges(StyleRange[] ranges) {
+ applyStyleRanges(ranges, true);
+ }
+
+ /**
+ * Applies the given ranges to this presentation. Each range must be a
+ * subrange of the presentation's default range. The ranges must be ordered
+ * by increasing offset and must not overlap (but may be adjacent).
+ *
+ * @param ranges the ranges to be added
+ * @param merge <code>true</code> if the style should be merged instead of replaced
+ * @since 3.0
+ */
+ private void applyStyleRanges(StyleRange[] ranges, boolean merge) {
+ int j= 0;
+ ArrayList oldRanges= fRanges;
+ ArrayList newRanges= new ArrayList(2*ranges.length + oldRanges.size());
+ for (int i= 0, n= ranges.length; i < n; i++) {
+ StyleRange range= ranges[i];
+ fRanges= oldRanges; // for getFirstIndexAfterWindow(...)
+ for (int m= getFirstIndexAfterWindow(new Region(range.start, range.length)); j < m; j++)
+ newRanges.add(oldRanges.get(j));
+ fRanges= newRanges; // for mergeStyleRange(...)
+ applyStyleRange(range, merge);
+ }
+ for (int m= oldRanges.size(); j < m; j++)
+ newRanges.add(oldRanges.get(j));
+ fRanges= newRanges;
+ }
+
+ /**
+ * Applies the template's style to the target.
+ *
+ * @param template the style range to be used as template
+ * @param target the style range to which to apply the template
+ * @param merge <code>true</code> if the style should be merged instead of replaced
+ * @since 3.0
+ */
+ private void applyStyle(StyleRange template, StyleRange target, boolean merge) {
+ if (merge) {
+ if (template.font != null)
+ target.font= template.font;
+ target.fontStyle|= template.fontStyle;
+
+//TODO No metrics
+// if (template.metrics != null)
+// target.metrics= template.metrics;
+
+ if (template.foreground != null || template.underlineStyle == StyleRange.UNDERLINE_LINK)
+ target.foreground= template.foreground;
+ if (template.background != null)
+ target.background= template.background;
+
+ target.strikeout|= template.strikeout;
+ if (template.strikeoutColor != null)
+ target.strikeoutColor= template.strikeoutColor;
+
+ target.underline|= template.underline;
+ if (template.underlineStyle != StyleRange.NONE && target.underlineStyle != StyleRange.UNDERLINE_LINK)
+ target.underlineStyle= template.underlineStyle;
+
+ if (template.underlineColor != null)
+ target.underlineColor= template.underlineColor;
+
+ if (template.borderStyle != StyleRange.NONE)
+ target.borderStyle= template.borderStyle;
+ if (template.borderColor != null)
+ target.borderColor= template.borderColor;
+
+ } else {
+ target.font= template.font;
+ target.fontStyle= template.fontStyle;
+// target.metrics= template.metrics;
+ target.foreground= template.foreground;
+ target.background= template.background;
+ target.strikeout= template.strikeout;
+ target.strikeoutColor= template.strikeoutColor;
+ target.underline= template.underline;
+ target.underlineStyle= template.underlineStyle;
+ target.underlineColor= template.underlineColor;
+ target.borderStyle= template.borderStyle;
+ target.borderColor= template.borderColor;
+ }
+ }
+
+ /**
+ * Checks whether the given range is a subrange of the presentation's
+ * default style range.
+ *
+ * @param range the range to be checked
+ * @exception IllegalArgumentException if range is not a subrange of the presentation's default range
+ */
+ private void checkConsistency(StyleRange range) {
+
+ if (range == null)
+ throw new IllegalArgumentException();
+
+ if (fDefaultRange != null) {
+
+ if (range.start < fDefaultRange.start)
+ range.start= fDefaultRange.start;
+
+ int defaultEnd= fDefaultRange.start + fDefaultRange.length;
+ int end= range.start + range.length;
+ if (end > defaultEnd)
+ range.length -= (end - defaultEnd);
+ }
+ }
+
+ /**
+ * Returns the index of the first range which overlaps with the
+ * specified window.
+ *
+ * @param window the window to be used for searching
+ * @return the index of the first range overlapping with the window
+ */
+ private int getFirstIndexInWindow(IRegion window) {
+ if (window != null) {
+ int start= window.getOffset();
+ int i= -1, j= fRanges.size();
+ while (j - i > 1) {
+ int k= (i + j) >> 1;
+ StyleRange r= (StyleRange) fRanges.get(k);
+ if (r.start + r.length > start)
+ j= k;
+ else
+ i= k;
+ }
+ return j;
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the index of the first range which comes after the specified window and does
+ * not overlap with this window.
+ *
+ * @param window the window to be used for searching
+ * @return the index of the first range behind the window and not overlapping with the window
+ */
+ private int getFirstIndexAfterWindow(IRegion window) {
+ if (window != null) {
+ int end= window.getOffset() + window.getLength();
+ int i= -1, j= fRanges.size();
+ while (j - i > 1) {
+ int k= (i + j) >> 1;
+ StyleRange r= (StyleRange) fRanges.get(k);
+ if (r.start < end)
+ i= k;
+ else
+ j= k;
+ }
+ return j;
+ }
+ return fRanges.size();
+ }
+
+ /**
+ * Returns a style range which is relative to the specified window and
+ * appropriately clipped if necessary. The original style range is not
+ * modified.
+ *
+ * @param window the reference window
+ * @param range the absolute range
+ * @return the window relative range based on the absolute range
+ */
+ private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) {
+ if (window == null || range == null)
+ return range;
+
+ int start= range.start - window.getOffset();
+ if (start < 0)
+ start= 0;
+
+ int rangeEnd= range.start + range.length;
+ int windowEnd= window.getOffset() + window.getLength();
+ int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
+ end -= window.getOffset();
+
+ StyleRange newRange= (StyleRange) range.clone();
+ newRange.start= start;
+ newRange.length= end - start;
+ return newRange;
+ }
+
+ /**
+ * Returns the region which is relative to the specified window and
+ * appropriately clipped if necessary.
+ *
+ * @param coverage the absolute coverage
+ * @return the window relative region based on the absolute coverage
+ * @since 3.0
+ */
+ private IRegion createWindowRelativeRegion(IRegion coverage) {
+ if (fResultWindow == null || coverage == null)
+ return coverage;
+
+ int start= coverage.getOffset() - fResultWindow.getOffset();
+ if (start < 0)
+ start= 0;
+
+ int rangeEnd= coverage.getOffset() + coverage.getLength();
+ int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength();
+ int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
+ end -= fResultWindow.getOffset();
+
+ return new Region(start, end - start);
+ }
+
+ /**
+ * Returns an iterator which enumerates all style ranged which define a style
+ * different from the presentation's default style range. The default style range
+ * is not enumerated.
+ *
+ * @return a style range iterator
+ */
+ public Iterator getNonDefaultStyleRangeIterator() {
+ return new FilterIterator(fDefaultRange != null);
+ }
+
+ /**
+ * Returns an iterator which enumerates all style ranges of this presentation
+ * except the default style range. The returned <code>StyleRange</code>s
+ * are relative to the start of the presentation's result window.
+ *
+ * @return a style range iterator
+ */
+ public Iterator getAllStyleRangeIterator() {
+ return new FilterIterator(false);
+ }
+
+ /**
+ * Returns whether this collection contains any style range including
+ * the default style range.
+ *
+ * @return <code>true</code> if there is no style range in this presentation
+ */
+ public boolean isEmpty() {
+ return (fDefaultRange == null && getDenumerableRanges() == 0);
+ }
+
+ /**
+ * Returns the number of style ranges in the presentation not counting the default
+ * style range.
+ *
+ * @return the number of style ranges in the presentation excluding the default style range
+ */
+ public int getDenumerableRanges() {
+ int size= getFirstIndexAfterWindow(fResultWindow) - getFirstIndexInWindow(fResultWindow);
+ return (size < 0 ? 0 : size);
+ }
+
+ /**
+ * Returns the style range with the smallest offset ignoring the default style range or null
+ * if the presentation is empty.
+ *
+ * @return the style range with the smallest offset different from the default style range
+ */
+ public StyleRange getFirstStyleRange() {
+ try {
+
+ StyleRange range= (StyleRange) fRanges.get(getFirstIndexInWindow(fResultWindow));
+ return createWindowRelativeRange(fResultWindow, range);
+
+ } catch (NoSuchElementException x) {
+ } catch (IndexOutOfBoundsException x) {
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the style range with the highest offset ignoring the default style range.
+ *
+ * @return the style range with the highest offset different from the default style range
+ */
+ public StyleRange getLastStyleRange() {
+ try {
+
+ StyleRange range= (StyleRange) fRanges.get(getFirstIndexAfterWindow(fResultWindow) - 1);
+ return createWindowRelativeRange(fResultWindow, range);
+
+ } catch (NoSuchElementException x) {
+ return null;
+ } catch (IndexOutOfBoundsException x) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the coverage of this presentation as clipped by the presentation's
+ * result window.
+ *
+ * @return the coverage of this presentation
+ */
+ public IRegion getCoverage() {
+
+ if (fDefaultRange != null) {
+ StyleRange range= getDefaultStyleRange();
+ return new Region(range.start, range.length);
+ }
+
+ StyleRange first= getFirstStyleRange();
+ StyleRange last= getLastStyleRange();
+
+ if (first == null || last == null)
+ return null;
+
+ return new Region(first.start, last.start - first. start + last.length);
+ }
+
+ /**
+ * Returns the extent of this presentation clipped by the
+ * presentation's result window.
+ *
+ * @return the clipped extent
+ * @since 3.0
+ */
+ public IRegion getExtent() {
+ if (fExtent != null)
+ return createWindowRelativeRegion(fExtent);
+ return getCoverage();
+ }
+
+ /**
+ * Clears this presentation by resetting all applied changes.
+ * @since 2.0
+ */
+ public void clear() {
+ fDefaultRange= null;
+ fResultWindow= null;
+ fRanges.clear();
+ }
+
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java
new file mode 100644
index 000000000..a21005da0
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java
@@ -0,0 +1,621 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2014 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Tom Eicher (Avaloq Evolution AG) - block selection mode
+ * Markus Schorn <markus.schorn@windriver.com> - shift with trailing empty line - https://bugs.eclipse.org/325438
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javafx.scene.layout.AnchorPane;
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+import org.eclipse.fx.ui.controls.styledtext.StyledTextArea;
+import org.eclipse.jface.text.projection.ChildDocument;
+import org.eclipse.jface.text.projection.ChildDocumentManager;
+import org.eclipse.jface.viewers.Viewer;
+
+public class TextViewer extends Viewer implements
+ ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, ITextViewerExtension8
+ /*,
+ IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension,
+ IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider*/ {
+ private StyledTextArea fTextWidget;
+ private IDocument fVisibleDocument;
+ private VisibleDocumentListener fVisibleDocumentListener= new VisibleDocumentListener();
+ private ISlaveDocumentManager fSlaveDocumentManager;
+ private IDocumentInformationMapping fInformationMapping;
+ private IDocumentAdapter fDocumentAdapter;
+ private WidgetCommand fWidgetCommand= new WidgetCommand();
+ protected List fTextListeners;
+ private int fRedrawCounter= 0;
+ private IRegion fLastSentSelectionChange;
+ private String fPartitioning;
+ private IDocument fDocument;
+ private boolean fReplaceTextPresentation;
+ private DocumentRewriteSessionListener fDocumentRewriteSessionListener= new DocumentRewriteSessionListener();
+ private IRewriteTarget fRewriteTarget;
+ private ViewerState fViewerState;
+ private List fTextInputListeners;
+ protected Position fMarkPosition;
+ private final String MARK_POSITION_CATEGORY="__mark_category_" + hashCode(); //$NON-NLS-1$
+ private final IPositionUpdater fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY);
+ private List fTextPresentationListeners;
+
+ public TextViewer() {
+ createControl();
+ }
+
+ protected void createControl() {
+ fTextWidget = createTextWidget();
+ AnchorPane.setLeftAnchor(fTextWidget, 0.0);
+ AnchorPane.setRightAnchor(fTextWidget, 0.0);
+ AnchorPane.setTopAnchor(fTextWidget, 0.0);
+ AnchorPane.setBottomAnchor(fTextWidget, 0.0);
+ getChildren().add(fTextWidget);
+ }
+
+ protected StyledTextArea getTextWidget() {
+ return fTextWidget;
+ }
+
+ protected StyledTextArea createTextWidget() {
+ StyledTextArea styledText= new StyledTextArea();
+// styledText.setLeftMargin(Math.max(styledText.getLeftMargin(), 2));
+ return styledText;
+ }
+
+ public void setInput(Object input) {
+
+ IDocument document= null;
+ if (input instanceof IDocument)
+ document= (IDocument) input;
+
+ setDocument(document);
+ }
+
+ public Object getInput() {
+ return getDocument();
+ }
+
+ public void setDocumentPartitioning(String partitioning) {
+ fPartitioning= partitioning;
+ }
+
+ /**
+ * Sets this viewer's visible document. The visible document represents the
+ * visible region of the viewer's input document.
+ *
+ * @param document the visible document
+ */
+ protected void setVisibleDocument(IDocument document) {
+ if (fVisibleDocument == document && fVisibleDocument instanceof ChildDocument) {
+ // optimization for new child documents
+ return;
+ }
+
+ if (fVisibleDocument != null) {
+ if (fVisibleDocumentListener != null)
+ fVisibleDocument.removeDocumentListener(fVisibleDocumentListener);
+ if (fVisibleDocument != document)
+ freeSlaveDocument(fVisibleDocument);
+ }
+
+ fVisibleDocument= document;
+ initializeDocumentInformationMapping(fVisibleDocument);
+
+ initializeWidgetContents();
+
+//TODO needs porting
+// fFindReplaceDocumentAdapter= null;
+ if (fVisibleDocument != null && fVisibleDocumentListener != null)
+ fVisibleDocument.addDocumentListener(fVisibleDocumentListener);
+ }
+
+ public IDocument getDocument() {
+ return fDocument;
+ }
+
+ public void setDocument(IDocument document) {
+ fReplaceTextPresentation= true;
+ fireInputDocumentAboutToBeChanged(fDocument, document);
+
+ IDocument oldDocument= fDocument;
+ fDocument= document;
+
+ setVisibleDocument(fDocument);
+//TODO needs porting
+// resetPlugins();
+ inputChanged(fDocument, oldDocument);
+
+ fireInputDocumentChanged(oldDocument, fDocument);
+ fLastSentSelectionChange= null;
+ fReplaceTextPresentation= false;
+ }
+
+ public IRegion getVisibleRegion() {
+
+ IDocument document= getVisibleDocument();
+ if (document instanceof ChildDocument) {
+ Position p= ((ChildDocument) document).getParentDocumentRange();
+ return new Region(p.getOffset(), p.getLength());
+ }
+
+ return new Region(0, document == null ? 0 : document.getLength());
+ }
+
+ protected void fireInputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+ List listener= fTextInputListeners;
+ if (listener != null) {
+ for (int i= 0; i < listener.size(); i++) {
+ ITextInputListener l= (ITextInputListener) listener.get(i);
+ l.inputDocumentAboutToBeChanged(oldInput, newInput);
+ }
+ }
+ }
+
+ protected void fireInputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ List listener= fTextInputListeners;
+ if (listener != null) {
+ for (int i= 0; i < listener.size(); i++) {
+ ITextInputListener l= (ITextInputListener) listener.get(i);
+ l.inputDocumentChanged(oldInput, newInput);
+ }
+ }
+ }
+
+ protected IDocument getVisibleDocument() {
+ return fVisibleDocument;
+ }
+
+ protected void freeSlaveDocument(IDocument slave) {
+ ISlaveDocumentManager manager= getSlaveDocumentManager();
+ if (manager != null && manager.isSlaveDocument(slave))
+ manager.freeSlaveDocument(slave);
+ }
+
+ protected ISlaveDocumentManager getSlaveDocumentManager() {
+ if (fSlaveDocumentManager == null)
+ fSlaveDocumentManager= createSlaveDocumentManager();
+ return fSlaveDocumentManager;
+ }
+
+ protected ISlaveDocumentManager createSlaveDocumentManager() {
+ return new ChildDocumentManager();
+ }
+
+ protected void initializeDocumentInformationMapping(IDocument visibleDocument) {
+ ISlaveDocumentManager manager= getSlaveDocumentManager();
+ fInformationMapping= manager == null ? null : manager.createMasterSlaveMapping(visibleDocument);
+ }
+
+ protected void inputChanged(Object newInput, Object oldInput) {
+
+ IDocument oldDocument= (IDocument) oldInput;
+ if (oldDocument != null) {
+
+ if (fMarkPosition != null && !fMarkPosition.isDeleted())
+ oldDocument.removePosition(fMarkPosition);
+
+ try {
+ oldDocument.removePositionUpdater(fMarkPositionUpdater);
+ oldDocument.removePositionCategory(MARK_POSITION_CATEGORY);
+
+ } catch (BadPositionCategoryException e) {
+ }
+ }
+
+ fMarkPosition= null;
+
+ if (oldDocument instanceof IDocumentExtension4) {
+ IDocumentExtension4 document= (IDocumentExtension4) oldDocument;
+ document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+ }
+
+// super.inputChanged(newInput, oldInput);
+
+ if (newInput instanceof IDocumentExtension4) {
+ IDocumentExtension4 document= (IDocumentExtension4) newInput;
+ document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+ }
+
+ IDocument newDocument= (IDocument) newInput;
+ if (newDocument != null) {
+ newDocument.addPositionCategory(MARK_POSITION_CATEGORY);
+ newDocument.addPositionUpdater(fMarkPositionUpdater);
+ }
+ }
+
+ private void initializeWidgetContents() {
+
+ if (fTextWidget != null && fVisibleDocument != null) {
+
+ // set widget content
+ if (fDocumentAdapter == null)
+ fDocumentAdapter= createDocumentAdapter();
+
+ fDocumentAdapter.setDocument(fVisibleDocument);
+ fTextWidget.setContent(fDocumentAdapter);
+ System.err.println(fDocumentAdapter);
+
+ // invalidate presentation
+ invalidateTextPresentation();
+ }
+ }
+
+ protected IDocumentAdapter createDocumentAdapter() {
+ return new DefaultDocumentAdapter();
+ }
+
+ public final void invalidateTextPresentation() {
+ if (fVisibleDocument != null) {
+ fWidgetCommand.event= null;
+ fWidgetCommand.start= 0;
+ fWidgetCommand.length= fVisibleDocument.getLength();
+ fWidgetCommand.text= fVisibleDocument.get();
+ updateTextListeners(fWidgetCommand);
+ }
+ }
+
+ protected void updateTextListeners(WidgetCommand cmd) {
+ List textListeners= fTextListeners;
+ if (textListeners != null) {
+ textListeners= new ArrayList(textListeners);
+ DocumentEvent event= cmd.event;
+ if (event instanceof SlaveDocumentEvent)
+ event= ((SlaveDocumentEvent) event).getMasterEvent();
+
+ TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws());
+ for (int i= 0; i < textListeners.size(); i++) {
+ ITextListener l= (ITextListener) textListeners.get(i);
+ l.textChanged(e);
+ }
+ }
+ }
+
+ protected final boolean redraws() {
+ return fRedrawCounter <= 0;
+ }
+
+ protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) {
+ }
+
+ protected void handleVisibleDocumentChanged(DocumentEvent event) {
+ }
+
+ public void addTextListener(ITextListener listener) {
+
+ Assert.isNotNull(listener);
+
+ if (fTextListeners == null)
+ fTextListeners= new ArrayList();
+
+ if (!fTextListeners.contains(listener))
+ fTextListeners.add(listener);
+ }
+
+ public void removeTextListener(ITextListener listener) {
+ Assert.isNotNull(listener);
+
+ if (fTextListeners != null) {
+ fTextListeners.remove(listener);
+ if (fTextListeners.size() == 0)
+ fTextListeners= null;
+ }
+ }
+
+ public void addTextInputListener(ITextInputListener listener) {
+
+ Assert.isNotNull(listener);
+
+ if (fTextInputListeners == null)
+ fTextInputListeners= new ArrayList();
+
+ if (!fTextInputListeners.contains(listener))
+ fTextInputListeners.add(listener);
+ }
+
+ public void removeTextInputListener(ITextInputListener listener) {
+
+ Assert.isNotNull(listener);
+
+ if (fTextInputListeners != null) {
+ fTextInputListeners.remove(listener);
+ if (fTextInputListeners.size() == 0)
+ fTextInputListeners= null;
+ }
+ }
+
+ public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) {
+
+ if (presentation == null || !redraws())
+ return;
+
+ if (fTextWidget == null)
+ return;
+
+
+ /*
+ * Call registered text presentation listeners
+ * and let them apply their presentation.
+ */
+ if (fTextPresentationListeners != null) {
+ ArrayList listeners= new ArrayList(fTextPresentationListeners);
+ for (int i= 0, size= listeners.size(); i < size; i++) {
+ ITextPresentationListener listener= (ITextPresentationListener)listeners.get(i);
+ listener.applyTextPresentation(presentation);
+ }
+ }
+
+ if (presentation.isEmpty())
+ return;
+
+ if (controlRedraw)
+ fTextWidget.setRedraw(false);
+
+ if (fReplaceTextPresentation)
+ applyTextPresentation(presentation);
+ else
+ addPresentation(presentation);
+
+ if (controlRedraw)
+ fTextWidget.setRedraw(true);
+ }
+
+ private void addPresentation(TextPresentation presentation) {
+
+ StyleRange range= presentation.getDefaultStyleRange();
+ if (range != null) {
+
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ fTextWidget.setStyleRange(range);
+
+ ArrayList ranges= new ArrayList(presentation.getDenumerableRanges());
+ Iterator e= presentation.getNonDefaultStyleRangeIterator();
+ while (e.hasNext()) {
+ range= (StyleRange) e.next();
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ ranges.add(range);
+ }
+
+ if (!ranges.isEmpty())
+ fTextWidget.replaceStyleRanges(0, 0, (StyleRange[])ranges.toArray(new StyleRange[ranges.size()]));
+
+ } else {
+ IRegion region= modelRange2WidgetRange(presentation.getCoverage());
+ if (region == null)
+ return;
+
+ List list= new ArrayList(presentation.getDenumerableRanges());
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext()) {
+ range= (StyleRange) e.next();
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ list.add(range);
+ }
+
+ if (!list.isEmpty()) {
+ StyleRange[] ranges= new StyleRange[list.size()];
+ list.toArray(ranges);
+ fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges);
+ }
+ }
+ }
+
+ private void applyTextPresentation(TextPresentation presentation) {
+ List list= new ArrayList(presentation.getDenumerableRanges());
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext()) {
+ StyleRange range= (StyleRange) e.next();
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ list.add(range);
+ }
+
+ if (!list.isEmpty()) {
+ StyleRange[] ranges= new StyleRange[list.size()];
+ list.toArray(ranges);
+ fTextWidget.setStyleRanges(ranges);
+ }
+ }
+
+ protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) {
+ IRegion region= modelRange2WidgetRange(new Region(range.start, range.length));
+ if (region != null) {
+ StyleRange result= (StyleRange) range.clone();
+ result.start= region.getOffset();
+ result.length= region.getLength();
+ return result;
+ }
+ return null;
+ }
+
+ public IRegion modelRange2WidgetRange(IRegion modelRange) {
+ if (fInformationMapping == null)
+ return modelRange;
+
+ try {
+
+ if (modelRange.getLength() < 0) {
+ Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength());
+ IRegion result= fInformationMapping.toImageRegion(reversed);
+ if (result != null)
+ return new Region(result.getOffset() + result.getLength(), -result.getLength());
+ }
+ return fInformationMapping.toImageRegion(modelRange);
+
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+ public IRewriteTarget getRewriteTarget() {
+ if (fRewriteTarget == null)
+ fRewriteTarget= new RewriteTarget();
+ return fRewriteTarget;
+ }
+
+ public final void setRedraw(boolean redraw) {
+//TODO needs porting
+// setRedraw(redraw, -1);
+ }
+
+ class VisibleDocumentListener implements IDocumentListener {
+
+ public void documentAboutToBeChanged(DocumentEvent e) {
+ if (e.getDocument() == getVisibleDocument())
+ fWidgetCommand.setEvent(e);
+ handleVisibleDocumentAboutToBeChanged(e);
+ }
+
+ public void documentChanged(DocumentEvent e) {
+ if (fWidgetCommand.event == e)
+ updateTextListeners(fWidgetCommand);
+ fLastSentSelectionChange= null;
+ handleVisibleDocumentChanged(e);
+ }
+ }
+
+ /**
+ * Represents a replace command that brings the text viewer's text widget
+ * back in synchronization with text viewer's document after the document
+ * has been changed.
+ */
+ protected class WidgetCommand {
+
+ /** The document event encapsulated by this command. */
+ public DocumentEvent event;
+ /** The start of the event. */
+ public int start;
+ /** The length of the event. */
+ public int length;
+ /** The inserted and replaced text segments of <code>event</code>. */
+ public String text;
+ /** The replaced text segments of <code>event</code>. */
+ public String preservedText;
+
+ /**
+ * Translates a document event into the presentation coordinates of this text viewer.
+ *
+ * @param e the event to be translated
+ */
+ public void setEvent(DocumentEvent e) {
+
+ event= e;
+
+ start= e.getOffset();
+ length= e.getLength();
+ text= e.getText();
+
+ if (length != 0) {
+ try {
+
+ if (e instanceof SlaveDocumentEvent) {
+ SlaveDocumentEvent slave= (SlaveDocumentEvent) e;
+ DocumentEvent master= slave.getMasterEvent();
+ if (master != null)
+ preservedText= master.getDocument().get(master.getOffset(), master.getLength());
+ } else {
+ preservedText= e.getDocument().get(e.getOffset(), e.getLength());
+ }
+
+ } catch (BadLocationException x) {
+ preservedText= null;
+// if (TRACE_ERRORS)
+// System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.WidgetCommand.setEvent")); //$NON-NLS-1$
+ }
+ } else
+ preservedText= null;
+ }
+ }
+
+ private class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener {
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentRewriteSessionListener#documentRewriteSessionChanged(org.eclipse.jface.text.DocumentRewriteSessionEvent)
+ */
+ public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) {
+ IRewriteTarget target= TextViewer.this.getRewriteTarget();
+ final boolean toggleRedraw;
+// if (REDRAW_BUG_158746)
+// toggleRedraw= true;
+// else
+ toggleRedraw= event.getSession().getSessionType() != DocumentRewriteSessionType.UNRESTRICTED_SMALL;
+ final boolean viewportStabilize= !toggleRedraw;
+ if (DocumentRewriteSessionEvent.SESSION_START == event.getChangeType()) {
+ if (toggleRedraw)
+ target.setRedraw(false);
+ target.beginCompoundChange();
+ if (viewportStabilize && fViewerState == null)
+ fViewerState= new ViewerState();
+ } else if (DocumentRewriteSessionEvent.SESSION_STOP == event.getChangeType()) {
+ if (viewportStabilize && fViewerState != null) {
+ fViewerState.restore(true);
+ fViewerState= null;
+ }
+ target.endCompoundChange();
+ if (toggleRedraw)
+ target.setRedraw(true);
+ }
+ }
+ }
+
+ /**
+ * The viewer's rewrite target.
+ * @since 2.0
+ */
+ class RewriteTarget implements IRewriteTarget {
+
+ /*
+ * @see org.eclipse.jface.text.IRewriteTarget#beginCompoundChange()
+ */
+ public void beginCompoundChange() {
+//TODO needs porting
+// if (fUndoManager != null)
+// fUndoManager.beginCompoundChange();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IRewriteTarget#endCompoundChange()
+ */
+ public void endCompoundChange() {
+//TODO needs porting
+// if (fUndoManager != null)
+// fUndoManager.endCompoundChange();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IRewriteTarget#getDocument()
+ */
+ public IDocument getDocument() {
+ return TextViewer.this.getDocument();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IRewriteTarget#setRedraw(boolean)
+ */
+ public void setRedraw(boolean redraw) {
+ TextViewer.this.setRedraw(redraw);
+ }
+ }
+
+ private final class ViewerState {
+//TODO needs porting
+ public void restore(boolean restoreViewport) {
+
+ }
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java
new file mode 100644
index 000000000..4039cb96a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.presentation;
+
+
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+
+
+/**
+ * A presentation damager is a strategy used by a presentation reconciler to
+ * determine the region of the document's presentation which must be rebuilt
+ * because of a document change. A presentation damager is assumed to be
+ * specific for a particular document content type. A presentation damager is
+ * expected to return a damage region which is a valid input for a presentation
+ * repairer. I.e. having access to the damage region only the repairer must be
+ * able to derive all the information needed to successfully repair this region.
+ * <p>
+ * This interface must either be implemented by clients or clients use the
+ * rule-based default implementation
+ * {@link org.eclipse.jface.text.rules.DefaultDamagerRepairer}. Implementers
+ * should be registered with a presentation reconciler in order get involved in
+ * the reconciling process.</p>
+ *
+ * @see IPresentationReconciler
+ * @see IDocument
+ * @see DocumentEvent
+ * @see IPresentationRepairer
+ */
+public interface IPresentationDamager {
+
+ /**
+ * Tells the presentation damager on which document it will work.
+ *
+ * @param document the damager's working document
+ */
+ void setDocument(IDocument document);
+
+ /**
+ * Returns the damage in the document's presentation caused by the given document change.
+ * The damage is restricted to the specified partition for which the presentation damager is
+ * responsible. The damage may also depend on whether the document change also caused changes
+ * of the document's partitioning.
+ *
+ * @param partition the partition inside which the damage must be determined
+ * @param event the event describing the change whose damage must be determined
+ * @param documentPartitioningChanged indicates whether the given change changed the document's partitioning
+ * @return the computed damage
+ */
+ IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, boolean documentPartitioningChanged);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java
new file mode 100644
index 000000000..edfdc4f2c
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.presentation;
+
+
+import org.eclipse.jface.text.ITextViewer;
+
+
+/**
+ * An <code>IPresentationReconciler</code> defines and maintains the
+ * representation of a text viewer's document in the presence of changes applied
+ * to the document. An <code>IPresentationReconciler</code> is a
+ * <code>ITextViewer</code> add-on.
+ * <p>
+ * The presentation reconciler keeps track of changes applied to the text
+ * viewer. It sends each change to presentation damagers which are registered
+ * for the content types of the regions in which the change occurred. The
+ * presentation reconciler passes the computed damage to presentation repairer
+ * which construct text presentations. When applied to the presentation
+ * reconciler's text viewer, those text presentations bring the document's
+ * presentation in sync with the document's content and thus repair the damage.
+ * A presentation damager is expected to return damage which is a valid input
+ * for a presentation repairer registered for the same content type as the
+ * damager.
+ * </p>
+ * <p>
+ * A presentation reconciler should always be configured with a pair of
+ * damager/repairer strategies. I.e. for each damager there should be a
+ * corresponding repairer.
+ * </p>
+ * <p>
+ * The interface may be implemented by clients. Clients may use
+ * <code>PresentationReconciler</code> as the standard implementation of this
+ * interface.
+ * </p>
+ * <p>
+ * In order to provided backward compatibility for clients of
+ * <code>IPresentationReconciler</code>, extension interfaces are used to
+ * provide a means of evolution. The following extension interface exists:
+ * <ul>
+ * <li>
+ * {@link org.eclipse.jface.text.presentation.IPresentationReconcilerExtension}
+ * since version 3.0 adding support for documents with multiple partitionings.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jface.text.presentation.IPresentationReconcilerExtension
+ * @see org.eclipse.jface.text.ITextViewer
+ * @see org.eclipse.jface.text.presentation.IPresentationDamager
+ * @see org.eclipse.jface.text.presentation.IPresentationRepairer
+ * @see org.eclipse.jface.text.TextPresentation
+ */
+public interface IPresentationReconciler {
+
+ /**
+ * Installs this presentation reconciler on the given text viewer. After
+ * this method has been finished, the reconciler is operational. I.e., it
+ * works without requesting further client actions until
+ * <code>uninstall</code> is called.
+ * <p>
+ * The <code>install</code> and <code>uninstall</code> methods must be
+ * called in sequence; i.e. repeatedly calling <code>install</code>
+ * without calling <code>uninstall</code> may throw an exception.
+ * </p>
+ *
+ * @param viewer the viewer on which this presentation reconciler is
+ * installed
+ */
+ void install(ITextViewer viewer);
+
+ /**
+ * Removes the reconciler from the text viewer it has previously been
+ * installed on.
+ */
+ void uninstall();
+
+ /**
+ * Returns the presentation damager registered with this presentation reconciler
+ * for the specified content type.
+ *
+ * @param contentType the content type for which to determine the damager
+ * @return the presentation damager registered for the given content type, or
+ * <code>null</code> if there is no damager
+ */
+ IPresentationDamager getDamager(String contentType);
+
+ /**
+ * Returns the presentation repairer registered with this presentation reconciler
+ * for the specified content type.
+ *
+ * @param contentType the content type for which to determine the repairer
+ * @return the presentation repairer registered for the given content type, or
+ * <code>null</code> if there is no repairer
+ */
+ IPresentationRepairer getRepairer(String contentType);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java
new file mode 100644
index 000000000..1fc459fd2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.presentation;
+
+/**
+ * Extension interface for {@link IPresentationReconciler}. Adds awareness of
+ * documents with multiple partitions.
+ *
+ * @since 3.0
+ */
+public interface IPresentationReconcilerExtension {
+
+ /**
+ * Returns the document partitioning this presentation reconciler is using.
+ *
+ * @return the document partitioning this presentation reconciler is using
+ */
+ String getDocumentPartitioning();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java
new file mode 100644
index 000000000..a07f8e681
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.presentation;
+
+
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextPresentation;
+
+
+/**
+ * A presentation repairer is a strategy used by a presentation reconciler to
+ * rebuild a damaged region in a document's presentation. A presentation
+ * repairer is assumed to be specific for a particular document content type.
+ * The presentation repairer gets the region which it should repair and
+ * constructs a "repair description". The presentation repairer merges the steps
+ * contained within this description into the text presentation passed into
+ * <code>createPresentation</code>.
+ * <p>
+ * This interface may be implemented by clients. Alternatively, clients may use
+ * the rule-based default implementation
+ * {@link org.eclipse.jface.text.rules.DefaultDamagerRepairer}. Implementers
+ * should be registered with a presentation reconciler in order get involved in
+ * the reconciling process.
+ * </p>
+ *
+ * @see IPresentationReconciler
+ * @see IDocument
+ * @see org.eclipse.swt.custom.StyleRange
+ * @see TextPresentation
+ */
+public interface IPresentationRepairer {
+
+
+ /**
+ * Tells the presentation repairer on which document it will work.
+ *
+ * @param document the damager's working document
+ */
+ void setDocument(IDocument document);
+
+ /**
+ * Fills the given presentation with the style ranges which when applied to the
+ * presentation reconciler's text viewer repair the presentation damage described by
+ * the given region.
+ *
+ * @param presentation the text presentation to be filled by this repairer
+ * @param damage the damage to be repaired
+ */
+ void createPresentation(TextPresentation presentation, ITypedRegion damage);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java
new file mode 100644
index 000000000..bae2990a6
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java
@@ -0,0 +1,595 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.presentation;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.DocumentPartitioningChangedEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IDocumentPartitioningListener;
+import org.eclipse.jface.text.IDocumentPartitioningListenerExtension;
+import org.eclipse.jface.text.IDocumentPartitioningListenerExtension2;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.TypedPosition;
+
+
+
+/**
+ * Standard implementation of <code>IPresentationReconciler</code>. This
+ * implementation assumes that the tasks performed by its presentation damagers
+ * and repairers are lightweight and of low cost. This presentation reconciler
+ * runs in the UI thread and always repairs the complete damage caused by a
+ * document change rather than just the portion overlapping with the viewer's
+ * viewport.
+ * <p>
+ * Usually, clients instantiate this class and configure it before using it.
+ * </p>
+ */
+public class PresentationReconciler implements IPresentationReconciler, IPresentationReconcilerExtension {
+
+ /** Prefix of the name of the position category for tracking damage regions. */
+ protected final static String TRACKED_PARTITION= "__reconciler_tracked_partition"; //$NON-NLS-1$
+
+
+ /**
+ * Internal listener class.
+ */
+ class InternalListener implements
+ ITextInputListener, IDocumentListener, ITextListener,
+ IDocumentPartitioningListener, IDocumentPartitioningListenerExtension, IDocumentPartitioningListenerExtension2 {
+
+ /** Set to <code>true</code> if between a document about to be changed and a changed event. */
+ private boolean fDocumentChanging= false;
+ /**
+ * The cached redraw state of the text viewer.
+ * @since 3.0
+ */
+ private boolean fCachedRedrawState= true;
+
+ /*
+ * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
+ */
+ public void inputDocumentAboutToBeChanged(IDocument oldDocument, IDocument newDocument) {
+ if (oldDocument != null) {
+ try {
+
+ fViewer.removeTextListener(this);
+ oldDocument.removeDocumentListener(this);
+ oldDocument.removeDocumentPartitioningListener(this);
+
+ oldDocument.removePositionUpdater(fPositionUpdater);
+ oldDocument.removePositionCategory(fPositionCategory);
+
+ } catch (BadPositionCategoryException x) {
+ // should not happened for former input documents;
+ }
+ }
+ }
+
+ /*
+ * @see ITextInputListener#inputDocumenChanged(IDocument, IDocument)
+ */
+ public void inputDocumentChanged(IDocument oldDocument, IDocument newDocument) {
+
+ fDocumentChanging= false;
+ fCachedRedrawState= true;
+
+ if (newDocument != null) {
+
+ newDocument.addPositionCategory(fPositionCategory);
+ newDocument.addPositionUpdater(fPositionUpdater);
+
+ newDocument.addDocumentPartitioningListener(this);
+ newDocument.addDocumentListener(this);
+ fViewer.addTextListener(this);
+
+ setDocumentToDamagers(newDocument);
+ setDocumentToRepairers(newDocument);
+ processDamage(new Region(0, newDocument.getLength()), newDocument);
+ }
+ }
+
+ /*
+ * @see IDocumentPartitioningListener#documentPartitioningChanged(IDocument)
+ */
+ public void documentPartitioningChanged(IDocument document) {
+ if (!fDocumentChanging && fCachedRedrawState)
+ processDamage(new Region(0, document.getLength()), document);
+ else
+ fDocumentPartitioningChanged= true;
+ }
+
+ /*
+ * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)
+ * @since 2.0
+ */
+ public void documentPartitioningChanged(IDocument document, IRegion changedRegion) {
+ if (!fDocumentChanging && fCachedRedrawState) {
+ processDamage(new Region(changedRegion.getOffset(), changedRegion.getLength()), document);
+ } else {
+ fDocumentPartitioningChanged= true;
+ fChangedDocumentPartitions= changedRegion;
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentPartitioningListenerExtension2#documentPartitioningChanged(org.eclipse.jface.text.DocumentPartitioningChangedEvent)
+ * @since 3.0
+ */
+ public void documentPartitioningChanged(DocumentPartitioningChangedEvent event) {
+ IRegion changedRegion= event.getChangedRegion(getDocumentPartitioning());
+ if (changedRegion != null)
+ documentPartitioningChanged(event.getDocument(), changedRegion);
+ }
+
+ /*
+ * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent e) {
+
+ fDocumentChanging= true;
+ if (fCachedRedrawState) {
+ try {
+ int offset= e.getOffset() + e.getLength();
+ ITypedRegion region= getPartition(e.getDocument(), offset);
+ fRememberedPosition= new TypedPosition(region);
+ e.getDocument().addPosition(fPositionCategory, fRememberedPosition);
+ } catch (BadLocationException x) {
+ // can not happen
+ } catch (BadPositionCategoryException x) {
+ // should not happen on input elements
+ }
+ }
+ }
+
+ /*
+ * @see IDocumentListener#documentChanged(DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent e) {
+ if (fCachedRedrawState) {
+ try {
+ e.getDocument().removePosition(fPositionCategory, fRememberedPosition);
+ } catch (BadPositionCategoryException x) {
+ // can not happen on input documents
+ }
+ }
+ fDocumentChanging= false;
+ }
+
+ /*
+ * @see ITextListener#textChanged(TextEvent)
+ */
+ public void textChanged(TextEvent e) {
+
+ fCachedRedrawState= e.getViewerRedrawState();
+ if (!fCachedRedrawState)
+ return;
+
+ IRegion damage= null;
+ IDocument document= null;
+
+ if (e.getDocumentEvent() == null) {
+ document= fViewer.getDocument();
+ if (document != null) {
+ if (e.getOffset() == 0 && e.getLength() == 0 && e.getText() == null) {
+ // redraw state change, damage the whole document
+ damage= new Region(0, document.getLength());
+ } else {
+ IRegion region= widgetRegion2ModelRegion(e);
+ if (region != null) {
+ try {
+ String text= document.get(region.getOffset(), region.getLength());
+ DocumentEvent de= new DocumentEvent(document, region.getOffset(), region.getLength(), text);
+ damage= getDamage(de, false);
+ } catch (BadLocationException x) {
+ }
+ }
+ }
+ }
+ } else {
+ DocumentEvent de= e.getDocumentEvent();
+ document= de.getDocument();
+ damage= getDamage(de, true);
+ }
+
+ if (damage != null && document != null)
+ processDamage(damage, document);
+
+ fDocumentPartitioningChanged= false;
+ fChangedDocumentPartitions= null;
+ }
+
+ /**
+ * Translates the given text event into the corresponding range of the viewer's document.
+ *
+ * @param e the text event
+ * @return the widget region corresponding the region of the given event or
+ * <code>null</code> if none
+ * @since 2.1
+ */
+ protected IRegion widgetRegion2ModelRegion(TextEvent e) {
+
+ String text= e.getText();
+ int length= text == null ? 0 : text.length();
+
+ if (fViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension= (ITextViewerExtension5) fViewer;
+ return extension.widgetRange2ModelRange(new Region(e.getOffset(), length));
+ }
+
+ IRegion visible= fViewer.getVisibleRegion();
+ IRegion region= new Region(e.getOffset() + visible.getOffset(), length);
+ return region;
+ }
+ }
+
+ /** The map of presentation damagers. */
+ private Map fDamagers;
+ /** The map of presentation repairers. */
+ private Map fRepairers;
+ /** The target viewer. */
+ private ITextViewer fViewer;
+ /** The internal listener. */
+ private InternalListener fInternalListener= new InternalListener();
+ /** The name of the position category to track damage regions. */
+ private String fPositionCategory;
+ /** The position updated for the damage regions' position category. */
+ private IPositionUpdater fPositionUpdater;
+ /** The positions representing the damage regions. */
+ private TypedPosition fRememberedPosition;
+ /** Flag indicating the receipt of a partitioning changed notification. */
+ private boolean fDocumentPartitioningChanged= false;
+ /** The range covering the changed partitioning. */
+ private IRegion fChangedDocumentPartitions= null;
+ /**
+ * The partitioning used by this presentation reconciler.
+ * @since 3.0
+ */
+ private String fPartitioning;
+
+ /**
+ * Creates a new presentation reconciler. There are no damagers or repairers
+ * registered with this reconciler by default. The default partitioning
+ * <code>IDocumentExtension3.DEFAULT_PARTITIONING</code> is used.
+ */
+ public PresentationReconciler() {
+ super();
+ fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+ fPositionCategory= TRACKED_PARTITION + hashCode();
+ fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+ }
+
+ /**
+ * Sets the document partitioning for this presentation reconciler.
+ *
+ * @param partitioning the document partitioning for this presentation reconciler.
+ * @since 3.0
+ */
+ public void setDocumentPartitioning(String partitioning) {
+ Assert.isNotNull(partitioning);
+ fPartitioning= partitioning;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationReconcilerExtension#geDocumenttPartitioning()
+ * @since 3.0
+ */
+ public String getDocumentPartitioning() {
+ return fPartitioning;
+ }
+
+ /**
+ * Registers the given presentation damager for a particular content type.
+ * If there is already a damager registered for this type, the old damager
+ * is removed first.
+ *
+ * @param damager the presentation damager to register, or <code>null</code> to remove an existing one
+ * @param contentType the content type under which to register
+ */
+ public void setDamager(IPresentationDamager damager, String contentType) {
+
+ Assert.isNotNull(contentType);
+
+ if (fDamagers == null)
+ fDamagers= new HashMap();
+
+ if (damager == null)
+ fDamagers.remove(contentType);
+ else
+ fDamagers.put(contentType, damager);
+ }
+
+ /**
+ * Registers the given presentation repairer for a particular content type.
+ * If there is already a repairer registered for this type, the old repairer
+ * is removed first.
+ *
+ * @param repairer the presentation repairer to register, or <code>null</code> to remove an existing one
+ * @param contentType the content type under which to register
+ */
+ public void setRepairer(IPresentationRepairer repairer, String contentType) {
+
+ Assert.isNotNull(contentType);
+
+ if (fRepairers == null)
+ fRepairers= new HashMap();
+
+ if (repairer == null)
+ fRepairers.remove(contentType);
+ else
+ fRepairers.put(contentType, repairer);
+ }
+
+ /*
+ * @see IPresentationReconciler#install(ITextViewer)
+ */
+ public void install(ITextViewer viewer) {
+ Assert.isNotNull(viewer);
+
+ fViewer= viewer;
+ fViewer.addTextInputListener(fInternalListener);
+
+ IDocument document= viewer.getDocument();
+ if (document != null)
+ fInternalListener.inputDocumentChanged(null, document);
+ }
+
+ /*
+ * @see IPresentationReconciler#uninstall()
+ */
+ public void uninstall() {
+ fViewer.removeTextInputListener(fInternalListener);
+
+ // Ensure we uninstall all listeners
+ fInternalListener.inputDocumentAboutToBeChanged(fViewer.getDocument(), null);
+ }
+
+ /*
+ * @see IPresentationReconciler#getDamager(String)
+ */
+ public IPresentationDamager getDamager(String contentType) {
+
+ if (fDamagers == null)
+ return null;
+
+ return (IPresentationDamager) fDamagers.get(contentType);
+ }
+
+ /*
+ * @see IPresentationReconciler#getRepairer(String)
+ */
+ public IPresentationRepairer getRepairer(String contentType) {
+
+ if (fRepairers == null)
+ return null;
+
+ return (IPresentationRepairer) fRepairers.get(contentType);
+ }
+
+ /**
+ * Informs all registered damagers about the document on which they will work.
+ *
+ * @param document the document on which to work
+ */
+ protected void setDocumentToDamagers(IDocument document) {
+ if (fDamagers != null) {
+ Iterator e= fDamagers.values().iterator();
+ while (e.hasNext()) {
+ IPresentationDamager damager= (IPresentationDamager) e.next();
+ damager.setDocument(document);
+ }
+ }
+ }
+
+ /**
+ * Informs all registered repairers about the document on which they will work.
+ *
+ * @param document the document on which to work
+ */
+ protected void setDocumentToRepairers(IDocument document) {
+ if (fRepairers != null) {
+ Iterator e= fRepairers.values().iterator();
+ while (e.hasNext()) {
+ IPresentationRepairer repairer= (IPresentationRepairer) e.next();
+ repairer.setDocument(document);
+ }
+ }
+ }
+
+ /**
+ * Constructs a "repair description" for the given damage and returns this
+ * description as a text presentation. For this, it queries the partitioning
+ * of the damage region and asks the appropriate presentation repairer for
+ * each partition to construct the "repair description" for this partition.
+ *
+ * @param damage the damage to be repaired
+ * @param document the document whose presentation must be repaired
+ * @return the presentation repair description as text presentation or
+ * <code>null</code> if the partitioning could not be computed
+ */
+ protected TextPresentation createPresentation(IRegion damage, IDocument document) {
+ try {
+ if (fRepairers == null || fRepairers.isEmpty()) {
+ TextPresentation presentation= new TextPresentation(damage, 100);
+ presentation.setDefaultStyleRange(new StyleRange(damage.getOffset(), damage.getLength(), null, null));
+ return presentation;
+ }
+
+ TextPresentation presentation= new TextPresentation(damage, 1000);
+
+ ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, getDocumentPartitioning(), damage.getOffset(), damage.getLength(), false);
+ for (int i= 0; i < partitioning.length; i++) {
+ ITypedRegion r= partitioning[i];
+ IPresentationRepairer repairer= getRepairer(r.getType());
+ if (repairer != null)
+ repairer.createPresentation(presentation, r);
+ }
+
+ return presentation;
+
+ } catch (BadLocationException x) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Checks for the first and the last affected partition affected by a
+ * document event and calls their damagers. Invalidates everything from the
+ * start of the damage for the first partition until the end of the damage
+ * for the last partition.
+ *
+ * @param e the event describing the document change
+ * @param optimize <code>true</code> if partition changes should be
+ * considered for optimization
+ * @return the damaged caused by the change or <code>null</code> if
+ * computing the partitioning failed
+ * @since 3.0
+ */
+ private IRegion getDamage(DocumentEvent e, boolean optimize) {
+ int length= e.getText() == null ? 0 : e.getText().length();
+
+ if (fDamagers == null || fDamagers.isEmpty()) {
+ length= Math.max(e.getLength(), length);
+ length= Math.min(e.getDocument().getLength() - e.getOffset(), length);
+ return new Region(e.getOffset(), length);
+ }
+
+ boolean isDeletion= length == 0;
+ IRegion damage= null;
+ try {
+ int offset= e.getOffset();
+ if (isDeletion)
+ offset= Math.max(0, offset - 1);
+ ITypedRegion partition= getPartition(e.getDocument(), offset);
+ IPresentationDamager damager= getDamager(partition.getType());
+ if (damager == null)
+ return null;
+
+ IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged);
+
+ if (!fDocumentPartitioningChanged && optimize && !isDeletion) {
+ damage= r;
+ } else {
+
+ int damageStart= r.getOffset();
+ int damageEnd= getDamageEndOffset(e);
+
+ if (fChangedDocumentPartitions != null) {
+ damageStart= Math.min(damageStart, fChangedDocumentPartitions.getOffset());
+ damageEnd= Math.max(damageEnd, fChangedDocumentPartitions.getOffset() + fChangedDocumentPartitions.getLength());
+ }
+
+ damage= damageEnd == -1 ? r : new Region(damageStart, damageEnd - damageStart);
+ }
+
+ } catch (BadLocationException x) {
+ }
+
+ return damage;
+ }
+
+ /**
+ * Returns the end offset of the damage. If a partition has been split by
+ * the given document event also the second half of the original
+ * partition must be considered. This is achieved by using the remembered
+ * partition range.
+ *
+ * @param e the event describing the change
+ * @return the damage end offset (excluding)
+ * @exception BadLocationException if method accesses invalid offset
+ */
+ private int getDamageEndOffset(DocumentEvent e) throws BadLocationException {
+
+ IDocument d= e.getDocument();
+
+ int length= 0;
+ if (e.getText() != null) {
+ length= e.getText().length();
+ if (length > 0)
+ -- length;
+ }
+
+ ITypedRegion partition= getPartition(d, e.getOffset() + length);
+ int endOffset= partition.getOffset() + partition.getLength();
+ if (endOffset == e.getOffset())
+ return -1;
+
+ int end= fRememberedPosition == null ? -1 : fRememberedPosition.getOffset() + fRememberedPosition.getLength();
+ if (endOffset < end && end < d.getLength())
+ partition= getPartition(d, end);
+
+ IPresentationDamager damager= getDamager(partition.getType());
+ if (damager == null)
+ return -1;
+
+ IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged);
+
+ return r.getOffset() + r.getLength();
+ }
+
+ /**
+ * Processes the given damage.
+ * @param damage the damage to be repaired
+ * @param document the document whose presentation must be repaired
+ */
+ private void processDamage(IRegion damage, IDocument document) {
+ if (damage != null && damage.getLength() > 0) {
+ TextPresentation p= createPresentation(damage, document);
+ if (p != null)
+ applyTextRegionCollection(p);
+ }
+ }
+
+ /**
+ * Applies the given text presentation to the text viewer the presentation
+ * reconciler is installed on.
+ *
+ * @param presentation the text presentation to be applied to the text viewer
+ */
+ private void applyTextRegionCollection(TextPresentation presentation) {
+ fViewer.changeTextPresentation(presentation, false);
+ }
+
+ /**
+ * Returns the partition for the given offset in the given document.
+ *
+ * @param document the document
+ * @param offset the offset
+ * @return the partition
+ * @throws BadLocationException if offset is invalid in the given document
+ * @since 3.0
+ */
+ private ITypedRegion getPartition(IDocument document, int offset) throws BadLocationException {
+ return TextUtilities.getPartition(document, getDocumentPartitioning(), offset, false);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java
new file mode 100644
index 000000000..83b07ac53
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.reconciler;
+
+import org.eclipse.jface.text.ITypedRegion;
+
+
+/**
+ * A dirty region describes a document range which has been changed.
+ */
+public class DirtyRegion implements ITypedRegion {
+
+ /**
+ * Identifies an insert operation.
+ */
+ final static public String INSERT= "__insert"; //$NON-NLS-1$
+ /**
+ * Identifies a remove operation.
+ */
+ final static public String REMOVE= "__remove"; //$NON-NLS-1$
+
+ /** The region's offset. */
+ private int fOffset;
+ /** The region's length. */
+ private int fLength;
+ /** Indicates the type of the applied change. */
+ private String fType;
+ /** The text which has been inserted. */
+ private String fText;
+
+ /**
+ * Creates a new dirty region.
+ *
+ * @param offset the offset within the document where the change occurred
+ * @param length the length of the text within the document that changed
+ * @param type the type of change that this region represents: {@link #INSERT} {@link #REMOVE}
+ * @param text the substitution text
+ */
+ public DirtyRegion(int offset, int length, String type, String text) {
+ fOffset= offset;
+ fLength= length;
+ fType= normalizeTypeValue(type);
+ fText= text;
+ }
+
+ /**
+ * Computes the normalized type value to ensure that the implementation can use object identity rather
+ * than equality.
+ *
+ * @param type the type value
+ * @return the normalized type value or <code>null</code>
+ * @since 3.1
+ */
+ private String normalizeTypeValue(String type) {
+ if (INSERT.equals(type))
+ return INSERT;
+ if (REMOVE.equals(type))
+ return REMOVE;
+ return null;
+ }
+
+ /*
+ * @see ITypedRegion#getOffset()
+ */
+ public int getOffset() {
+ return fOffset;
+ }
+
+ /*
+ * @see ITypedRegion#getLength()
+ */
+ public int getLength() {
+ return fLength;
+ }
+
+ /*
+ * @see ITypedRegion#getType
+ */
+ public String getType() {
+ return fType;
+ }
+
+ /**
+ * Returns the text that changed as part of the region change.
+ *
+ * @return the changed text
+ */
+ public String getText() {
+ return fText;
+ }
+
+ /**
+ * Modify the receiver so that it encompasses the region specified by the dirty region.
+ *
+ * @param dr the dirty region with which to merge
+ */
+ void mergeWith(DirtyRegion dr) {
+ int start= Math.min(fOffset, dr.fOffset);
+ int end= Math.max(fOffset + fLength, dr.fOffset + dr.fLength);
+ fOffset= start;
+ fLength= end - start;
+ fText= (dr.fText == null ? fText : (fText == null) ? dr.fText : fText + dr.fText);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java
new file mode 100644
index 000000000..53a10d46a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.reconciler;
+
+import org.eclipse.jface.text.ITextViewer;
+
+
+/**
+ * An <code>IReconciler</code> defines and maintains a model of the content
+ * of the text viewer's document in the presence of changes applied to this
+ * document. An <code>IReconciler</code> is a {@link org.eclipse.jface.text.ITextViewer} add-on.
+ * <p>
+ * Reconcilers are assumed to be asynchronous, i.e. they allow a certain
+ * temporal window of inconsistency between the document and the model of
+ * the content of this document.
+ * </p>
+ * <p>
+ * Reconcilers have a list of {@link org.eclipse.jface.text.reconciler.IReconcilingStrategy}
+ * objects each of which is registered for a particular document content type.
+ * The reconciler uses the strategy objects to react on the changes applied
+ * to the text viewer's document.
+ *</p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IReconciler</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link org.eclipse.jface.text.reconciler.IReconcilerExtension} since version 3.0 introducing
+ * the ability to be aware of documents with multiple partitionings.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link org.eclipse.jface.text.reconciler.MonoReconciler} or
+ * {@link org.eclipse.jface.text.reconciler.Reconciler} as the standard
+ * implementers of this interface.
+ * </p>
+ *
+ * @see ITextViewer
+ * @see IReconcilingStrategy
+ */
+public interface IReconciler {
+
+ /**
+ * Installs the reconciler on the given text viewer. After this method has been
+ * finished, the reconciler is operational, i.e., it works without requesting
+ * further client actions until <code>uninstall</code> is called.
+ *
+ * @param textViewer the viewer on which the reconciler is installed
+ */
+ void install(ITextViewer textViewer);
+
+ /**
+ * Removes the reconciler from the text viewer it has
+ * previously been installed on.
+ */
+ void uninstall();
+
+ /**
+ * Returns the reconciling strategy registered with the reconciler
+ * for the specified content type.
+ *
+ * @param contentType the content type for which to determine the reconciling strategy
+ * @return the reconciling strategy registered for the given content type, or
+ * <code>null</code> if there is no such strategy
+ */
+ IReconcilingStrategy getReconcilingStrategy(String contentType);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java
new file mode 100644
index 000000000..b7f7a582a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.reconciler;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+
+/**
+ * A reconciling strategy is used by an reconciler to reconcile a model
+ * based on text of a particular content type. It provides methods for
+ * incremental as well as non-incremental reconciling.
+ * <p>
+ * If a reconcile strategy consists of several steps between which
+ * model transformation is desired the each step should implement
+ * {@link org.eclipse.jface.text.reconciler.IReconcileStep}.
+ * </p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IReconcilingStrategy</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension} since version 2.0 introducing
+ * the following functions:
+ * <ul>
+ * <li>usage of a progress monitor</li>
+ * <li>initial reconciling step: if a reconciler runs as periodic activity in the background, this
+ * methods offers the reconciler a chance for initializing its strategies and achieving a
+ * reconciled state before the periodic activity starts.</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * This interface must be implemented by clients. Implementers should be
+ * registered with a reconciler in order get involved in the reconciling
+ * process.
+ * </p>
+ */
+public interface IReconcilingStrategy {
+
+ /**
+ * Tells this reconciling strategy on which document it will
+ * work. This method will be called before any other method
+ * and can be called multiple times. The regions passed to the
+ * other methods always refer to the most recent document
+ * passed into this method.
+ *
+ * @param document the document on which this strategy will work
+ */
+ void setDocument(IDocument document);
+
+ /**
+ * Activates incremental reconciling of the specified dirty region.
+ * As a dirty region might span multiple content types, the segment of the
+ * dirty region which should be investigated is also provided to this
+ * reconciling strategy. The given regions refer to the document passed into
+ * the most recent call of {@link #setDocument(IDocument)}.
+ *
+ * @param dirtyRegion the document region which has been changed
+ * @param subRegion the sub region in the dirty region which should be reconciled
+ */
+ void reconcile(DirtyRegion dirtyRegion, IRegion subRegion);
+
+ /**
+ * Activates non-incremental reconciling. The reconciling strategy is just told
+ * that there are changes and that it should reconcile the given partition of the
+ * document most recently passed into {@link #setDocument(IDocument)}.
+ *
+ * @param partition the document partition to be reconciled
+ */
+ void reconcile(IRegion partition);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java
new file mode 100644
index 000000000..4dccc48ed
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.fx.ui.controls.styledtext.StyleRange;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+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.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+
+
+/**
+ * A standard implementation of a syntax driven presentation damager
+ * and presentation repairer. It uses a token scanner to scan
+ * the document and to determine its damage and new text presentation.
+ * The tokens returned by the scanner are supposed to return text attributes
+ * as their data.
+ *
+ * @see ITokenScanner
+ * @since 2.0
+ */
+public class DefaultDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
+
+
+ /** The document this object works on */
+ protected IDocument fDocument;
+ /** The scanner it uses */
+ protected ITokenScanner fScanner;
+ /** The default text attribute if non is returned as data by the current token */
+ protected TextAttribute fDefaultTextAttribute;
+
+ /**
+ * Creates a damager/repairer that uses the given scanner and returns the given default
+ * text attribute if the current token does not carry a text attribute.
+ *
+ * @param scanner the token scanner to be used
+ * @param defaultTextAttribute the text attribute to be returned if non is specified by the current token,
+ * may not be <code>null</code>
+ *
+ * @deprecated use DefaultDamagerRepairer(ITokenScanner) instead
+ */
+ public DefaultDamagerRepairer(ITokenScanner scanner, TextAttribute defaultTextAttribute) {
+
+ Assert.isNotNull(defaultTextAttribute);
+
+ fScanner= scanner;
+ fDefaultTextAttribute= defaultTextAttribute;
+ }
+
+ /**
+ * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code>
+ * and is assumed to return only token that carry text attributes.
+ *
+ * @param scanner the token scanner to be used, may not be <code>null</code>
+ */
+ public DefaultDamagerRepairer(ITokenScanner scanner) {
+
+ Assert.isNotNull(scanner);
+
+ fScanner= scanner;
+ fDefaultTextAttribute= new TextAttribute(null);
+ }
+
+ /*
+ * @see IPresentationDamager#setDocument(IDocument)
+ * @see IPresentationRepairer#setDocument(IDocument)
+ */
+ public void setDocument(IDocument document) {
+ fDocument= document;
+ }
+
+
+ //---- IPresentationDamager
+
+ /**
+ * Returns the end offset of the line that contains the specified offset or
+ * if the offset is inside a line delimiter, the end offset of the next line.
+ *
+ * @param offset the offset whose line end offset must be computed
+ * @return the line end offset for the given offset
+ * @exception BadLocationException if offset is invalid in the current document
+ */
+ protected int endOfLineOf(int offset) throws BadLocationException {
+
+ IRegion info= fDocument.getLineInformationOfOffset(offset);
+ if (offset <= info.getOffset() + info.getLength())
+ return info.getOffset() + info.getLength();
+
+ int line= fDocument.getLineOfOffset(offset);
+ try {
+ info= fDocument.getLineInformation(line + 1);
+ return info.getOffset() + info.getLength();
+ } catch (BadLocationException x) {
+ return fDocument.getLength();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation damages entire lines unless clipped by the given partition.
+ * </p>
+ *
+ * @return the full lines containing the document changes described by the document event,
+ * clipped by the given partition. If there was a partitioning change then the whole
+ * partition is returned.
+ */
+ public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) {
+
+ if (!documentPartitioningChanged) {
+ try {
+
+ IRegion info= fDocument.getLineInformationOfOffset(e.getOffset());
+ int start= Math.max(partition.getOffset(), info.getOffset());
+
+ int end= e.getOffset() + (e.getText() == null ? e.getLength() : e.getText().length());
+
+ if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) {
+ // optimize the case of the same line
+ end= info.getOffset() + info.getLength();
+ } else
+ end= endOfLineOf(end);
+
+ end= Math.min(partition.getOffset() + partition.getLength(), end);
+ return new Region(start, end - start);
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ return partition;
+ }
+
+ //---- IPresentationRepairer
+
+ /*
+ * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+ */
+ public void createPresentation(TextPresentation presentation, ITypedRegion region) {
+
+ if (fScanner == null) {
+ // will be removed if deprecated constructor will be removed
+ addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute);
+ return;
+ }
+
+ int lastStart= region.getOffset();
+ int length= 0;
+ boolean firstToken= true;
+ IToken lastToken= Token.UNDEFINED;
+ TextAttribute lastAttribute= getTokenTextAttribute(lastToken);
+
+ fScanner.setRange(fDocument, lastStart, region.getLength());
+
+ while (true) {
+ IToken token= fScanner.nextToken();
+ if (token.isEOF())
+ break;
+
+ TextAttribute attribute= getTokenTextAttribute(token);
+ if (lastAttribute != null && lastAttribute.equals(attribute)) {
+ length += fScanner.getTokenLength();
+ firstToken= false;
+ } else {
+ if (!firstToken)
+ addRange(presentation, lastStart, length, lastAttribute);
+ firstToken= false;
+ lastToken= token;
+ lastAttribute= attribute;
+ lastStart= fScanner.getTokenOffset();
+ length= fScanner.getTokenLength();
+ }
+ }
+
+ addRange(presentation, lastStart, length, lastAttribute);
+ }
+
+ /**
+ * Returns a text attribute encoded in the given token. If the token's
+ * data is not <code>null</code> and a text attribute it is assumed that
+ * it is the encoded text attribute. It returns the default text attribute
+ * if there is no encoded text attribute found.
+ *
+ * @param token the token whose text attribute is to be determined
+ * @return the token's text attribute
+ */
+ protected TextAttribute getTokenTextAttribute(IToken token) {
+ Object data= token.getData();
+ if (data instanceof TextAttribute)
+ return (TextAttribute) data;
+ return fDefaultTextAttribute;
+ }
+
+ /**
+ * Adds style information to the given text presentation.
+ *
+ * @param presentation the text presentation to be extended
+ * @param offset the offset of the range to be styled
+ * @param length the length of the range to be styled
+ * @param attr the attribute describing the style of the range to be styled
+ */
+ protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) {
+ if (attr != null) {
+ int style= attr.getStyle();
+ int fontStyle= style & (StyleRange.ITALIC | StyleRange.BOLD | StyleRange.NORMAL);
+ StyleRange styleRange= new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), fontStyle);
+ styleRange.strikeout= (style & TextAttribute.STRIKETHROUGH) != 0;
+ styleRange.underline= (style & TextAttribute.UNDERLINE) != 0;
+ styleRange.font= attr.getFont();
+ presentation.addStyleRange(styleRange);
+ }
+ }
+}
+
+
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java
new file mode 100644
index 000000000..9a1d8673d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java
@@ -0,0 +1,7 @@
+package org.eclipse.jface.text.source;
+
+import org.eclipse.jface.text.ITextViewer;
+
+public interface ISourceViewer extends ITextViewer {
+ void configure(SourceViewerConfiguration configuration);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java
new file mode 100644
index 000000000..5fd1cd1ca
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text.source;
+
+public interface ISourceViewerExtension {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java
new file mode 100644
index 000000000..925eef77e
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text.source;
+
+public interface ISourceViewerExtension2 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java
new file mode 100644
index 000000000..495c4cbbb
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text.source;
+
+public interface ISourceViewerExtension3 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java
new file mode 100644
index 000000000..f54fa74a8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.text.source;
+
+public interface ISourceViewerExtension4 {
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java
new file mode 100644
index 000000000..561a7d108
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Tom Eicher (Avaloq Evolution AG) - block selection mode
+ * Tom Hofmann (Perspectix AG) - bug 297572
+ *******************************************************************************/
+package org.eclipse.jface.text.source;
+
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+
+public class SourceViewer extends TextViewer implements ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4 {
+
+ private IPresentationReconciler fPresentationReconciler;
+ private IReconciler fReconciler;
+
+ @Override
+ public void configure(SourceViewerConfiguration configuration) {
+ if (getTextWidget() == null)
+ return;
+
+ setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this));
+
+ // install content type independent plug-ins
+ fPresentationReconciler= configuration.getPresentationReconciler(this);
+ if (fPresentationReconciler != null)
+ fPresentationReconciler.install(this);
+
+ fReconciler= configuration.getReconciler(this);
+ if (fReconciler != null)
+ fReconciler.install(this);
+ }
+
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java
new file mode 100644
index 000000000..6de5d43db
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.source;
+
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+
+public class SourceViewerConfiguration {
+ public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+ return IDocumentExtension3.DEFAULT_PARTITIONING;
+ }
+
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler= new PresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ return reconciler;
+ }
+
+ public IReconciler getReconciler(ISourceViewer sourceViewer) {
+ return null;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java
new file mode 100644
index 000000000..34de0cd52
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java
@@ -0,0 +1,5 @@
+package org.eclipse.jface.viewers;
+
+public interface IInputSelectionProvider {
+ public Object getInput();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java
new file mode 100644
index 000000000..6f8160dd0
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java
@@ -0,0 +1,10 @@
+package org.eclipse.jface.viewers;
+
+import javafx.scene.layout.AnchorPane;
+
+public abstract class Viewer extends AnchorPane {
+ protected void inputChanged(Object input, Object oldInput) {
+ }
+
+ public abstract void setInput(Object input);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/.classpath b/experimental/compensator/org.eclipse.fx.text/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/experimental/compensator/org.eclipse.fx.text/.gitignore b/experimental/compensator/org.eclipse.fx.text/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/experimental/compensator/org.eclipse.fx.text/.project b/experimental/compensator/org.eclipse.fx.text/.project
new file mode 100644
index 000000000..bef853f43
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.text</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..202af9645
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF
@@ -0,0 +1,46 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Text
+Bundle-SymbolicName: org.eclipse.fx.text
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: org.eclipse.jface.text,
+ org.eclipse.jface.text.rules
+Require-Bundle: org.eclipse.text;bundle-version="3.5.300",
+ org.eclipse.equinox.common;bundle-version="3.6.200",
+ org.eclipse.core.runtime;bundle-version="3.10.0"
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0"
diff --git a/experimental/compensator/org.eclipse.fx.text/build.properties b/experimental/compensator/org.eclipse.fx.text/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java
new file mode 100644
index 000000000..2998f1e6d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * An {@link org.eclipse.jface.text.IDocument} that is a read-only clone of another document.
+ *
+ * @since 3.0
+ */
+class DocumentClone extends AbstractDocument {
+
+ private static class StringTextStore implements ITextStore {
+
+ private String fContent;
+
+ /**
+ * Creates a new string text store with the given content.
+ *
+ * @param content the content
+ */
+ public StringTextStore(String content) {
+ Assert.isNotNull(content);
+ fContent= content;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#get(int)
+ */
+ public char get(int offset) {
+ return fContent.charAt(offset);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#get(int, int)
+ */
+ public String get(int offset, int length) {
+ return fContent.substring(offset, offset + length);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#getLength()
+ */
+ public int getLength() {
+ return fContent.length();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
+ */
+ public void replace(int offset, int length, String text) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
+ */
+ public void set(String text) {
+ }
+
+ }
+
+ /**
+ * Creates a new document clone with the given content.
+ *
+ * @param content the content
+ * @param lineDelimiters the line delimiters
+ */
+ public DocumentClone(String content, String[] lineDelimiters) {
+ super();
+ setTextStore(new StringTextStore(content));
+ ConfigurableLineTracker tracker= new ConfigurableLineTracker(lineDelimiters);
+ setLineTracker(tracker);
+ getTracker().set(content);
+ completeInitialization();
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java
new file mode 100644
index 000000000..6f804a832
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * A buffered rule based scanner. The buffer always contains a section
+ * of a fixed size of the document to be scanned. Completely adheres to
+ * the contract of <code>RuleBasedScanner</code>.
+ */
+public class BufferedRuleBasedScanner extends RuleBasedScanner {
+
+ /** The default buffer size. Value = 500 */
+ private final static int DEFAULT_BUFFER_SIZE= 500;
+ /** The actual size of the buffer. Initially set to <code>DEFAULT_BUFFER_SIZE</code> */
+ private int fBufferSize= DEFAULT_BUFFER_SIZE;
+ /** The buffer */
+ private char[] fBuffer= new char[DEFAULT_BUFFER_SIZE];
+ /** The offset of the document at which the buffer starts */
+ private int fStart;
+ /** The offset of the document at which the buffer ends */
+ private int fEnd;
+ /** The cached length of the document */
+ private int fDocumentLength;
+
+
+ /**
+ * Creates a new buffered rule based scanner which does
+ * not have any rule and a default buffer size of 500 characters.
+ */
+ protected BufferedRuleBasedScanner() {
+ super();
+ }
+
+ /**
+ * Creates a new buffered rule based scanner which does
+ * not have any rule. The buffer size is set to the given
+ * number of characters.
+ *
+ * @param size the buffer size
+ */
+ public BufferedRuleBasedScanner(int size) {
+ super();
+ setBufferSize(size);
+ }
+
+ /**
+ * Sets the buffer to the given number of characters.
+ *
+ * @param size the buffer size
+ */
+ protected void setBufferSize(int size) {
+ Assert.isTrue(size > 0);
+ fBufferSize= size;
+ fBuffer= new char[size];
+ }
+
+ /**
+ * Shifts the buffer so that the buffer starts at the
+ * given document offset.
+ *
+ * @param offset the document offset at which the buffer starts
+ */
+ private void shiftBuffer(int offset) {
+
+ fStart= offset;
+ fEnd= fStart + fBufferSize;
+ if (fEnd > fDocumentLength)
+ fEnd= fDocumentLength;
+
+ try {
+
+ String content= fDocument.get(fStart, fEnd - fStart);
+ content.getChars(0, fEnd - fStart, fBuffer, 0);
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ /*
+ * @see RuleBasedScanner#setRange(IDocument, int, int)
+ */
+ public void setRange(IDocument document, int offset, int length) {
+
+ super.setRange(document, offset, length);
+
+ fDocumentLength= document.getLength();
+ shiftBuffer(offset);
+ }
+
+ /*
+ * @see RuleBasedScanner#read()
+ */
+ public int read() {
+ fColumn= UNDEFINED;
+ if (fOffset >= fRangeEnd) {
+ ++ fOffset;
+ return EOF;
+ }
+
+ if (fOffset == fEnd)
+ shiftBuffer(fEnd);
+ else if (fOffset < fStart || fEnd < fOffset)
+ shiftBuffer(fOffset);
+
+ return fBuffer[fOffset++ - fStart];
+ }
+
+ /*
+ * @see RuleBasedScanner#unread()
+ */
+ public void unread() {
+
+ if (fOffset == fStart)
+ shiftBuffer(Math.max(0, fStart - (fBufferSize / 2)));
+
+ --fOffset;
+ fColumn= UNDEFINED;
+ }
+}
+
+
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java
new file mode 100644
index 000000000..df08dd407
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java
@@ -0,0 +1,822 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.DocumentRewriteSession;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.IDocumentPartitionerExtension;
+import org.eclipse.jface.text.IDocumentPartitionerExtension2;
+import org.eclipse.jface.text.IDocumentPartitionerExtension3;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.TypedPosition;
+import org.eclipse.jface.text.TypedRegion;
+
+
+
+/**
+ * A standard implementation of a document partitioner. It uses an
+ * {@link IPartitionTokenScanner} to scan the document and to determine the
+ * document's partitioning. The tokens returned by the scanner must return the
+ * partition type as their data. The partitioner remembers the document's
+ * partitions in the document itself rather than maintaining its own data
+ * structure.
+ * <p>
+ * To reduce array creations in {@link IDocument#getPositions(String)}, the
+ * positions get cached. The cache is cleared after updating the positions in
+ * {@link #documentChanged2(DocumentEvent)}. Subclasses need to call
+ * {@link #clearPositionCache()} after modifying the partitioner's positions.
+ * The cached positions may be accessed through {@link #getPositions()}.
+ * </p>
+ *
+ * @see IPartitionTokenScanner
+ * @since 3.1
+ */
+public class FastPartitioner implements IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 {
+
+ /**
+ * The position category this partitioner uses to store the document's partitioning information.
+ */
+ private static final String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$
+ /** The partitioner's scanner */
+ protected final IPartitionTokenScanner fScanner;
+ /** The legal content types of this partitioner */
+ protected final String[] fLegalContentTypes;
+ /** The partitioner's document */
+ protected IDocument fDocument;
+ /** The document length before a document change occurred */
+ protected int fPreviousDocumentLength;
+ /** The position updater used to for the default updating of partitions */
+ protected final DefaultPositionUpdater fPositionUpdater;
+ /** The offset at which the first changed partition starts */
+ protected int fStartOffset;
+ /** The offset at which the last changed partition ends */
+ protected int fEndOffset;
+ /**The offset at which a partition has been deleted */
+ protected int fDeleteOffset;
+ /**
+ * The position category this partitioner uses to store the document's partitioning information.
+ */
+ private final String fPositionCategory;
+ /**
+ * The active document rewrite session.
+ */
+ private DocumentRewriteSession fActiveRewriteSession;
+ /**
+ * Flag indicating whether this partitioner has been initialized.
+ */
+ private boolean fIsInitialized= false;
+ /**
+ * The cached positions from our document, so we don't create a new array every time
+ * someone requests partition information.
+ */
+ private Position[] fCachedPositions= null;
+ /** Debug option for cache consistency checking. */
+ private static final boolean CHECK_CACHE_CONSISTENCY= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text/debug/FastPartitioner/PositionCache")); //$NON-NLS-1$//$NON-NLS-2$;
+
+ /**
+ * Creates a new partitioner that uses the given scanner and may return
+ * partitions of the given legal content types.
+ *
+ * @param scanner the scanner this partitioner is supposed to use
+ * @param legalContentTypes the legal content types of this partitioner
+ */
+ public FastPartitioner(IPartitionTokenScanner scanner, String[] legalContentTypes) {
+ fScanner= scanner;
+ fLegalContentTypes= TextUtilities.copy(legalContentTypes);
+ fPositionCategory= CONTENT_TYPES_CATEGORY + hashCode();
+ fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories()
+ */
+ public String[] getManagingPositionCategories() {
+ return new String[] { fPositionCategory };
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentPartitioner#connect(org.eclipse.jface.text.IDocument)
+ */
+ public final void connect(IDocument document) {
+ connect(document, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public void connect(IDocument document, boolean delayInitialization) {
+ Assert.isNotNull(document);
+ Assert.isTrue(!document.containsPositionCategory(fPositionCategory));
+
+ fDocument= document;
+ fDocument.addPositionCategory(fPositionCategory);
+
+ fIsInitialized= false;
+ if (!delayInitialization)
+ checkInitialization();
+ }
+
+ /**
+ * Calls {@link #initialize()} if the receiver is not yet initialized.
+ */
+ protected final void checkInitialization() {
+ if (!fIsInitialized)
+ initialize();
+ }
+
+ /**
+ * Performs the initial partitioning of the partitioner's document.
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ protected void initialize() {
+ fIsInitialized= true;
+ clearPositionCache();
+ fScanner.setRange(fDocument, 0, fDocument.getLength());
+
+ try {
+ IToken token= fScanner.nextToken();
+ while (!token.isEOF()) {
+
+ String contentType= getTokenContentType(token);
+
+ if (isSupportedContentType(contentType)) {
+ TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType);
+ fDocument.addPosition(fPositionCategory, p);
+ }
+
+ token= fScanner.nextToken();
+ }
+ } catch (BadLocationException x) {
+ // cannot happen as offsets come from scanner
+ } catch (BadPositionCategoryException x) {
+ // cannot happen if document has been connected before
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public void disconnect() {
+
+ Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory));
+
+ try {
+ fDocument.removePositionCategory(fPositionCategory);
+ } catch (BadPositionCategoryException x) {
+ // can not happen because of Assert
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public void documentAboutToBeChanged(DocumentEvent e) {
+ if (fIsInitialized) {
+
+ Assert.isTrue(e.getDocument() == fDocument);
+
+ fPreviousDocumentLength= e.getDocument().getLength();
+ fStartOffset= -1;
+ fEndOffset= -1;
+ fDeleteOffset= -1;
+ }
+ }
+
+ /*
+ * @see IDocumentPartitioner#documentChanged(DocumentEvent)
+ */
+ public final boolean documentChanged(DocumentEvent e) {
+ if (fIsInitialized) {
+ IRegion region= documentChanged2(e);
+ return (region != null);
+ }
+ return false;
+ }
+
+ /**
+ * Helper method for tracking the minimal region containing all partition changes.
+ * If <code>offset</code> is smaller than the remembered offset, <code>offset</code>
+ * will from now on be remembered. If <code>offset + length</code> is greater than
+ * the remembered end offset, it will be remembered from now on.
+ *
+ * @param offset the offset
+ * @param length the length
+ */
+ private void rememberRegion(int offset, int length) {
+ // remember start offset
+ if (fStartOffset == -1)
+ fStartOffset= offset;
+ else if (offset < fStartOffset)
+ fStartOffset= offset;
+
+ // remember end offset
+ int endOffset= offset + length;
+ if (fEndOffset == -1)
+ fEndOffset= endOffset;
+ else if (endOffset > fEndOffset)
+ fEndOffset= endOffset;
+ }
+
+ /**
+ * Remembers the given offset as the deletion offset.
+ *
+ * @param offset the offset
+ */
+ private void rememberDeletedOffset(int offset) {
+ fDeleteOffset= offset;
+ }
+
+ /**
+ * Creates the minimal region containing all partition changes using the
+ * remembered offset, end offset, and deletion offset.
+ *
+ * @return the minimal region containing all the partition changes
+ */
+ private IRegion createRegion() {
+ if (fDeleteOffset == -1) {
+ if (fStartOffset == -1 || fEndOffset == -1)
+ return null;
+ return new Region(fStartOffset, fEndOffset - fStartOffset);
+ } else if (fStartOffset == -1 || fEndOffset == -1) {
+ return new Region(fDeleteOffset, 0);
+ } else {
+ int offset= Math.min(fDeleteOffset, fStartOffset);
+ int endOffset= Math.max(fDeleteOffset, fEndOffset);
+ return new Region(offset, endOffset - offset);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public IRegion documentChanged2(DocumentEvent e) {
+
+ if (!fIsInitialized)
+ return null;
+
+ try {
+ Assert.isTrue(e.getDocument() == fDocument);
+
+ Position[] category= getPositions();
+ IRegion line= fDocument.getLineInformationOfOffset(e.getOffset());
+ int reparseStart= line.getOffset();
+ int partitionStart= -1;
+ String contentType= null;
+ int newLength= e.getText() == null ? 0 : e.getText().length();
+
+ int first= fDocument.computeIndexInCategory(fPositionCategory, reparseStart);
+ if (first > 0) {
+ TypedPosition partition= (TypedPosition) category[first - 1];
+ if (partition.includes(reparseStart)) {
+ partitionStart= partition.getOffset();
+ contentType= partition.getType();
+ if (e.getOffset() == partition.getOffset() + partition.getLength())
+ reparseStart= partitionStart;
+ -- first;
+ } else if (reparseStart == e.getOffset() && reparseStart == partition.getOffset() + partition.getLength()) {
+ partitionStart= partition.getOffset();
+ contentType= partition.getType();
+ reparseStart= partitionStart;
+ -- first;
+ } else {
+ partitionStart= partition.getOffset() + partition.getLength();
+ contentType= IDocument.DEFAULT_CONTENT_TYPE;
+ }
+ }
+
+ fPositionUpdater.update(e);
+ for (int i= first; i < category.length; i++) {
+ Position p= category[i];
+ if (p.isDeleted) {
+ rememberDeletedOffset(e.getOffset());
+ break;
+ }
+ }
+ clearPositionCache();
+ category= getPositions();
+
+ fScanner.setPartialRange(fDocument, reparseStart, fDocument.getLength() - reparseStart, contentType, partitionStart);
+
+ int behindLastScannedPosition= reparseStart;
+ IToken token= fScanner.nextToken();
+
+ while (!token.isEOF()) {
+
+ contentType= getTokenContentType(token);
+
+ if (!isSupportedContentType(contentType)) {
+ token= fScanner.nextToken();
+ continue;
+ }
+
+ int start= fScanner.getTokenOffset();
+ int length= fScanner.getTokenLength();
+
+ behindLastScannedPosition= start + length;
+ int lastScannedPosition= behindLastScannedPosition - 1;
+
+ // remove all affected positions
+ while (first < category.length) {
+ TypedPosition p= (TypedPosition) category[first];
+ if (lastScannedPosition >= p.offset + p.length ||
+ (p.overlapsWith(start, length) &&
+ (!fDocument.containsPosition(fPositionCategory, start, length) ||
+ !contentType.equals(p.getType())))) {
+
+ rememberRegion(p.offset, p.length);
+ fDocument.removePosition(fPositionCategory, p);
+ ++ first;
+
+ } else
+ break;
+ }
+
+ // if position already exists and we have scanned at least the
+ // area covered by the event, we are done
+ if (fDocument.containsPosition(fPositionCategory, start, length)) {
+ if (lastScannedPosition >= e.getOffset() + newLength)
+ return createRegion();
+ ++ first;
+ } else {
+ // insert the new type position
+ try {
+ fDocument.addPosition(fPositionCategory, new TypedPosition(start, length, contentType));
+ rememberRegion(start, length);
+ } catch (BadPositionCategoryException x) {
+ } catch (BadLocationException x) {
+ }
+ }
+
+ token= fScanner.nextToken();
+ }
+
+ first= fDocument.computeIndexInCategory(fPositionCategory, behindLastScannedPosition);
+
+ clearPositionCache();
+ category= getPositions();
+ TypedPosition p;
+ while (first < category.length) {
+ p= (TypedPosition) category[first++];
+ fDocument.removePosition(fPositionCategory, p);
+ rememberRegion(p.offset, p.length);
+ }
+
+ } catch (BadPositionCategoryException x) {
+ // should never happen on connected documents
+ } catch (BadLocationException x) {
+ } finally {
+ clearPositionCache();
+ }
+
+ return createRegion();
+ }
+
+ /**
+ * Returns the position in the partitoner's position category which is
+ * close to the given offset. This is, the position has either an offset which
+ * is the same as the given offset or an offset which is smaller than the given
+ * offset. This method profits from the knowledge that a partitioning is
+ * a ordered set of disjoint position.
+ * <p>
+ * May be extended or replaced by subclasses.
+ * </p>
+ * @param offset the offset for which to search the closest position
+ * @return the closest position in the partitioner's category
+ */
+ protected TypedPosition findClosestPosition(int offset) {
+
+ try {
+
+ int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+ Position[] category= getPositions();
+
+ if (category.length == 0)
+ return null;
+
+ if (index < category.length) {
+ if (offset == category[index].offset)
+ return (TypedPosition) category[index];
+ }
+
+ if (index > 0)
+ index--;
+
+ return (TypedPosition) category[index];
+
+ } catch (BadPositionCategoryException x) {
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public String getContentType(int offset) {
+ checkInitialization();
+
+ TypedPosition p= findClosestPosition(offset);
+ if (p != null && p.includes(offset))
+ return p.getType();
+
+ return IDocument.DEFAULT_CONTENT_TYPE;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public ITypedRegion getPartition(int offset) {
+ checkInitialization();
+
+ try {
+
+ Position[] category = getPositions();
+
+ if (category == null || category.length == 0)
+ return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+
+ int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+
+ if (index < category.length) {
+
+ TypedPosition next= (TypedPosition) category[index];
+
+ if (offset == next.offset)
+ return new TypedRegion(next.getOffset(), next.getLength(), next.getType());
+
+ if (index == 0)
+ return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+
+ TypedPosition previous= (TypedPosition) category[index - 1];
+ if (previous.includes(offset))
+ return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+ int endOffset= previous.getOffset() + previous.getLength();
+ return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ TypedPosition previous= (TypedPosition) category[category.length - 1];
+ if (previous.includes(offset))
+ return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+ int endOffset= previous.getOffset() + previous.getLength();
+ return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+
+ } catch (BadPositionCategoryException x) {
+ } catch (BadLocationException x) {
+ }
+
+ return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ /*
+ * @see IDocumentPartitioner#computePartitioning(int, int)
+ */
+ public final ITypedRegion[] computePartitioning(int offset, int length) {
+ return computePartitioning(offset, length, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public String[] getLegalContentTypes() {
+ return TextUtilities.copy(fLegalContentTypes);
+ }
+
+ /**
+ * Returns whether the given type is one of the legal content types.
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ *
+ * @param contentType the content type to check
+ * @return <code>true</code> if the content type is a legal content type
+ */
+ protected boolean isSupportedContentType(String contentType) {
+ if (contentType != null) {
+ for (int i= 0; i < fLegalContentTypes.length; i++) {
+ if (fLegalContentTypes[i].equals(contentType))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a content type encoded in the given token. If the token's
+ * data is not <code>null</code> and a string it is assumed that
+ * it is the encoded content type.
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ *
+ * @param token the token whose content type is to be determined
+ * @return the token's content type
+ */
+ protected String getTokenContentType(IToken token) {
+ Object data= token.getData();
+ if (data instanceof String)
+ return (String) data;
+ return null;
+ }
+
+ /* zero-length partition support */
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public String getContentType(int offset, boolean preferOpenPartitions) {
+ return getPartition(offset, preferOpenPartitions).getType();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public ITypedRegion getPartition(int offset, boolean preferOpenPartitions) {
+ ITypedRegion region= getPartition(offset);
+ if (preferOpenPartitions) {
+ if (region.getOffset() == offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+ if (offset > 0) {
+ region= getPartition(offset - 1);
+ if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE))
+ return region;
+ }
+ return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+ }
+ return region;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be replaced or extended by subclasses.
+ * </p>
+ */
+ public ITypedRegion[] computePartitioning(int offset, int length, boolean includeZeroLengthPartitions) {
+ checkInitialization();
+ List list= new ArrayList();
+
+ try {
+
+ int endOffset= offset + length;
+
+ Position[] category= getPositions();
+
+ TypedPosition previous= null, current= null;
+ int start, end, gapOffset;
+ Position gap= new Position(0);
+
+ int startIndex= getFirstIndexEndingAfterOffset(category, offset);
+ int endIndex= getFirstIndexStartingAfterOffset(category, endOffset);
+ for (int i= startIndex; i < endIndex; i++) {
+
+ current= (TypedPosition) category[i];
+
+ gapOffset= (previous != null) ? previous.getOffset() + previous.getLength() : 0;
+ gap.setOffset(gapOffset);
+ gap.setLength(current.getOffset() - gapOffset);
+ if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+ (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+ start= Math.max(offset, gapOffset);
+ end= Math.min(endOffset, gap.getOffset() + gap.getLength());
+ list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+ }
+
+ if (current.overlapsWith(offset, length)) {
+ start= Math.max(offset, current.getOffset());
+ end= Math.min(endOffset, current.getOffset() + current.getLength());
+ list.add(new TypedRegion(start, end - start, current.getType()));
+ }
+
+ previous= current;
+ }
+
+ if (previous != null) {
+ gapOffset= previous.getOffset() + previous.getLength();
+ gap.setOffset(gapOffset);
+ gap.setLength(fDocument.getLength() - gapOffset);
+ if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+ (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+ start= Math.max(offset, gapOffset);
+ end= Math.min(endOffset, fDocument.getLength());
+ list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+ }
+ }
+
+ if (list.isEmpty())
+ list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE));
+
+ } catch (BadPositionCategoryException ex) {
+ // Make sure we clear the cache
+ clearPositionCache();
+ } catch (RuntimeException ex) {
+ // Make sure we clear the cache
+ clearPositionCache();
+ throw ex;
+ }
+
+ TypedRegion[] result= new TypedRegion[list.size()];
+ list.toArray(result);
+ return result;
+ }
+
+ /**
+ * Returns <code>true</code> if the given ranges overlap with or touch each other.
+ *
+ * @param gap the first range
+ * @param offset the offset of the second range
+ * @param length the length of the second range
+ * @return <code>true</code> if the given ranges overlap with or touch each other
+ */
+ private boolean overlapsOrTouches(Position gap, int offset, int length) {
+ return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength();
+ }
+
+ /**
+ * Returns the index of the first position which ends after the given offset.
+ *
+ * @param positions the positions in linear order
+ * @param offset the offset
+ * @return the index of the first position which ends after the offset
+ */
+ private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) {
+ int i= -1, j= positions.length;
+ while (j - i > 1) {
+ int k= (i + j) >> 1;
+ Position p= positions[k];
+ if (p.getOffset() + p.getLength() > offset)
+ j= k;
+ else
+ i= k;
+ }
+ return j;
+ }
+
+ /**
+ * Returns the index of the first position which starts at or after the given offset.
+ *
+ * @param positions the positions in linear order
+ * @param offset the offset
+ * @return the index of the first position which starts after the offset
+ */
+ private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) {
+ int i= -1, j= positions.length;
+ while (j - i > 1) {
+ int k= (i + j) >> 1;
+ Position p= positions[k];
+ if (p.getOffset() >= offset)
+ j= k;
+ else
+ i= k;
+ }
+ return j;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentPartitionerExtension3#startRewriteSession(org.eclipse.jface.text.DocumentRewriteSession)
+ */
+ public void startRewriteSession(DocumentRewriteSession session) throws IllegalStateException {
+ if (fActiveRewriteSession != null)
+ throw new IllegalStateException();
+ fActiveRewriteSession= session;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public void stopRewriteSession(DocumentRewriteSession session) {
+ if (fActiveRewriteSession == session)
+ flushRewriteSession();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * May be extended by subclasses.
+ * </p>
+ */
+ public DocumentRewriteSession getActiveRewriteSession() {
+ return fActiveRewriteSession;
+ }
+
+ /**
+ * Flushes the active rewrite session.
+ */
+ protected final void flushRewriteSession() {
+ fActiveRewriteSession= null;
+
+ // remove all position belonging to the partitioner position category
+ try {
+ fDocument.removePositionCategory(fPositionCategory);
+ } catch (BadPositionCategoryException x) {
+ }
+ fDocument.addPositionCategory(fPositionCategory);
+
+ fIsInitialized= false;
+ }
+
+ /**
+ * Clears the position cache. Needs to be called whenever the positions have
+ * been updated.
+ */
+ protected final void clearPositionCache() {
+ if (fCachedPositions != null) {
+ fCachedPositions= null;
+ }
+ }
+
+ /**
+ * Returns the partitioners positions.
+ *
+ * @return the partitioners positions
+ * @throws BadPositionCategoryException if getting the positions from the
+ * document fails
+ */
+ protected final Position[] getPositions() throws BadPositionCategoryException {
+ if (fCachedPositions == null) {
+ fCachedPositions= fDocument.getPositions(fPositionCategory);
+ } else if (CHECK_CACHE_CONSISTENCY) {
+ Position[] positions= fDocument.getPositions(fPositionCategory);
+ int len= Math.min(positions.length, fCachedPositions.length);
+ for (int i= 0; i < len; i++) {
+ if (!positions[i].equals(fCachedPositions[i]))
+ System.err.println("FastPartitioner.getPositions(): cached position is not up to date: from document: " + toString(positions[i]) + " in cache: " + toString(fCachedPositions[i])); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ for (int i= len; i < positions.length; i++)
+ System.err.println("FastPartitioner.getPositions(): new position in document: " + toString(positions[i])); //$NON-NLS-1$
+ for (int i= len; i < fCachedPositions.length; i++)
+ System.err.println("FastPartitioner.getPositions(): stale position in cache: " + toString(fCachedPositions[i])); //$NON-NLS-1$
+ }
+ return fCachedPositions;
+ }
+
+ /**
+ * Pretty print a <code>Position</code>.
+ *
+ * @param position the position to format
+ * @return a formatted string
+ */
+ private String toString(Position position) {
+ return "P[" + position.getOffset() + "+" + position.getLength() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java
new file mode 100644
index 000000000..97e8b4c71
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * Defines the interface of a character scanner used by rules.
+ * Rules may request the next character or ask the character
+ * scanner to unread the last read character.
+ */
+public interface ICharacterScanner {
+
+ /**
+ * The value returned when this scanner has read EOF.
+ */
+ public static final int EOF= -1;
+
+ /**
+ * Provides rules access to the legal line delimiters. The returned
+ * object may not be modified by clients.
+ *
+ * @return the legal line delimiters
+ */
+ char[][] getLegalLineDelimiters();
+
+ /**
+ * Returns the column of the character scanner.
+ *
+ * @return the column of the character scanner
+ */
+ int getColumn();
+
+ /**
+ * Returns the next character or EOF if end of file has been reached
+ *
+ * @return the next character or EOF
+ */
+ int read();
+
+ /**
+ * Rewinds the scanner before the last read character.
+ */
+ void unread();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java
new file mode 100644
index 000000000..f0d2ebd2f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * A partition token scanner returns tokens that represent partitions. For that reason,
+ * a partition token scanner is vulnerable in respect to the document offset it starts
+ * scanning. In a simple case, a partition token scanner must always start at a partition
+ * boundary. A partition token scanner can also start in the middle of a partition,
+ * if it knows the type of the partition.
+ *
+ * @since 2.0
+ */
+public interface IPartitionTokenScanner extends ITokenScanner {
+
+ /**
+ * Configures the scanner by providing access to the document range that should be scanned. The
+ * range may not only contain complete partitions but starts at the beginning of a line in the
+ * middle of a partition of the given content type. This requires that a partition delimiter can
+ * not contain a line delimiter.
+ *
+ * @param document the document to scan
+ * @param offset the offset of the document range to scan
+ * @param length the length of the document range to scan
+ * @param contentType the content type at the given offset
+ * @param partitionOffset the offset at which the partition of the given offset starts
+ */
+ void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java
new file mode 100644
index 000000000..5a793437a
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+/**
+ * Defines the interface for a rule used in the scanning of text for the purpose of
+ * document partitioning or text styling. A predicate rule can only return one single
+ * token after having successfully detected content. This token is called success token.
+ * Also, it also returns a token indicating that this rule has not been successful.
+ *
+ * @see ICharacterScanner
+ * @since 2.0
+ */
+public interface IPredicateRule extends IRule {
+
+ /**
+ * Returns the success token of this predicate rule.
+ *
+ * @return the success token of this rule
+ */
+ IToken getSuccessToken();
+
+ /**
+ * Evaluates the rule by examining the characters available from
+ * the provided character scanner. The token returned by this rule
+ * returns <code>true</code> when calling <code>isUndefined</code>,
+ * if the text that the rule investigated does not match the rule's requirements. Otherwise,
+ * this method returns this rule's success token. If this rules relies on a text pattern
+ * comprising a opening and a closing character sequence this method can also be called
+ * when the scanner is positioned already between the opening and the closing sequence.
+ * In this case, <code>resume</code> must be set to <code>true</code>.
+ *
+ * @param scanner the character scanner to be used by this rule
+ * @param resume indicates that the rule starts working between the opening and the closing character sequence
+ * @return the token computed by the rule
+ */
+ IToken evaluate(ICharacterScanner scanner, boolean resume);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java
new file mode 100644
index 000000000..667de4689
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * Defines the interface for a rule used in the scanning of text for the purpose of document
+ * partitioning or text styling.
+ *
+ * @see ICharacterScanner
+ */
+public interface IRule {
+
+ /**
+ * Evaluates the rule by examining the characters available from the provided character scanner.
+ * The token returned by this rule returns <code>true</code> when calling
+ * <code>isUndefined</code>, if the text that the rule investigated does not match the rule's
+ * requirements
+ *
+ * @param scanner the character scanner to be used by this rule
+ * @return the token computed by the rule
+ */
+ IToken evaluate(ICharacterScanner scanner);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java
new file mode 100644
index 000000000..4502569c0
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * A token to be returned by a rule.
+ */
+public interface IToken {
+
+ /**
+ * Return whether this token is undefined.
+ *
+ * @return <code>true</code>if this token is undefined
+ */
+ boolean isUndefined();
+
+ /**
+ * Return whether this token represents a whitespace.
+ *
+ * @return <code>true</code>if this token represents a whitespace
+ */
+ boolean isWhitespace();
+
+ /**
+ * Return whether this token represents End Of File.
+ *
+ * @return <code>true</code>if this token represents EOF
+ */
+ boolean isEOF();
+
+ /**
+ * Return whether this token is neither undefined, nor whitespace, nor EOF.
+ *
+ * @return <code>true</code>if this token is not undefined, not a whitespace, and not EOF
+ */
+ boolean isOther();
+
+ /**
+ * Return a data attached to this token. The semantics of this data kept undefined by this interface.
+ *
+ * @return the data attached to this token.
+ */
+ Object getData();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java
new file mode 100644
index 000000000..dd7ff43b7
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * A token scanner scans a range of a document and reports about the token it finds.
+ * A scanner has state. When asked, the scanner returns the offset and the length of the
+ * last found token.
+ *
+ * @see org.eclipse.jface.text.rules.IToken
+ * @since 2.0
+ */
+public interface ITokenScanner {
+
+ /**
+ * Configures the scanner by providing access to the document range that should
+ * be scanned.
+ *
+ * @param document the document to scan
+ * @param offset the offset of the document range to scan
+ * @param length the length of the document range to scan
+ */
+ void setRange(IDocument document, int offset, int length);
+
+ /**
+ * Returns the next token in the document.
+ *
+ * @return the next token in the document
+ */
+ IToken nextToken();
+
+ /**
+ * Returns the offset of the last token read by this scanner.
+ *
+ * @return the offset of the last token read by this scanner
+ */
+ int getTokenOffset();
+
+ /**
+ * Returns the length of the last token read by this scanner.
+ *
+ * @return the length of the last token read by this scanner
+ */
+ int getTokenLength();
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java
new file mode 100644
index 000000000..5bd84bf38
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * Defines the interface by which <code>WhitespaceRule</code>
+ * determines whether a given character is to be considered
+ * whitespace in the current context.
+ */
+public interface IWhitespaceDetector {
+
+ /**
+ * Returns whether the specified character is whitespace.
+ *
+ * @param c the character to be checked
+ * @return <code>true</code> if the specified character is a whitespace char
+ */
+ boolean isWhitespace(char c);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java
new file mode 100644
index 000000000..ae63ee80f
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * Defines the interface by which <code>WordRule</code>
+ * determines whether a given character is valid as part
+ * of a word in the current context.
+ */
+public interface IWordDetector {
+
+ /**
+ * Returns whether the specified character is
+ * valid as the first character in a word.
+ *
+ * @param c the character to be checked
+ * @return <code>true</code> is a valid first character in a word, <code>false</code> otherwise
+ */
+ boolean isWordStart(char c);
+
+ /**
+ * Returns whether the specified character is
+ * valid as a subsequent character in a word.
+ *
+ * @param c the character to be checked
+ * @return <code>true</code> if the character is a valid word part, <code>false</code> otherwise
+ */
+ boolean isWordPart(char c);
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java
new file mode 100644
index 000000000..7887e7842
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * A rule for detecting patterns which begin with a given
+ * sequence and may end with a given sequence thereby spanning
+ * multiple lines.
+ */
+public class MultiLineRule extends PatternRule {
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specified token.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ */
+ public MultiLineRule(String startSequence, String endSequence, IToken token) {
+ this(startSequence, endSequence, token, (char) 0);
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specific token.
+ * Any character which follows the given escape character will be ignored.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ * @param escapeCharacter the escape character
+ */
+ public MultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) {
+ this(startSequence, endSequence, token, escapeCharacter, false);
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specific token. Any character that follows the
+ * given escape character will be ignored. <code>breakOnEOF</code> indicates whether
+ * EOF is equivalent to detecting the <code>endSequence</code>.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ * @param escapeCharacter the escape character
+ * @param breaksOnEOF indicates whether the end of the file terminates this rule successfully
+ * @since 2.1
+ */
+ public MultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF) {
+ super(startSequence, endSequence, token, escapeCharacter, false, breaksOnEOF);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java
new file mode 100644
index 000000000..d1d92f944
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Christopher Lenz (cmlenz@gmx.de) - support for line continuation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * Standard implementation of <code>IPredicateRule</code>.
+ * Is is capable of detecting a pattern which begins with a given start
+ * sequence and ends with a given end sequence. If the end sequence is
+ * not specified, it can be either end of line, end or file, or both. Additionally,
+ * the pattern can be constrained to begin in a certain column. The rule can also
+ * be used to check whether the text to scan covers half of the pattern, i.e. contains
+ * the end sequence required by the rule.
+ */
+public class PatternRule implements IPredicateRule {
+
+ /**
+ * Comparator that orders <code>char[]</code> in decreasing array lengths.
+ *
+ * @since 3.1
+ */
+ private static class DecreasingCharArrayLengthComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return ((char[]) o2).length - ((char[]) o1).length;
+ }
+ }
+
+ /** Internal setting for the un-initialized column constraint */
+ protected static final int UNDEFINED= -1;
+
+ /** The token to be returned on success */
+ protected IToken fToken;
+ /** The pattern's start sequence */
+ protected char[] fStartSequence;
+ /** The pattern's end sequence */
+ protected char[] fEndSequence;
+ /** The pattern's column constrain */
+ protected int fColumn= UNDEFINED;
+ /** The pattern's escape character */
+ protected char fEscapeCharacter;
+ /**
+ * Indicates whether the escape character continues a line
+ * @since 3.0
+ */
+ protected boolean fEscapeContinuesLine;
+ /** Indicates whether end of line terminates the pattern */
+ protected boolean fBreaksOnEOL;
+ /** Indicates whether end of file terminates the pattern */
+ protected boolean fBreaksOnEOF;
+
+ /**
+ * Line delimiter comparator which orders according to decreasing delimiter length.
+ * @since 3.1
+ */
+ private Comparator fLineDelimiterComparator= new DecreasingCharArrayLengthComparator();
+ /**
+ * Cached line delimiters.
+ * @since 3.1
+ */
+ private char[][] fLineDelimiters;
+ /**
+ * Cached sorted {@linkplain #fLineDelimiters}.
+ * @since 3.1
+ */
+ private char[][] fSortedLineDelimiters;
+
+ /**
+ * Creates a rule for the given starting and ending sequence.
+ * When these sequences are detected the rule will return the specified token.
+ * Alternatively, the sequence can also be ended by the end of the line.
+ * Any character which follows the given escapeCharacter will be ignored.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+ * @param token the token which will be returned on success
+ * @param escapeCharacter any character following this one will be ignored
+ * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+ */
+ public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL) {
+ Assert.isTrue(startSequence != null && startSequence.length() > 0);
+ Assert.isTrue(endSequence != null || breaksOnEOL);
+ Assert.isNotNull(token);
+
+ fStartSequence= startSequence.toCharArray();
+ fEndSequence= (endSequence == null ? new char[0] : endSequence.toCharArray());
+ fToken= token;
+ fEscapeCharacter= escapeCharacter;
+ fBreaksOnEOL= breaksOnEOL;
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence.
+ * When these sequences are detected the rule will return the specified token.
+ * Alternatively, the sequence can also be ended by the end of the line or the end of the file.
+ * Any character which follows the given escapeCharacter will be ignored.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+ * @param token the token which will be returned on success
+ * @param escapeCharacter any character following this one will be ignored
+ * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+ * @param breaksOnEOF indicates whether the end of the file also terminates the pattern
+ * @since 2.1
+ */
+ public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF) {
+ this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL);
+ fBreaksOnEOF= breaksOnEOF;
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence.
+ * When these sequences are detected the rule will return the specified token.
+ * Alternatively, the sequence can also be ended by the end of the line or the end of the file.
+ * Any character which follows the given escapeCharacter will be ignored. An end of line
+ * immediately after the given <code>lineContinuationCharacter</code> will not cause the
+ * pattern to terminate even if <code>breakOnEOL</code> is set to true.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+ * @param token the token which will be returned on success
+ * @param escapeCharacter any character following this one will be ignored
+ * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+ * @param breaksOnEOF indicates whether the end of the file also terminates the pattern
+ * @param escapeContinuesLine indicates whether the specified escape character is used for line
+ * continuation, so that an end of line immediately after the escape character does not
+ * terminate the pattern, even if <code>breakOnEOL</code> is set
+ * @since 3.0
+ */
+ public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF, boolean escapeContinuesLine) {
+ this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL, breaksOnEOF);
+ fEscapeContinuesLine= escapeContinuesLine;
+ }
+
+ /**
+ * Sets a column constraint for this rule. If set, the rule's token
+ * will only be returned if the pattern is detected starting at the
+ * specified column. If the column is smaller then 0, the column
+ * constraint is considered removed.
+ *
+ * @param column the column in which the pattern starts
+ */
+ public void setColumnConstraint(int column) {
+ if (column < 0)
+ column= UNDEFINED;
+ fColumn= column;
+ }
+
+
+ /**
+ * Evaluates this rules without considering any column constraints.
+ *
+ * @param scanner the character scanner to be used
+ * @return the token resulting from this evaluation
+ */
+ protected IToken doEvaluate(ICharacterScanner scanner) {
+ return doEvaluate(scanner, false);
+ }
+
+ /**
+ * Evaluates this rules without considering any column constraints. Resumes
+ * detection, i.e. look sonly for the end sequence required by this rule if the
+ * <code>resume</code> flag is set.
+ *
+ * @param scanner the character scanner to be used
+ * @param resume <code>true</code> if detection should be resumed, <code>false</code> otherwise
+ * @return the token resulting from this evaluation
+ * @since 2.0
+ */
+ protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) {
+
+ if (resume) {
+
+ if (endSequenceDetected(scanner))
+ return fToken;
+
+ } else {
+
+ int c= scanner.read();
+ if (c == fStartSequence[0]) {
+ if (sequenceDetected(scanner, fStartSequence, false)) {
+ if (endSequenceDetected(scanner))
+ return fToken;
+ }
+ }
+ }
+
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ /*
+ * @see IRule#evaluate(ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ return evaluate(scanner, false);
+ }
+
+ /**
+ * Returns whether the end sequence was detected. As the pattern can be considered
+ * ended by a line delimiter, the result of this method is <code>true</code> if the
+ * rule breaks on the end of the line, or if the EOF character is read.
+ *
+ * @param scanner the character scanner to be used
+ * @return <code>true</code> if the end sequence has been detected
+ */
+ protected boolean endSequenceDetected(ICharacterScanner scanner) {
+
+ char[][] originalDelimiters= scanner.getLegalLineDelimiters();
+ int count= originalDelimiters.length;
+ if (fLineDelimiters == null || fLineDelimiters.length != count) {
+ fSortedLineDelimiters= new char[count][];
+ } else {
+ while (count > 0 && Arrays.equals(fLineDelimiters[count - 1], originalDelimiters[count - 1]))
+ count--;
+ }
+ if (count != 0) {
+ fLineDelimiters= originalDelimiters;
+ System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length);
+ Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator);
+ }
+
+ int readCount= 1;
+ int c;
+ while ((c= scanner.read()) != ICharacterScanner.EOF) {
+ if (c == fEscapeCharacter) {
+ // Skip escaped character(s)
+ if (fEscapeContinuesLine) {
+ c= scanner.read();
+ for (int i= 0; i < fSortedLineDelimiters.length; i++) {
+ if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], fBreaksOnEOF))
+ break;
+ }
+ } else
+ scanner.read();
+
+ } else if (fEndSequence.length > 0 && c == fEndSequence[0]) {
+ // Check if the specified end sequence has been found.
+ if (sequenceDetected(scanner, fEndSequence, fBreaksOnEOF))
+ return true;
+ } else if (fBreaksOnEOL) {
+ // Check for end of line since it can be used to terminate the pattern.
+ for (int i= 0; i < fSortedLineDelimiters.length; i++) {
+ if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], fBreaksOnEOF))
+ return true;
+ }
+ }
+ readCount++;
+ }
+
+ if (fBreaksOnEOF)
+ return true;
+
+ for (; readCount > 0; readCount--)
+ scanner.unread();
+
+ return false;
+ }
+
+ /**
+ * Returns whether the next characters to be read by the character scanner
+ * are an exact match with the given sequence. No escape characters are allowed
+ * within the sequence. If specified the sequence is considered to be found
+ * when reading the EOF character.
+ *
+ * @param scanner the character scanner to be used
+ * @param sequence the sequence to be detected
+ * @param eofAllowed indicated whether EOF terminates the pattern
+ * @return <code>true</code> if the given sequence has been detected
+ */
+ protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
+ for (int i= 1; i < sequence.length; i++) {
+ int c= scanner.read();
+ if (c == ICharacterScanner.EOF && eofAllowed) {
+ return true;
+ } else if (c != sequence[i]) {
+ // Non-matching character detected, rewind the scanner back to the start.
+ // Do not unread the first character.
+ scanner.unread();
+ for (int j= i-1; j > 0; j--)
+ scanner.unread();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /*
+ * @see IPredicateRule#evaluate(ICharacterScanner, boolean)
+ * @since 2.0
+ */
+ public IToken evaluate(ICharacterScanner scanner, boolean resume) {
+ if (fColumn == UNDEFINED)
+ return doEvaluate(scanner, resume);
+
+ int c= scanner.read();
+ scanner.unread();
+ if (c == fStartSequence[0])
+ return (fColumn == scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED);
+ return Token.UNDEFINED;
+ }
+
+ /*
+ * @see IPredicateRule#getSuccessToken()
+ * @since 2.0
+ */
+ public IToken getSuccessToken() {
+ return fToken;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java
new file mode 100644
index 000000000..55dde65d5
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * Scanner that exclusively uses predicate rules.
+ * <p>
+ * If a partial range is set (see {@link #setPartialRange(IDocument, int, int, String, int)} with
+ * content type that is not <code>null</code> then this scanner will first try the rules that match
+ * the given content type.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class RuleBasedPartitionScanner extends BufferedRuleBasedScanner implements IPartitionTokenScanner {
+
+ /** The content type of the partition in which to resume scanning. */
+ protected String fContentType;
+ /** The offset of the partition inside which to resume. */
+ protected int fPartitionOffset;
+
+
+ /**
+ * Disallow setting the rules since this scanner
+ * exclusively uses predicate rules.
+ *
+ * @param rules the sequence of rules controlling this scanner
+ */
+ public void setRules(IRule[] rules) {
+ throw new UnsupportedOperationException();
+ }
+
+ /*
+ * @see RuleBasedScanner#setRules(IRule[])
+ */
+ public void setPredicateRules(IPredicateRule[] rules) {
+ super.setRules(rules);
+ }
+
+ /*
+ * @see ITokenScanner#setRange(IDocument, int, int)
+ */
+ public void setRange(IDocument document, int offset, int length) {
+ setPartialRange(document, offset, length, null, -1);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If the given content type is not <code>null</code> then this scanner will first try the rules
+ * that match the given content type.
+ * </p>
+ */
+ public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+ fContentType= contentType;
+ fPartitionOffset= partitionOffset;
+ if (partitionOffset > -1) {
+ int delta= offset - partitionOffset;
+ if (delta > 0) {
+ super.setRange(document, partitionOffset, length + delta);
+ fOffset= offset;
+ return;
+ }
+ }
+ super.setRange(document, offset, length);
+ }
+
+ /*
+ * @see ITokenScanner#nextToken()
+ */
+ public IToken nextToken() {
+
+
+ if (fContentType == null || fRules == null) {
+ //don't try to resume
+ return super.nextToken();
+ }
+
+ // inside a partition
+
+ fColumn= UNDEFINED;
+ boolean resume= (fPartitionOffset > -1 && fPartitionOffset < fOffset);
+ fTokenOffset= resume ? fPartitionOffset : fOffset;
+
+ IPredicateRule rule;
+ IToken token;
+
+ for (int i= 0; i < fRules.length; i++) {
+ rule= (IPredicateRule) fRules[i];
+ token= rule.getSuccessToken();
+ if (fContentType.equals(token.getData())) {
+ token= rule.evaluate(this, resume);
+ if (!token.isUndefined()) {
+ fContentType= null;
+ return token;
+ }
+ }
+ }
+
+ // haven't found any rule for this type of partition
+ fContentType= null;
+ if (resume)
+ fOffset= fPartitionOffset;
+ return super.nextToken();
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java
new file mode 100644
index 000000000..dc2777672
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * A generic scanner which can be "programmed" with a sequence of rules.
+ * The scanner is used to get the next token by evaluating its rule in sequence until
+ * one is successful. If a rule returns a token which is undefined, the scanner will proceed to
+ * the next rule. Otherwise the token provided by the rule will be returned by
+ * the scanner. If no rule returned a defined token, this scanner returns a token
+ * which returns <code>true</code> when calling <code>isOther</code>, unless the end
+ * of the file is reached. In this case the token returns <code>true</code> when calling
+ * <code>isEOF</code>.
+ *
+ * @see IRule
+ */
+public class RuleBasedScanner implements ICharacterScanner, ITokenScanner {
+
+ /** The list of rules of this scanner */
+ protected IRule[] fRules;
+ /** The token to be returned by default if no rule fires */
+ protected IToken fDefaultReturnToken;
+ /** The document to be scanned */
+ protected IDocument fDocument;
+ /** The cached legal line delimiters of the document */
+ protected char[][] fDelimiters;
+ /** The offset of the next character to be read */
+ protected int fOffset;
+ /** The end offset of the range to be scanned */
+ protected int fRangeEnd;
+ /** The offset of the last read token */
+ protected int fTokenOffset;
+ /** The cached column of the current scanner position */
+ protected int fColumn;
+ /** Internal setting for the un-initialized column cache. */
+ protected static final int UNDEFINED= -1;
+
+ /**
+ * Creates a new rule based scanner which does not have any rule.
+ */
+ public RuleBasedScanner() {
+ }
+
+ /**
+ * Configures the scanner with the given sequence of rules.
+ *
+ * @param rules the sequence of rules controlling this scanner
+ */
+ public void setRules(IRule[] rules) {
+ if (rules != null) {
+ fRules= new IRule[rules.length];
+ System.arraycopy(rules, 0, fRules, 0, rules.length);
+ } else
+ fRules= null;
+ }
+
+ /**
+ * Configures the scanner's default return token. This is the token
+ * which is returned when none of the rules fired and EOF has not been
+ * reached.
+ *
+ * @param defaultReturnToken the default return token
+ * @since 2.0
+ */
+ public void setDefaultReturnToken(IToken defaultReturnToken) {
+ Assert.isNotNull(defaultReturnToken.getData());
+ fDefaultReturnToken= defaultReturnToken;
+ }
+
+ /*
+ * @see ITokenScanner#setRange(IDocument, int, int)
+ */
+ public void setRange(final IDocument document, int offset, int length) {
+ Assert.isLegal(document != null);
+ final int documentLength= document.getLength();
+ checkRange(offset, length, documentLength);
+
+ fDocument= document;
+ fOffset= offset;
+ fColumn= UNDEFINED;
+ fRangeEnd= offset + length;
+
+ String[] delimiters= fDocument.getLegalLineDelimiters();
+ fDelimiters= new char[delimiters.length][];
+ for (int i= 0; i < delimiters.length; i++)
+ fDelimiters[i]= delimiters[i].toCharArray();
+
+ if (fDefaultReturnToken == null)
+ fDefaultReturnToken= new Token(null);
+ }
+
+ /**
+ * Checks that the given range is valid.
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=69292
+ *
+ * @param offset the offset of the document range to scan
+ * @param length the length of the document range to scan
+ * @param documentLength the document's length
+ * @since 3.3
+ */
+ private void checkRange(int offset, int length, int documentLength) {
+ Assert.isLegal(offset > -1);
+ Assert.isLegal(length > -1);
+ Assert.isLegal(offset + length <= documentLength);
+ }
+
+ /*
+ * @see ITokenScanner#getTokenOffset()
+ */
+ public int getTokenOffset() {
+ return fTokenOffset;
+ }
+
+ /*
+ * @see ITokenScanner#getTokenLength()
+ */
+ public int getTokenLength() {
+ if (fOffset < fRangeEnd)
+ return fOffset - getTokenOffset();
+ return fRangeEnd - getTokenOffset();
+ }
+
+
+ /*
+ * @see ICharacterScanner#getColumn()
+ */
+ public int getColumn() {
+ if (fColumn == UNDEFINED) {
+ try {
+ int line= fDocument.getLineOfOffset(fOffset);
+ int start= fDocument.getLineOffset(line);
+
+ fColumn= fOffset - start;
+
+ } catch (BadLocationException ex) {
+ }
+ }
+ return fColumn;
+ }
+
+ /*
+ * @see ICharacterScanner#getLegalLineDelimiters()
+ */
+ public char[][] getLegalLineDelimiters() {
+ return fDelimiters;
+ }
+
+ /*
+ * @see ITokenScanner#nextToken()
+ */
+ public IToken nextToken() {
+
+ fTokenOffset= fOffset;
+ fColumn= UNDEFINED;
+
+ if (fRules != null) {
+ for (int i= 0; i < fRules.length; i++) {
+ IToken token= (fRules[i].evaluate(this));
+ if (!token.isUndefined())
+ return token;
+ }
+ }
+
+ if (read() == EOF)
+ return Token.EOF;
+ return fDefaultReturnToken;
+ }
+
+ /*
+ * @see ICharacterScanner#read()
+ */
+ public int read() {
+
+ try {
+
+ if (fOffset < fRangeEnd) {
+ try {
+ return fDocument.getChar(fOffset);
+ } catch (BadLocationException e) {
+ }
+ }
+
+ return EOF;
+
+ } finally {
+ ++ fOffset;
+ fColumn= UNDEFINED;
+ }
+ }
+
+ /*
+ * @see ICharacterScanner#unread()
+ */
+ public void unread() {
+ --fOffset;
+ fColumn= UNDEFINED;
+ }
+}
+
+
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java
new file mode 100644
index 000000000..5b26d852d
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Christopher Lenz (cmlenz@gmx.de) - support for line continuation
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+/**
+ * A specific configuration of pattern rule whereby
+ * the pattern begins with a specific sequence and may
+ * end with a specific sequence, but will not span more
+ * than a single line.
+ */
+public class SingleLineRule extends PatternRule {
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specified token.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ */
+ public SingleLineRule(String startSequence, String endSequence, IToken token) {
+ this(startSequence, endSequence, token, (char) 0);
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specified token.
+ * Any character which follows the given escape character
+ * will be ignored.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ * @param escapeCharacter the escape character
+ */
+ public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) {
+ this(startSequence, endSequence, token, escapeCharacter, false);
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specified token. Alternatively, the
+ * line can also be ended with the end of the file.
+ * Any character which follows the given escape character
+ * will be ignored.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ * @param escapeCharacter the escape character
+ * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule
+ * @since 2.1
+ */
+ public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF) {
+ super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF);
+ }
+
+ /**
+ * Creates a rule for the given starting and ending sequence
+ * which, if detected, will return the specified token. Alternatively, the
+ * line can also be ended with the end of the file.
+ * Any character which follows the given escape character
+ * will be ignored. In addition, an escape character immediately before an
+ * end of line can be set to continue the line.
+ *
+ * @param startSequence the pattern's start sequence
+ * @param endSequence the pattern's end sequence
+ * @param token the token to be returned on success
+ * @param escapeCharacter the escape character
+ * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule
+ * @param escapeContinuesLine indicates whether the specified escape character is used for line
+ * continuation, so that an end of line immediately after the escape character does not
+ * terminate the line, even if <code>breakOnEOL</code> is true
+ * @since 3.0
+ */
+ public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF, boolean escapeContinuesLine) {
+ super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF, escapeContinuesLine);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java
new file mode 100644
index 000000000..24f48a458
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.text.rules;
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * Standard implementation of <code>IToken</code>.
+ */
+public class Token implements IToken {
+
+ /** Internal token type: Undefined */
+ private static final int T_UNDEFINED= 0;
+ /** Internal token type: EOF */
+ private static final int T_EOF= 1;
+ /** Internal token type: Whitespace */
+ private static final int T_WHITESPACE= 2;
+ /** Internal token type: Others */
+ private static final int T_OTHER= 3;
+
+
+ /**
+ * Standard token: Undefined.
+ */
+ public static final IToken UNDEFINED= new Token(T_UNDEFINED);
+ /**
+ * Standard token: End Of File.
+ */
+ public static final IToken EOF= new Token(T_EOF);
+ /**
+ * Standard token: Whitespace.
+ */
+ public static final IToken WHITESPACE= new Token(T_WHITESPACE);
+
+ /**
+ * Standard token: Neither {@link #UNDEFINED}, {@link #WHITESPACE}, nor {@link #EOF}.
+ * @deprecated will be removed
+ */
+ public static final IToken OTHER= new Token(T_OTHER);
+
+ /** The type of this token */
+ private int fType;
+ /** The data associated with this token */
+ private Object fData;
+
+ /**
+ * Creates a new token according to the given specification which does not
+ * have any data attached to it.
+ *
+ * @param type the type of the token
+ * @since 2.0
+ */
+ private Token(int type) {
+ fType= type;
+ fData= null;
+ }
+
+ /**
+ * Creates a new token which represents neither undefined, whitespace, nor EOF.
+ * The newly created token has the given data attached to it.
+ *
+ * @param data the data attached to the newly created token
+ */
+ public Token(Object data) {
+ fType= T_OTHER;
+ fData= data;
+ }
+
+ /**
+ * Re-initializes the data of this token. The token may not represent
+ * undefined, whitespace, or EOF.
+ *
+ * @param data to be attached to the token
+ * @since 2.0
+ */
+ public void setData(Object data) {
+ Assert.isTrue(isOther());
+ fData= data;
+ }
+
+ /*
+ * @see IToken#getData()
+ */
+ public Object getData() {
+ return fData;
+ }
+
+ /*
+ * @see IToken#isOther()
+ */
+ public boolean isOther() {
+ return (fType == T_OTHER);
+ }
+
+ /*
+ * @see IToken#isEOF()
+ */
+ public boolean isEOF() {
+ return (fType == T_EOF);
+ }
+
+ /*
+ * @see IToken#isWhitespace()
+ */
+ public boolean isWhitespace() {
+ return (fType == T_WHITESPACE);
+ }
+
+ /*
+ * @see IToken#isUndefined()
+ */
+ public boolean isUndefined() {
+ return (fType == T_UNDEFINED);
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java
new file mode 100644
index 000000000..6bd1af7f2
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting whitespace.
+ * A whitespace rule uses a whitespace detector in order to find out which
+ * characters are whitespace characters.
+ *
+ * @see IWhitespaceDetector
+ */
+public class WhitespaceRule implements IRule {
+
+ /** The whitespace detector used by this rule */
+ protected IWhitespaceDetector fDetector;
+
+ /**
+ * The token returned for whitespace.
+ * @since 3.5
+ */
+ protected final IToken fWhitespaceToken;
+
+ /**
+ * Creates a rule which, with the help of an whitespace detector, will return
+ * {@link Token#WHITESPACE} when a whitespace is detected.
+ *
+ * @param detector the rule's whitespace detector
+ */
+ public WhitespaceRule(IWhitespaceDetector detector) {
+ this(detector, Token.WHITESPACE);
+ }
+
+ /**
+ * Creates a rule which, with the help of an whitespace detector, will return the given
+ * whitespace token when a whitespace is detected.
+ *
+ * @param detector the rule's whitespace detector
+ * @param token the token returned for whitespace
+ * @since 3.5
+ */
+ public WhitespaceRule(IWhitespaceDetector detector, IToken token) {
+ Assert.isNotNull(detector);
+ Assert.isNotNull(token);
+ fDetector= detector;
+ fWhitespaceToken= token;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@link #fWhitespaceToken} if whitespace got detected, {@link Token#UNDEFINED}
+ * otherwise
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ int c= scanner.read();
+ if (fDetector.isWhitespace((char) c)) {
+ do {
+ c= scanner.read();
+ } while (fDetector.isWhitespace((char) c));
+ scanner.unread();
+ return fWhitespaceToken;
+ }
+
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+}
diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java
new file mode 100644
index 000000000..b52a7ea38
--- /dev/null
+++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Doug Satchwell <doug.satchwell@ymail.com> - [implementation] Performance issue with jface text WordRule - http://bugs.eclipse.org/277299
+ *******************************************************************************/
+package org.eclipse.jface.text.rules;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * An implementation of {@link IRule} capable of detecting words. A word rule also allows to
+ * associate a token to a word. That is, not only can the rule be used to provide tokens for exact
+ * matches, but also for the generalized notion of a word in the context in which it is used. A word
+ * rule uses a word detector to determine what a word is.
+ *
+ * @see IWordDetector
+ */
+public class WordRule implements IRule {
+
+ /** Internal setting for the un-initialized column constraint. */
+ protected static final int UNDEFINED= -1;
+
+ /** The word detector used by this rule. */
+ protected IWordDetector fDetector;
+ /** The default token to be returned on success and if nothing else has been specified. */
+ protected IToken fDefaultToken;
+ /** The column constraint. */
+ protected int fColumn= UNDEFINED;
+ /** The table of predefined words and token for this rule. */
+ protected Map fWords= new HashMap();
+ /** Buffer used for pattern detection. */
+ private StringBuffer fBuffer= new StringBuffer();
+ /**
+ * Tells whether this rule is case sensitive.
+ * @since 3.3
+ */
+ private boolean fIgnoreCase= false;
+
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the scanner
+ * will be rolled back and an undefined token will be returned in order to allow
+ * any subsequent rules to analyze the characters.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @see #addWord(String, IToken)
+ */
+ public WordRule(IWordDetector detector) {
+ this(detector, Token.UNDEFINED, false);
+ }
+
+ /**
+ * Creates a rule which, with the help of a word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ * @see #addWord(String, IToken)
+ */
+ public WordRule(IWordDetector detector, IToken defaultToken) {
+ this(detector, defaultToken, false);
+ }
+
+ /**
+ * Creates a rule which, with the help of a word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ * @param ignoreCase the case sensitivity associated with this rule
+ * @see #addWord(String, IToken)
+ * @since 3.3
+ */
+ public WordRule(IWordDetector detector, IToken defaultToken, boolean ignoreCase) {
+ Assert.isNotNull(detector);
+ Assert.isNotNull(defaultToken);
+
+ fDetector= detector;
+ fDefaultToken= defaultToken;
+ fIgnoreCase= ignoreCase;
+ }
+
+ /**
+ * Adds a word and the token to be returned if it is detected.
+ *
+ * @param word the word this rule will search for, may not be <code>null</code>
+ * @param token the token to be returned if the word has been found, may not be <code>null</code>
+ */
+ public void addWord(String word, IToken token) {
+ Assert.isNotNull(word);
+ Assert.isNotNull(token);
+
+ // If case-insensitive, convert to lower case before adding to the map
+ if (fIgnoreCase)
+ word= word.toLowerCase();
+ fWords.put(word, token);
+ }
+
+ /**
+ * Sets a column constraint for this rule. If set, the rule's token
+ * will only be returned if the pattern is detected starting at the
+ * specified column. If the column is smaller then 0, the column
+ * constraint is considered removed.
+ *
+ * @param column the column in which the pattern starts
+ */
+ public void setColumnConstraint(int column) {
+ if (column < 0)
+ column= UNDEFINED;
+ fColumn= column;
+ }
+
+ /*
+ * @see IRule#evaluate(ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ int c= scanner.read();
+ if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c)) {
+ if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+ fBuffer.setLength(0);
+ do {
+ fBuffer.append((char) c);
+ c= scanner.read();
+ } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+ scanner.unread();
+
+ String buffer= fBuffer.toString();
+ // If case-insensitive, convert to lower case before accessing the map
+ if (fIgnoreCase)
+ buffer= buffer.toLowerCase();
+
+ IToken token= (IToken)fWords.get(buffer);
+
+ if (token != null)
+ return token;
+
+ if (fDefaultToken.isUndefined())
+ unreadBuffer(scanner);
+
+ return fDefaultToken;
+ }
+ }
+
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Returns the characters in the buffer to the scanner.
+ *
+ * @param scanner the scanner to be used
+ */
+ protected void unreadBuffer(ICharacterScanner scanner) {
+ for (int i= fBuffer.length() - 1; i >= 0; i--)
+ scanner.unread();
+ }
+
+}

Back to the top