Bug 577727: Fix select line start
Change-Id: I16e74319b9e3d61b020ff260661836795300c8e1
Signed-off-by: Stephan Wahlbrink <sw@wahlbrink.eu>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/188716
Reviewed-by: Mickael Istria <mistria@redhat.com>
Tested-by: Platform Bot <platform-bot@eclipse.org>
diff --git a/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF b/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF
index 665d367..47dd5a5 100644
--- a/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.ui.editors.tests;singleton:=true
-Bundle-Version: 3.12.300.qualifier
+Bundle-Version: 3.12.400.qualifier
Bundle-Vendor: %Plugin.providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.ui.editors.tests
diff --git a/org.eclipse.ui.editors.tests/pom.xml b/org.eclipse.ui.editors.tests/pom.xml
index fee685a..dbbbfe8 100644
--- a/org.eclipse.ui.editors.tests/pom.xml
+++ b/org.eclipse.ui.editors.tests/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.ui</groupId>
<artifactId>org.eclipse.ui.editors.tests</artifactId>
- <version>3.12.300-SNAPSHOT</version>
+ <version>3.12.400-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<testSuite>${project.artifactId}</testSuite>
diff --git a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextMultiCaretNavigationTest.java b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextMultiCaretNavigationTest.java
new file mode 100644
index 0000000..eee388d
--- /dev/null
+++ b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextMultiCaretNavigationTest.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+package org.eclipse.ui.editors.tests;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.core.filesystem.EFS;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IMultiTextSelection;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.MultiTextSelection;
+import org.eclipse.jface.text.Region;
+
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+/*
+ * Note: this test would better fit in the org.eclipse.ui.workbench.texteditor bundle, but initializing
+ * and editor from this bundle is quite tricky without the IDE and EFS utils.
+ */
+public class TextMultiCaretNavigationTest {
+
+ private static File file;
+ private static AbstractTextEditor editor;
+ private static StyledText widget;
+
+ @Before
+ public void setUpBeforeClass() throws IOException, PartInitException, CoreException {
+ file = File.createTempFile(TextMultiCaretNavigationTest.class.getName(), ".txt");
+ Files.write(file.toPath(), " abc\n 1234\nxyz".getBytes());
+ editor = (AbstractTextEditor)IDE.openEditorOnFileStore(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), EFS.getStore(file.toURI()));
+ widget = (StyledText) editor.getAdapter(Control.class);
+ }
+
+ @After
+ public void tearDown() {
+ editor.dispose();
+ file.delete();
+ }
+
+
+ @Test
+ public void testShiftHome() {
+ IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ editor.getSelectionProvider().setSelection(new MultiTextSelection(document,
+ new IRegion[] { new Region(5, 0), new Region(14, 0), new Region(18, 0), }));
+ assertEquals(5, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ IMultiTextSelection selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(2, 3), new Region(10, 4), new Region(15, 3) },
+ selection.getRegions());
+ assertEquals(2, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(0, 5), new Region(6, 8), new Region(15, 3) },
+ selection.getRegions());
+ assertEquals(0, widget.getCaretOffset());
+ }
+
+ @Test
+ public void testShiftEnd() {
+ IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ editor.getSelectionProvider().setSelection(new MultiTextSelection(document,
+ new IRegion[] { new Region(0, 0), new Region(6, 0), new Region(15, 0), }));
+ assertEquals(0, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_END).run();
+ IMultiTextSelection selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(0, 5), new Region(6, 8), new Region(15, 3) },
+ selection.getRegions());
+ assertEquals(5, widget.getCaretOffset());
+ }
+
+ @Test
+ public void testShiftEndHomeHome() {
+ IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ editor.getSelectionProvider().setSelection(new MultiTextSelection(document,
+ new IRegion[] { new Region(0, 0), new Region(6, 0), new Region(15, 0), }));
+ assertEquals(0, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_END).run();
+ IMultiTextSelection selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(0, 5), new Region(6, 8), new Region(15, 3) },
+ selection.getRegions());
+ assertEquals(5, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(0, 2), new Region(6, 4), new Region(15, 0) },
+ selection.getRegions());
+ assertEquals(2, widget.getCaretOffset()); // Bug 577727
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ selection = (IMultiTextSelection) editor.getSelectionProvider().getSelection();
+ assertArrayEquals(new IRegion[] { new Region(0, 0), new Region(6, 0), new Region(15, 0) },
+ selection.getRegions());
+ assertEquals(0, widget.getCaretOffset());
+ }
+
+}
diff --git a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextNavigationTest.java b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextNavigationTest.java
index 9449786..2ae93a4 100644
--- a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextNavigationTest.java
+++ b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/TextNavigationTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021 Red Hat Inc.
+ * Copyright (c) 2021 Red Hat Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -116,6 +116,30 @@
}
@Test
+ public void testShiftEndHomeHome() {
+ editor.getSelectionProvider().setSelection(new TextSelection(0, 0));
+ assertEquals(0, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_END).run();
+ ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection();
+ assertEquals(0, selection.getOffset());
+ assertEquals(5, selection.getLength());
+ assertEquals(5, widget.getCaretOffset());
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ selection = (ITextSelection) editor.getSelectionProvider().getSelection();
+ assertEquals(0, selection.getOffset());
+ assertEquals(2, selection.getLength());
+ assertEquals(2, widget.getCaretOffset()); // Bug 577727
+
+ editor.getAction(ITextEditorActionDefinitionIds.SELECT_LINE_START).run();
+ selection = (ITextSelection) editor.getSelectionProvider().getSelection();
+ assertEquals(0, selection.getOffset());
+ assertEquals(0, selection.getLength());
+ assertEquals(0, widget.getCaretOffset());
+ }
+
+ @Test
public void testEndHomeRevealCaret() {
editor.getSelectionProvider().setSelection(new TextSelection(0, 0));
IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
index 29fc5c4..6ae6eb0 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
@@ -1352,9 +1352,6 @@
line = st.getText(lineOffset, end);
}
- // Remember current selection
- Point oldSelection = new Point(offset, offset + length);
-
// The new caret position
int newCaretOffset = -1;
@@ -1367,16 +1364,12 @@
newCaretOffset = lineOffset;
}
- newSelection.add(new Point(
- fDoSelect
- ? (caretAtBeginningOfSelection ? Math.max(oldSelection.x, oldSelection.y)
- : Math.min(oldSelection.x, oldSelection.y))
- : newCaretOffset,
- newCaretOffset));
+ newSelection.add(
+ new Point(fDoSelect ? (caretAtBeginningOfSelection ? offset + length : offset) : newCaretOffset,
+ newCaretOffset));
}
st.setSelectionRanges(newSelection.stream().flatMapToInt(
- p -> IntStream.of(Math.max(p.x, p.y), -Math.abs(p.x - p.y))) // negative length to put cursor at
- // beginning of selection
+ p -> IntStream.of(p.x, p.y - p.x))
.toArray());
if (newSelection.size() == 1) {
st.showSelection();