From d929e361396ca5bddddf1aedf4fdabc179082fce Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Thu, 7 Nov 2019 20:28:38 +0100 Subject: Bug 552811 - [TextViewer] shift left broken for mixed lines if empty prefix is allowed Empty strings are treated differently by MultiStringMatcher and TextUtilities.indexOf() and needs to be handled specially now. Fixup for c89b823822e2d73ba4996ad419475db34c916ed5. Change-Id: Ifdb5c495f5fc99d33da6d879f436a37063b93430 --- .../eclipse/jface/text/tests/TextViewerTest.java | 49 ++++++++++++++++++++++ .../src/org/eclipse/jface/text/TextViewer.java | 18 ++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java index 2ee51f543..2bf06c627 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java @@ -44,7 +44,10 @@ import org.eclipse.jface.util.Util; import org.eclipse.jface.text.BlockTextSelection; import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentAdapter; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextViewer; @@ -318,4 +321,50 @@ public class TextViewerTest { b.append("end"); return b.toString(); } + + @Test + public void testShiftLeft() { + Shell shell= new Shell(); + try { + TextViewer textViewer= new TextViewer(shell, SWT.NONE); + { + // Normal case, both lines match prefix + Document document= new Document("//line1\n//line2"); + textViewer.setDocumentPartitioning(IDocumentExtension3.DEFAULT_PARTITIONING); + textViewer.setDocument(document); + textViewer.setDefaultPrefixes(new String[] { "//" }, IDocument.DEFAULT_CONTENT_TYPE); + + textViewer.doOperation(ITextOperationTarget.SELECT_ALL); + textViewer.doOperation(ITextOperationTarget.STRIP_PREFIX); + + assertEquals("line1\nline2", textViewer.getDocument().get()); + } + { + // Don't shift anything, as 2nd line does not match any prefix + Document document= new Document("//line1\nline2"); + textViewer.setDocumentPartitioning(IDocumentExtension3.DEFAULT_PARTITIONING); + textViewer.setDocument(document); + textViewer.setDefaultPrefixes(new String[] { "//" }, IDocument.DEFAULT_CONTENT_TYPE); + + textViewer.doOperation(ITextOperationTarget.SELECT_ALL); + textViewer.doOperation(ITextOperationTarget.STRIP_PREFIX); + + assertEquals("//line1\nline2", textViewer.getDocument().get()); + } + { + // Shift line1, since line2 matches the allowed empty prefix + Document document= new Document("//line1\nline2"); + textViewer.setDocumentPartitioning(IDocumentExtension3.DEFAULT_PARTITIONING); + textViewer.setDocument(document); + textViewer.setDefaultPrefixes(new String[] { "//", "" }, IDocument.DEFAULT_CONTENT_TYPE); + + textViewer.doOperation(ITextOperationTarget.SELECT_ALL); + textViewer.doOperation(ITextOperationTarget.STRIP_PREFIX); + + assertEquals("line1\nline2", textViewer.getDocument().get()); + } + } finally { + shell.dispose(); + } + } } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java index 72e3df7b2..099931c48 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java @@ -4326,6 +4326,8 @@ public class TextViewer extends Viewer implements try { IRegion[] occurrences= new IRegion[endLine - startLine + 1]; + + boolean allowEmptyPrefix= Arrays.stream(prefixes).anyMatch(String::isEmpty); MultiStringMatcher prefixMatcher= MultiStringMatcher.create(prefixes); // find all the first occurrences of prefix in the given lines @@ -4335,20 +4337,28 @@ public class TextViewer extends Viewer implements String text= d.get(line.getOffset(), line.getLength()); int index= -1; + int matchOffset= -1; + String matchText= ""; //$NON-NLS-1$ Match m= prefixMatcher.indexOf(text, 0); if (m != null) { + matchOffset= m.getOffset(); + matchText= m.getText(); + } else if (allowEmptyPrefix) { + matchOffset= 0; + } + if (matchOffset > -1) { if (ignoreWhitespace) { - String s= d.get(line.getOffset(), m.getOffset()); + String s= d.get(line.getOffset(), matchOffset); s= s.trim(); if (s.isEmpty()) - index= line.getOffset() + m.getOffset(); - } else if (m.getOffset() == 0) + index= line.getOffset() + matchOffset; + } else if (matchOffset == 0) index= line.getOffset(); } if (index > -1) { // remember where prefix is in line, so that it can be removed - int length= m.getText().length(); + int length= matchText.length(); if (length == 0 && !ignoreWhitespace && line.getLength() > 0) { // found a non-empty line which cannot be shifted return; -- cgit v1.2.1