| author | Deepak Azad | 2012-04-27 04:17:27 (EDT) |
|---|---|---|
| committer | Dani Megert | 2012-04-27 04:17:27 (EDT) |
| commit | 1b02d37376c3050930a5c0e7cb577494e267828d (patch) (side-by-side diff) | |
| tree | 116b3cc57e2421b3dd00362cc508bbd312982787 | |
| parent | 9a2cb80b2c308fec5e2faa29c9e33e9e37745f07 (diff) | |
| download | eclipse.platform.text-1b02d37376c3050930a5c0e7cb577494e267828d.zip eclipse.platform.text-1b02d37376c3050930a5c0e7cb577494e267828d.tar.gz eclipse.platform.text-1b02d37376c3050930a5c0e7cb577494e267828d.tar.bz2 | |
Fixed bug 372516: [syntax highlighting] bracket highlighting should alsov20120427-0817
work if caret is after the last bracket
4 files changed, 101 insertions, 57 deletions
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java index 00166bc..e3f84cd 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java @@ -38,10 +38,10 @@ import org.eclipse.jface.text.source.ICharacterPairMatcherExtension; */ public abstract class AbstractPairMatcherTest extends TestCase { - private final boolean fCaretInsideMatchedPair; + private final boolean fCaretEitherSideOfBracket; - public AbstractPairMatcherTest(boolean caretInsideMatchedPair) { - fCaretInsideMatchedPair= caretInsideMatchedPair; + public AbstractPairMatcherTest(boolean caretEitherSideOfBracket) { + fCaretEitherSideOfBracket= caretEitherSideOfBracket; } /** @@ -51,7 +51,7 @@ public abstract class AbstractPairMatcherTest extends TestCase { * @return the character pair matcher */ protected ICharacterPairMatcher createMatcher(final String chars) { - return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), fCaretInsideMatchedPair); + return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), fCaretEitherSideOfBracket); } /** @@ -156,7 +156,6 @@ public abstract class AbstractPairMatcherTest extends TestCase { public void testIncompleteMatch() throws BadLocationException { final ICharacterPairMatcher matcher= createMatcher("()[]{}"); performMatch(matcher, "(% "); - performMatch(matcher, "%( )"); performMatch(matcher, "( % )"); performMatch(matcher, "%"); matcher.dispose(); @@ -325,15 +324,11 @@ public abstract class AbstractPairMatcherTest extends TestCase { assertNull(region); } else { assertNotNull(region); - final boolean isForward= test.isEnclosingTestCase() ? false : test.fPos1 > test.fMatch2; - assertEquals(isForward, matcher.getAnchor() == ICharacterPairMatcher.RIGHT); - - final int offset= (isForward || test.isEnclosingTestCase()) ? test.getOffset() : test.getOffset() - 1; - final int length= ((isForward && (!fCaretInsideMatchedPair || test.isSelectionTestCase())) || test.isEnclosingTestCase()) - ? test.getLength() - : test.getLength() + 1; - assertEquals(length, region.getLength()); - assertEquals(offset, region.getOffset()); + final boolean isBackward= test.isEnclosingTestCase() ? false : test.fPos1 > test.fMatch2; + assertEquals(isBackward, matcher.getAnchor() == ICharacterPairMatcher.RIGHT); + + assertEquals(test.getLength(), region.getLength()); + assertEquals(test.getOffset(), region.getOffset()); } } @@ -360,16 +355,6 @@ public abstract class AbstractPairMatcherTest extends TestCase { int match2= str.lastIndexOf("#"); boolean enclosingTest= match1 != match2; - - if (!selectionTest && fCaretInsideMatchedPair) { - if (pos1 - 1 >= 0) { - char ch= str.charAt(pos1 - 1); - if ("()[]{}<>".indexOf(ch) % 2 == 1) { - pos1-= 1; - } - } - } - // account for the length of marker characters if (selectionTest) { if (!enclosingTest) { @@ -402,13 +387,35 @@ public abstract class AbstractPairMatcherTest extends TestCase { final String stripped= str.replaceAll("%", "").replaceAll("#", ""); - if (enclosingTest) + if (enclosingTest) { return new TestCase(stripped, pos1, pos2, match1, match2); - else { - if (selectionTest) - return new TestCase(stripped, pos1, pos2, pos2, match1); - else - return new TestCase(stripped, pos1, pos2, pos1, match1); + } else { + if (selectionTest) { + return new TestCase(stripped, pos1, pos2, pos1 < match1 ? pos1 : pos2, match1); + } else { + if (match1 == -1) + return new TestCase(stripped, pos1, pos2, pos1, match1); + + match2= match1; + match1= pos1; + if (!selectionTest && !enclosingTest) { + String chars= "()[]{}<>"; + if (fCaretEitherSideOfBracket && pos1 < stripped.length()) { + char ch= stripped.charAt(pos1); + char prevCh= pos1 - 1 >= 0 ? stripped.charAt(pos1 - 1) : Character.MIN_VALUE; + if (chars.indexOf(ch) % 2 == 1 && chars.indexOf(prevCh) % 2 != 0) { + match1++; + } + } + if (pos1 - 1 >= 0) { + char ch= stripped.charAt(pos1 - 1); + if (chars.indexOf(ch) % 2 == 0) { + match1--; + } + } + } + return new TestCase(stripped, pos1, pos2, match1, match2); + } } } diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java index 70f4f4c..bac928e 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java @@ -34,8 +34,7 @@ public class DefaultPairMatcherTest extends AbstractPairMatcherTest { /** Tests that the test case reader works */ - public void testTestCaseReader() { - super.testTestCaseReader(); + public void testTestCaseReader1() { performReaderTest("#( )%", 3, 0, "( )"); performReaderTest("( )%", 3, -1, "( )"); } @@ -61,6 +60,7 @@ public class DefaultPairMatcherTest extends AbstractPairMatcherTest { public void testIncompleteMatch1() throws BadLocationException { final ICharacterPairMatcher matcher= createMatcher("()[]{}"); performMatch(matcher, "( %)"); + performMatch(matcher, "%( )"); matcher.dispose(); } diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java index bfc71b5..56f3d98 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java @@ -13,6 +13,9 @@ package org.eclipse.jface.text.tests; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.source.ICharacterPairMatcher; + /** * Tests for the default pair matcher. @@ -31,8 +34,24 @@ public class DefaultPairMatcherTest2 extends AbstractPairMatcherTest { } /** Tests that the test case reader works */ - public void testTestCaseReader() { - performReaderTest("#( )%", 2, 0, "( )"); - performReaderTest("( )%", 2, -1, "( )"); + public void testTestCaseReader1() { + performReaderTest("#( )%", 3, 0, "( )"); + performReaderTest("( )%", 3, -1, "( )"); + } + + /** + * Very simple checks. + * + * @throws BadLocationException + */ + public void testSimpleMatchSameMatcher1() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "#( %)"); + performMatch(matcher, "#[ %]"); + performMatch(matcher, "#{ %}"); + performMatch(matcher, "%( )#"); + performMatch(matcher, "%[ ]#"); + performMatch(matcher, "%{ }#"); + matcher.dispose(); } }
\ No newline at end of file diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java index 47928a7..f3c806a 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java @@ -31,7 +31,7 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar private int fAnchor= -1; private final CharPairs fPairs; private final String fPartitioning; - private final boolean fCaretInsideMatchedPair; + private final boolean fCaretEitherSideOfBracket; /** * Creates a new character pair matcher that matches the specified characters within the @@ -64,18 +64,18 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar * * @param chars a list of characters * @param partitioning the partitioning to match within - * @param caretInsideMatchedPair controls the matching behavior. When <code>true</code>, the - * matching start peer will be found when the caret is placed before the end - * character. When <code>false</code>, the matching start peer will be found when the - * caret is placed after the end character. + * @param caretEitherSideOfBracket controls the matching behavior. When <code>true</code>, the + * matching peer will be found when the caret is placed either before or after a + * character. When <code>false</code>, the matching peer will be found only when the + * caret is placed after a character. * @since 3.8 */ - public DefaultCharacterPairMatcher(char[] chars, String partitioning, boolean caretInsideMatchedPair) { + public DefaultCharacterPairMatcher(char[] chars, String partitioning, boolean caretEitherSideOfBracket) { Assert.isLegal(chars.length % 2 == 0); Assert.isNotNull(partitioning); fPairs= new CharPairs(chars); fPartitioning= partitioning; - fCaretInsideMatchedPair= caretInsideMatchedPair; + fCaretEitherSideOfBracket= caretEitherSideOfBracket; } /** @@ -113,11 +113,19 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar if (document == null || offset < 0 || offset > document.getLength() || Math.abs(length) > 1) return null; - int sourceCaretOffset= offset + length; - int adjustment= getOffsetAdjustment(document, sourceCaretOffset, length); - sourceCaretOffset+= adjustment; - - return match(document, sourceCaretOffset); + try { + int sourceCaretOffset= offset + length; + if (Math.abs(length) == 1) { + char ch= length > 0 ? document.getChar(offset) : document.getChar(sourceCaretOffset); + if (!fPairs.contains(ch)) + return null; + } + int adjustment= getOffsetAdjustment(document, sourceCaretOffset, length); + sourceCaretOffset+= adjustment; + return match(document, sourceCaretOffset); + } catch (BadLocationException e) { + return null; + } } /** @@ -195,7 +203,7 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar start= currentEndOffset; end= previousEndOffset; } - for (int i= start; i < end; i++) { + for (int i= Math.max(start - 1, 0); i <= end; i++) { if (isMatchedChar(document.getChar(i))) { return true; } @@ -208,7 +216,7 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar start= currentStartOffset; end= previousStartOffset; } - for (int i= start; i < end; i++) { + for (int i= Math.max(start - 1, 0); i <= end; i++) { if (isMatchedChar(document.getChar(i))) { return true; } @@ -230,7 +238,7 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar * @since 3.8 */ private int getOffsetAdjustment(IDocument document, int offset, int length) { - if (length == 0 || Math.abs(length) > 1) + if (length == 0 || Math.abs(length) > 1 || offset >= document.getLength()) return 0; try { if (length < 0) { @@ -238,7 +246,7 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar return 1; } } else { - if (fCaretInsideMatchedPair && fPairs.isEndCharacter(document.getChar(offset - 1))) { + if (fCaretEitherSideOfBracket && fPairs.isEndCharacter(document.getChar(offset - 1))) { return -1; } } @@ -252,11 +260,21 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar * Performs the actual work of matching for #match(IDocument, int). */ private IRegion performMatch(IDocument doc, int caretOffset) throws BadLocationException { - final char prevChar= doc.getChar(Math.max(caretOffset - 1, 0)); + char prevChar= (caretOffset - 1 >= 0) ? doc.getChar(caretOffset - 1) : Character.MIN_VALUE; boolean isForward; final char ch; - if (fCaretInsideMatchedPair) { - final char currChar= doc.getChar(caretOffset); + if (fCaretEitherSideOfBracket) { + char currChar= (caretOffset != doc.getLength()) ? doc.getChar(caretOffset) : Character.MIN_VALUE; + if (fPairs.isEndCharacter(prevChar) && !fPairs.isEndCharacter(currChar)) { //https://bugs.eclipse.org/bugs/show_bug.cgi?id=372516 + caretOffset--; + currChar= prevChar; + prevChar= doc.getChar(Math.max(caretOffset - 1, 0)); + } else if (fPairs.isStartCharacter(currChar) && !fPairs.contains(prevChar)) { + caretOffset++; + prevChar= currChar; + currChar= doc.getChar(caretOffset); + } + isForward= fPairs.contains(prevChar) && fPairs.isStartCharacter(prevChar); boolean isBackward= fPairs.contains(currChar) && !fPairs.isStartCharacter(currChar); if (!isForward && !isBackward) { @@ -271,9 +289,9 @@ public class DefaultCharacterPairMatcher implements ICharacterPairMatcher, IChar } fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT; - final int searchStartPosition= isForward ? caretOffset : (fCaretInsideMatchedPair ? caretOffset - 1 : caretOffset - 2); - final int adjustedOffset= isForward ? caretOffset - 1 : (fCaretInsideMatchedPair ? caretOffset + 1 : caretOffset); - final String partition= TextUtilities.getContentType(doc, fPartitioning, ((!isForward && fCaretInsideMatchedPair) ? caretOffset : caretOffset - 1), false); + final int searchStartPosition= isForward ? caretOffset : (fCaretEitherSideOfBracket ? caretOffset - 1 : caretOffset - 2); + final int adjustedOffset= isForward ? caretOffset - 1 : (fCaretEitherSideOfBracket ? caretOffset + 1 : caretOffset); + final String partition= TextUtilities.getContentType(doc, fPartitioning, ((!isForward && fCaretEitherSideOfBracket) ? caretOffset : Math.max(caretOffset - 1, 0)), false); final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition); int endOffset= findMatchingPeer(partDoc, ch, fPairs.getMatching(ch), isForward, isForward ? doc.getLength() : -1, searchStartPosition); |

