Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Reckord2017-12-08 13:01:45 -0500
committerCarsten Reckord2018-01-30 07:56:22 -0500
commit6a35da449d6559dcb0988c0ba842177eef7e27f0 (patch)
tree312ab38aeea5486c22cc9d5e9369e928c503e5be
parentc8a75c5a719cbf05bc1384dbff713955b756d665 (diff)
downloadeclipse.platform.text-6a35da449d6559dcb0988c0ba842177eef7e27f0.tar.gz
eclipse.platform.text-6a35da449d6559dcb0988c0ba842177eef7e27f0.tar.xz
eclipse.platform.text-6a35da449d6559dcb0988c0ba842177eef7e27f0.zip
528344 - [Generic Editor] Default highlighter patterns are brokenI20180130-2000
Use a single (positive) pattern definition for valid words to match both the current word and occurrences within the text Change-Id: I6d05484b9991a543c2979005deae4533cb8c2735 Signed-off-by: Carsten Reckord <reckord@yatta.de>
-rw-r--r--org.eclipse.ui.genericeditor.tests/plugin.xml2
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AbstratGenericEditorTest.java11
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/HighlightTest.java116
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/ReconcilerTest.java29
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultWordHighlightStrategy.java41
5 files changed, 162 insertions, 37 deletions
diff --git a/org.eclipse.ui.genericeditor.tests/plugin.xml b/org.eclipse.ui.genericeditor.tests/plugin.xml
index a9c5904dc..1700b8ff8 100644
--- a/org.eclipse.ui.genericeditor.tests/plugin.xml
+++ b/org.eclipse.ui.genericeditor.tests/plugin.xml
@@ -140,7 +140,7 @@
point="org.eclipse.ui.genericeditor.highlightReconcilers">
<highlightReconciler
class="org.eclipse.ui.genericeditor.tests.contributions.HighlightReconciler"
- contentType="org.eclipse.ui.genericeditor.tests.content-type">
+ contentType="org.eclipse.ui.genericeditor.tests.content-type-bar">
</highlightReconciler>
</extension>
</plugin>
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AbstratGenericEditorTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AbstratGenericEditorTest.java
index ef1e3b0c4..b0a8635fa 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AbstratGenericEditorTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AbstratGenericEditorTest.java
@@ -55,8 +55,13 @@ public class AbstratGenericEditorTest {
project = ResourcesPlugin.getWorkspace().getRoot().getProject(getClass().getName() + System.currentTimeMillis());
project.create(null);
project.open(null);
- createAndOpenFile("foo.txt", "bar 'bar'");
+ project.setDefaultCharset("UTF-8", null);
+ createAndOpenFile();
}
+
+ protected void createAndOpenFile() throws Exception {
+ createAndOpenFile("foo.txt", "bar 'bar'");
+ }
/**
* Creates a new file in the project, opens it, and associate that file with the test state
@@ -67,7 +72,8 @@ public class AbstratGenericEditorTest {
*/
protected void createAndOpenFile(String name, String contents) throws Exception {
this.file = project.getFile(name);
- this.file.create(new ByteArrayInputStream(contents.getBytes()), true, null);
+ this.file.create(new ByteArrayInputStream(contents.getBytes("UTF-8")), true, null);
+ this.file.setCharset("UTF-8", null);
this.editor = (ExtensionBasedTextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().openEditor(new FileEditorInput(this.file), "org.eclipse.ui.genericeditor.GenericEditor");
}
@@ -82,6 +88,7 @@ public class AbstratGenericEditorTest {
editor.close(false);
editor = null;
}
+ while(Display.getDefault().readAndDispatch()) {}
if (file != null) {
file.delete(true, new NullProgressMonitor());
file = null;
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/HighlightTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/HighlightTest.java
index e259ffe30..4d2c36571 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/HighlightTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/HighlightTest.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.ui.genericeditor.tests;
+import static org.junit.Assert.assertEquals;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -19,6 +21,8 @@ import org.junit.Test;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.tests.util.DisplayHelper;
@@ -27,25 +31,115 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
public class HighlightTest extends AbstratGenericEditorTest {
- private static final String ANNOTATION_TYPE = "org.eclipse.ui.genericeditor.text"; //$NON-NLS-1$
+ private static final String ANNOTATION_TYPE= "org.eclipse.ui.genericeditor.text"; //$NON-NLS-1$
+
+ private static final String EDITOR_TEXT= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+
+ @Override
+ protected void createAndOpenFile() throws Exception {
+ //leave editor creation to individual tests
+ }
+
+ @Test
+ public void testCustomHighlightReconciler() throws Exception {
+ createAndOpenFile("bar.txt", "bar 'bar'");
+
+ checkHighlightForCaretOffset(0, "'bar'", 1);
+ }
+
+ @Test
+ public void testHighlightWordAtDocumentStart() throws Exception {
+ createAndOpenFile("foo.txt", EDITOR_TEXT);
+
+ checkHighlightForCaretOffset(0, "Lorem", 3);
+ }
+
+ @Test
+ public void testHighlightWordWithNonLetterParts() throws Exception {
+ String complexWord= "dolor_sit123amet45";
+ String editorText= EDITOR_TEXT.replaceFirst("dolor sit amet", complexWord).replaceFirst("dolor sit amet", complexWord);
+ createAndOpenFile("foo.txt", editorText);
+
+ checkHighlightForCaretOffset(editorText.indexOf("dolor") + 3, complexWord, 2);
+ checkHighlightForCaretOffset(editorText.indexOf("_sit") + 3, complexWord, 2);
+ checkHighlightForCaretOffset(editorText.indexOf("123") + 1, complexWord, 2);
+ checkHighlightForCaretOffset(editorText.indexOf("amet") + 1, complexWord, 2);
+ }
+
+ @Test
+ public void testHighlightSimpleWordNotMatchingWordPart() throws Exception {
+ String complexWord= "dolor_sit123amet45";
+ String editorText= EDITOR_TEXT.replaceFirst("dolor sit amet", complexWord);
+ createAndOpenFile("foo.txt", editorText);
+
+ checkHighlightForCaretOffset(editorText.indexOf("dolor ") + 1, "dolor", 2);
+ checkHighlightForCaretOffset(editorText.indexOf(" sit") + 1, "sit", 2);
+ checkHighlightForCaretOffset(editorText.indexOf(" amet") + 1, "amet", 2);
+ }
@Test
- public void testHighlightReconciler() {
- IDocumentProvider dp = editor.getDocumentProvider();
- IAnnotationModel am = dp.getAnnotationModel(editor.getEditorInput());
+ public void testHighlightNonAsciiCharacters() throws Exception {
+ String complexWord= "sit\u00f6\u00f6amet";
+ String editorText= EDITOR_TEXT.replaceFirst("sit amet", complexWord).replaceFirst("sit amet", complexWord);
+ createAndOpenFile("foo.txt", editorText);
+
+ checkHighlightForCaretOffset(editorText.indexOf("sit") + 1, complexWord, 2);
+ checkHighlightForCaretOffset(editorText.indexOf("\u00f6") + 1, complexWord, 2);
+ checkHighlightForCaretOffset(editorText.indexOf("amet") + 1, complexWord, 2);
+ }
+
+ private void checkHighlightForCaretOffset(int pos, String expectedHighlight, int expectedHighlightCount) throws Exception {
+ clearAnnotations();
+
+ editor.selectAndReveal(pos, 0);
+ waitForAnnotations(expectedHighlightCount);
+
+ List<Annotation> annotations= getAnnotationsFromAnnotationModel();
+
+ IAnnotationModel annotationModel= getAnnotationModel();
+ IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ for (int i= 0; i < annotations.size(); i++) {
+ Annotation annotation= annotations.get(i);
+ Position position= annotationModel.getPosition(annotation);
+ String highlight= document.get(position.offset, position.length);
+ assertEquals("Wrong highlight " + i + " at position " + position.offset, expectedHighlight, highlight);
+ }
+ Assert.assertEquals("Wrong number of highlights", expectedHighlightCount, annotations.size());
+ }
+
+ private void clearAnnotations() {
+ editor.selectAndReveal(0, 0);
+ IAnnotationModel annotationModel= getAnnotationModel();
+ List<Annotation> annotations= getAnnotationsFromAnnotationModel();
+ for (Annotation annotation : annotations) {
+ annotationModel.removeAnnotation(annotation);
+ }
+ }
+
+ private IAnnotationModel getAnnotationModel() {
+ IDocumentProvider dp= editor.getDocumentProvider();
+ IAnnotationModel am= dp.getAnnotationModel(editor.getEditorInput());
+ return am;
+ }
+
+ private void waitForAnnotations(int count) {
new DisplayHelper() {
+ final IAnnotationModel annotationModel= getAnnotationModel();
+
@Override
protected boolean condition() {
- return getAnnotationsFromAnnotationModel(am).size() == 1;
+ return getAnnotationsFromAnnotationModel().size() == count;
}
- }.waitForCondition(Display.getDefault().getActiveShell().getDisplay(), 2000);
- Assert.assertTrue("file does not have highlighting", getAnnotationsFromAnnotationModel(am).size() == 1);
+ }.waitForCondition(Display.getDefault(), 2000);
}
- private List<Annotation> getAnnotationsFromAnnotationModel(IAnnotationModel annotationModel) {
- List<Annotation> annotationList = new ArrayList<>();
- Iterator<Annotation> annotationIterator=annotationModel.getAnnotationIterator();
+
+ private List<Annotation> getAnnotationsFromAnnotationModel() {
+ List<Annotation> annotationList= new ArrayList<>();
+ Iterator<Annotation> annotationIterator= getAnnotationModel().getAnnotationIterator();
while (annotationIterator.hasNext()) {
- Annotation ann = annotationIterator.next();
+ Annotation ann= annotationIterator.next();
if (ann.getType().indexOf(ANNOTATION_TYPE) > -1) {
annotationList.add(ann);
}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/ReconcilerTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/ReconcilerTest.java
index 56c4a7cd4..0f5470814 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/ReconcilerTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/ReconcilerTest.java
@@ -17,6 +17,8 @@ import org.junit.Test;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -36,6 +38,8 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
public class ReconcilerTest extends AbstratGenericEditorTest {
protected ExtensionBasedTextEditor secondEditor;
+ protected IFile secondFile;
+ protected IProject secondProject;
@Test
public void testReconciler() throws Exception {
@@ -44,10 +48,10 @@ public class ReconcilerTest extends AbstratGenericEditorTest {
@Test
public void testMultipleEditors() throws Exception {
- IProject secondProject = ResourcesPlugin.getWorkspace().getRoot().getProject(getClass().getName() + System.currentTimeMillis());
+ secondProject= ResourcesPlugin.getWorkspace().getRoot().getProject(getClass().getName() + System.currentTimeMillis());
secondProject.create(null);
secondProject.open(null);
- IFile secondFile = secondProject.getFile("foo.txt");
+ secondFile= secondProject.getFile("foo.txt");
secondFile.create(new ByteArrayInputStream("bar 'bar'".getBytes()), true, null);
secondEditor = (ExtensionBasedTextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().openEditor(new FileEditorInput(secondFile), "org.eclipse.ui.genericeditor.GenericEditor");
@@ -56,7 +60,7 @@ public class ReconcilerTest extends AbstratGenericEditorTest {
@Test
public void testMultipleReconcilers() throws Exception {
- IFile secondFile = project.getFile("bar.txt");
+ secondFile = project.getFile("bar.txt");
secondFile.create(new ByteArrayInputStream("".getBytes()), true, null);
secondEditor = (ExtensionBasedTextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().openEditor(new FileEditorInput(secondFile), "org.eclipse.ui.genericeditor.GenericEditor");
@@ -82,4 +86,23 @@ public class ReconcilerTest extends AbstratGenericEditorTest {
Assert.assertTrue("file was not affected by reconciler", doc.get().contains(expectedText));
}
+ @Override
+ public void tearDown() throws Exception {
+ if (secondEditor != null)
+ {
+ secondEditor.close(false);
+ secondEditor = null;
+ while(Display.getDefault().readAndDispatch()) {}
+ }
+ if (secondFile != null)
+ {
+ secondFile.delete(true, new NullProgressMonitor());
+ secondFile = null;
+ }
+ super.tearDown();
+ if (secondProject != null)
+ {
+ secondProject.delete(true, new NullProgressMonitor());
+ }
+ }
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultWordHighlightStrategy.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultWordHighlightStrategy.java
index 44673c8d0..4f4ce28b0 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultWordHighlightStrategy.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultWordHighlightStrategy.java
@@ -57,8 +57,9 @@ public class DefaultWordHighlightStrategy implements IReconcilingStrategy, IReco
private ISourceViewer sourceViewer;
private IDocument document;
- private static final String WORD_REGEXP = "[a-zA-Z]+"; //$NON-NLS-1$
- private static final Pattern WORD_PATTERN = Pattern.compile(WORD_REGEXP);
+ private static final String WORD_REGEXP = "\\w+"; //$NON-NLS-1$
+ private static final Pattern WORD_PATTERN = Pattern.compile(WORD_REGEXP, Pattern.UNICODE_CHARACTER_CLASS);
+ private static final Pattern CURRENT_WORD_START_PATTERN = Pattern.compile(WORD_REGEXP + "$", Pattern.UNICODE_CHARACTER_CLASS); //$NON-NLS-1$
private Annotation[] fOccurrenceAnnotations = null;
@@ -71,13 +72,11 @@ public class DefaultWordHighlightStrategy implements IReconcilingStrategy, IReco
String text = document.get();
offset = ((ITextViewerExtension5)sourceViewer).widgetOffset2ModelOffset(offset);
- int wordStartOffset = findStartingOffset(text, offset);
- int wordEndOffset = findEndingOffset(text, offset);
- if(wordEndOffset <= wordStartOffset || wordEndOffset == -1 || wordStartOffset == -1) {
+ String word = findCurrentWord(text, offset);
+ if(word == null) {
removeOccurrenceAnnotations();
return;
}
- String word = text.substring(wordStartOffset, wordEndOffset);
Matcher m = WORD_PATTERN.matcher(text);
Map<Annotation, Position> annotationMap = new HashMap<>();
@@ -109,23 +108,25 @@ public class DefaultWordHighlightStrategy implements IReconcilingStrategy, IReco
}
}
- private static int findStartingOffset(String text, int offset) {
- final Pattern NON_ALPHANUMERIC_LAST_PATTERN = Pattern.compile("[^\\w](?!.*[^\\w])"); //$NON-NLS-1$
+ private static String findCurrentWord(String text, int offset) {
+ String wordStart = null;
+ String wordEnd = null;
+
String substring = text.substring(0, offset);
- Matcher m = NON_ALPHANUMERIC_LAST_PATTERN.matcher(substring);
- if(m.find()) {
- return m.end();
+ Matcher m = CURRENT_WORD_START_PATTERN.matcher(substring);
+ if (m.find()) {
+ wordStart=m.group();
}
- return -1;
- }
-
- private static int findEndingOffset(String text, int offset) {
- String substring = text.substring(offset);
- String[] split = substring.split("[^a-zA-Z0-9]+");//$NON-NLS-1$
- if(split.length == 0) {
- return -1;
+ substring = text.substring(offset);
+ m = WORD_PATTERN.matcher(substring);
+ if (m.lookingAt()) {
+ wordEnd = m.group();
}
- return offset + split[0].length();
+ if (wordStart != null && wordEnd != null)
+ return wordStart + wordEnd;
+ if (wordStart != null)
+ return wordStart;
+ return wordEnd;
}
public void install(ITextViewer viewer) {

Back to the top