From cd120d83e86d21bba8d70e7cc0cdcc66ea8da1ec Mon Sep 17 00:00:00 2001 From: danthe1st Date: Fri, 24 Jan 2025 23:19:41 +0100 Subject: [PATCH] add custom folding regions --- .../jdt/text/tests/JdtTextTestSuite.java | 6 +- .../CustomFoldingRegionNewFoldingTest.java | 215 ++++++++++ .../folding/CustomFoldingRegionTest.java | 387 ++++++++++++++++++ .../jdt/text/tests/folding/FoldingTest.java | 4 +- .../text/tests/folding/FoldingTestSuite.java | 26 ++ .../text/tests/folding/FoldingTestUtils.java | 2 + .../DefaultJavaFoldingPreferenceBlock.java | 99 +++-- .../ui/text/folding/FoldingMessages.java | 7 +- .../text/folding/FoldingMessages.properties | 8 +- .../eclipse/jdt/ui/PreferenceConstants.java | 33 ++ .../DefaultJavaFoldingStructureProvider.java | 292 ++++++++++++- 11 files changed, 1026 insertions(+), 53 deletions(-) create mode 100644 org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionNewFoldingTest.java create mode 100644 org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionTest.java create mode 100644 org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestSuite.java diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java index ae6b859828e..c59e7208361 100644 --- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2024 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -20,7 +20,7 @@ import org.eclipse.jdt.text.tests.codemining.CodeMiningTriggerTest; import org.eclipse.jdt.text.tests.codemining.ParameterNamesCodeMiningTest; import org.eclipse.jdt.text.tests.contentassist.ContentAssistTestSuite; -import org.eclipse.jdt.text.tests.folding.FoldingTest; +import org.eclipse.jdt.text.tests.folding.FoldingTestSuite; import org.eclipse.jdt.text.tests.semantictokens.SemanticTokensProviderTest; import org.eclipse.jdt.text.tests.spelling.SpellCheckEngineTestCase; import org.eclipse.jdt.text.tests.templates.TemplatesTestSuite; @@ -71,7 +71,7 @@ JavaElementPrefixPatternMatcherTest.class, CodeMiningTriggerTest.class, ParameterNamesCodeMiningTest.class, - FoldingTest.class, + FoldingTestSuite.class, }) public class JdtTextTestSuite { } \ No newline at end of file diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionNewFoldingTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionNewFoldingTest.java new file mode 100644 index 00000000000..bde22b17206 --- /dev/null +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionNewFoldingTest.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2025 Daniel Schmid 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 + * + * Contributors: + * Daniel Schmid - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.text.tests.folding; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jface.text.IRegion; + +import org.eclipse.jdt.ui.PreferenceConstants; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + +public class CustomFoldingRegionNewFoldingTest extends CustomFoldingRegionTest { + + @Before + @Override + public void setUp() throws CoreException { + super.setUp(); + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setValue(PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED, true); + } + + + @After + @Override + public void tearDown() throws CoreException { + super.tearDown(); + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setToDefault(PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED); + } + + @Test + @Override + public void testCustomFoldingRegionsInMethod() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a(){ + // region + + // endregion + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 5); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 5); + } + + @Test + @Override + public void testCustomFoldingRegionsMultipleLevels() throws Exception { + String str= """ + package org.example.test; + // region outside class + public class Test { + // region outside method + void a(){ + // endregion should be ignored + // region inside method + System.out.println("Hello World"); + // endregion inside method + } + // endregion outside method + } + // endregion outside class + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(4, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 1, 12);//outside class + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 10);//outside method + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 8);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 8);//inside method + } + + @Test + @Override + public void testCustomFoldingRegionsUsingSpecialCommentTypes() throws Exception { + String str= """ + package org.example.test; + + public class Test { + void a(){ + /* region multiline + */ + /** region javadoc */ + /** endregion javadoc */ + /* endregion multiline + */ + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(5, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 9);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 5);// multiline (comment) + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 9);// multiline (folding region) + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 7);// javadoc + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 8, 9);// multiline (last comment) + } + + @Test + @Override + public void testCustomRegionsWithLocalClass() throws Exception { + String str= """ + package org.example.test; + + public class Test { + void a(){ + // region + int i; + + // endregion + class Inner{ + + } + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 10);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 7);//region + } + + @Test + @Override + public void testCustomRegionsAroundFieldAndMethod() throws Exception { + String str= """ + package org.example.test; + + public class Test { + // region + int a; + + void b(){ + + } + // endregion + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 9);//region + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 7);//void b() + } + + @Test + @Override + public void testCommentsInEmptyBlocks() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a(){ + {/* region 1*/} + System.out.println("Hello World"); + {/* endregion 1*/} + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 5);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 5);//region 1 + } + + @Test + public void testNotFoldedWithinDifferentControlFlowStatements() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a() { + // region + for (int i = 0; i < 10; i++) { + // endregion + // region + } + boolean b=false; + // region + while (b) { + // endregion + } + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(3, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 12);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 6);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 10, 11);//void a() + } + +} diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionTest.java new file mode 100644 index 00000000000..b5f219609de --- /dev/null +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/CustomFoldingRegionTest.java @@ -0,0 +1,387 @@ +/******************************************************************************* + * Copyright (c) 2025 Daniel Schmid 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 + * + * Contributors: + * Daniel Schmid - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.text.tests.folding; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jface.text.IRegion; + +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; + +import org.eclipse.jdt.ui.PreferenceConstants; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + +public class CustomFoldingRegionTest { + @Rule + public ProjectTestSetup projectSetup= new ProjectTestSetup(); + + private IJavaProject fJProject1; + + private IPackageFragmentRoot fSourceFolder; + + protected IPackageFragment fPackageFragment; + + @Before + public void setUp() throws CoreException { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fPackageFragment= fSourceFolder.createPackageFragment("org.example.test", false, null); + } + + + @After + public void tearDown() throws CoreException { + JavaProjectHelper.delete(fJProject1); + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setToDefault(PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_START); + store.setToDefault(PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_END); + } + + @Test + public void testNoCustomFoldingRegions() throws Exception { + String str= """ + package org.example.test; + public class Test { + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(0, projectionRanges.size()); + } + + @Test + public void testCustomFoldingRegionInsideAndOutsideClass() throws Exception { + String str= """ + package org.example.test; + // region + // something else + // endregion + public class Test { + // region + // something else + // endregion + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 1, 3); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 5, 7); + } + + @Test + public void testNestedCustomRegions() throws Exception { + String str= """ + package org.example.test; + + public class Test { + // region outer + // region inner + + // endregion outer + // endregion inner + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 7);//outer + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 6);//inner + } + + @Test + public void testNoCustomFoldingRegionsInMethod() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a(){ + + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(1, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 3); + } + + @Test + public void testCustomFoldingRegionsInMethod() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a(){ + // region + + // endregion + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 6); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 5); + } + + @Test + public void testNoCustomFoldingRegionsSingleImport() throws Exception { + String str= """ + package org.example.test; + + import java.util.List; + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(0, projectionRanges.size()); + } + + @Test + public void testCustomFoldingRegionAroundSingleImport() throws Exception { + String str= """ + package org.example.test; + + // region imports + import java.util.List; + // endregion + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(1, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 4); + } + + @Test + public void testCustomFoldingRegionAroundClasses() throws Exception { + String str= """ + package org.example.test; + + class A { + + } + + // region + + class B { + + } + + class C { + + } + // endregion + + class D { + + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(1, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 15); + } + + @Test + public void testCustomFoldingRegionsMultipleLevels() throws Exception { + String str= """ + package org.example.test; + // region outside class + public class Test { + // endregion should be ignored + // region outside method + void a(){ + // endregion should be ignored + // region inside method + System.out.println("Hello World"); + // endregion inside method + } + // endregion outside method + } + // endregion outside class + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(4, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 1, 13);//outside class + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 11);//outside method + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 5, 10);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 7, 9);//inside method + } + + @Test + public void testCustomFoldingRegionsNotEndingTooEarly() throws Exception { + String str= """ + package org.example.test; + + public class Test { + void a(){ + // region inside method + } + // endregion outside method + } + // endregion outside class + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(1, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 4);//void a() + } + + @Test + public void testCustomFoldingRegionsUsingSpecialCommentTypes() throws Exception { + String str= """ + package org.example.test; + + public class Test { + void a(){ + /* region multiline + */ + /** region javadoc */ + /** endregion javadoc */ + /* endregion multiline + */ + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(3, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 10);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 9);// multiline + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 7);// javadoc + } + + @Test + public void testCustomRegionsWithLocalClass() throws Exception { + String str= """ + package org.example.test; + + public class Test { + void a(){ + // region + int i; + + // endregion + class Inner{ + + } + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(3, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 10);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 7);//region + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 8, 10);//class Inner + } + + @Test + public void testNoCustomRegionAtDifferentLevelsWithOtherClass() throws Exception { + String str= """ + package org.example.test; + + public class Test{ + // region outside + public class A { + public void helloWorld() { + + } + // endregion inside + } + + public class B { + + + } + + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(3, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 4, 8);//class A + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 5, 6);//void helloWorld() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 11, 13);//class B + } + + @Test + public void testCustomRegionsAroundFieldAndMethod() throws Exception { + String str= """ + package org.example.test; + + public class Test { + // region + int a; + + void b(){ + + } + // endregion + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 9);//region + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 6, 8);//void b() + } + + @Test + public void testDifferentConfiguration() throws Exception { + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setValue(PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_START, "#regstart"); + store.setValue(PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_END, "#regend"); + + + String str= """ + package org.example.test; + public class Test { + // region should be ignored + // #regstart this is the region + // #regend should end here + // endregion should be ignored + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(1, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 4); + } + + @Test + public void testCommentsInEmptyBlocks() throws Exception { + String str= """ + package org.example.test; + public class Test { + void a(){ + {/* region 1*/} + System.out.println("Hello World"); + {/* endregion 1*/} + } + } + """; + List projectionRanges= getProjectionRangesOfFile(str); + assertEquals(2, projectionRanges.size()); + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 2, 6);//void a() + FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(projectionRanges, str, 3, 5);//region 1 + } + + protected List getProjectionRangesOfFile(String str) throws Exception { + return FoldingTestUtils.getProjectionRangesOfFile(fPackageFragment, "Test.java", str); + } + +} diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTest.java index 47469488f72..ac82f5ce827 100644 --- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTest.java +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTest.java @@ -57,11 +57,13 @@ public void setUp() throws CoreException { packageFragment= sourceFolder.createPackageFragment("org.example.test", false, null); IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); store.setValue(PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED, true); - } + } @After public void tearDown() throws CoreException { JavaProjectHelper.delete(jProject); + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setToDefault(PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED); } @Test diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestSuite.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestSuite.java new file mode 100644 index 00000000000..8fb66db2334 --- /dev/null +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestSuite.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2025 Daniel Schmid 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 + * + * Contributors: + * Daniel Schmid - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.text.tests.folding; + +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasses({ + FoldingTest.class, + CustomFoldingRegionTest.class, + CustomFoldingRegionNewFoldingTest.class, +}) +public class FoldingTestSuite { +} diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestUtils.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestUtils.java index 8e5f5f33697..bad1df8b9d3 100644 --- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestUtils.java +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/folding/FoldingTestUtils.java @@ -101,4 +101,6 @@ private static int findLineStartIndex(String input, int lineNumber) { private static int findNextLineStart(String input, int currentInputIndex) { return input.indexOf('\n', currentInputIndex + 1); } + + } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java index 43510a919e0..10325997bb6 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,10 +15,10 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; @@ -28,6 +28,7 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; import org.eclipse.jface.preference.IPreferenceStore; @@ -60,6 +61,12 @@ public void widgetSelected(SelectionEvent e) { fOverlayStore.setValue(fCheckBoxes.get(button), button.getSelection()); } }; + private Map fStringInputs= new HashMap<>(); + private ModifyListener fModifyListener = e -> { + Text text = (Text)e.widget; + fOverlayStore.setValue(fStringInputs.get(text), text.getText()); + }; + public DefaultJavaFoldingPreferenceBlock() { @@ -77,6 +84,9 @@ private OverlayKey[] createKeys() { overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_IMPORTS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_HEADERS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGIONS)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_START)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_END)); return overlayKeys.toArray(new OverlayKey[overlayKeys.size()]); } @@ -88,32 +98,29 @@ public Control createControl(Composite composite) { fOverlayStore.load(); fOverlayStore.start(); - composite.setLayout(new GridLayout(1, false)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - Composite inner= new Composite(composite, SWT.NONE); GridLayout layout= new GridLayout(1, false); - layout.verticalSpacing= 10; + layout.verticalSpacing= 3; layout.marginWidth= 0; - layout.marginHeight= 0; - inner.setLayout(layout); - inner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - Group initialFoldGroup = new Group(inner, SWT.NONE); - GridLayout initialFoldLayout = new GridLayout(1, false); - initialFoldLayout.marginWidth = 10; - initialFoldLayout.marginHeight = 10; - initialFoldGroup.setLayout(initialFoldLayout); - initialFoldGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - initialFoldGroup.setText(FoldingMessages.DefaultJavaFoldingPreferenceBlock_title); - - addCheckBox(initialFoldGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_comments, PreferenceConstants.EDITOR_FOLDING_JAVADOC, 0); - addCheckBox(initialFoldGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_headers, PreferenceConstants.EDITOR_FOLDING_HEADERS, 0); - addCheckBox(initialFoldGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_innerTypes, PreferenceConstants.EDITOR_FOLDING_INNERTYPES, 0); - addCheckBox(initialFoldGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_methods, PreferenceConstants.EDITOR_FOLDING_METHODS, 0); - addCheckBox(initialFoldGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_imports, PreferenceConstants.EDITOR_FOLDING_IMPORTS, 0); - - Group extendedFoldingGroup= new Group(inner, SWT.NONE); +// layout.marginHeight= 0; + composite.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + + Composite outer= new Composite(composite, SWT.NONE); + outer.setLayout(layout); + outer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Group initialFoldingGroup= new Group(outer, SWT.NONE); + initialFoldingGroup.setLayout(layout); + initialFoldingGroup.setText(FoldingMessages.DefaultJavaFoldingPreferenceBlock_title); + initialFoldingGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_comments, PreferenceConstants.EDITOR_FOLDING_JAVADOC, 0); + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_headers, PreferenceConstants.EDITOR_FOLDING_HEADERS, 0); + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_innerTypes, PreferenceConstants.EDITOR_FOLDING_INNERTYPES, 0); + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_methods, PreferenceConstants.EDITOR_FOLDING_METHODS, 0); + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_imports, PreferenceConstants.EDITOR_FOLDING_IMPORTS, 0); + addCheckBox(initialFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_customRegions, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGIONS, 0); + + Group extendedFoldingGroup= new Group(outer, SWT.NONE); GridLayout extendedFoldingLayout= new GridLayout(1, false); extendedFoldingLayout.marginWidth= 10; extendedFoldingLayout.marginHeight= 10; @@ -126,7 +133,17 @@ public Control createControl(Composite composite) { label.setLayoutData(gd); label.setText(FoldingMessages.DefaultJavaFoldingPreferenceBlock_Warning_New_Feature); addCheckBox(extendedFoldingGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_New, PreferenceConstants.EDITOR_NEW_FOLDING_ENABLED, 0); - return inner; + + Group customRegionGroup= new Group(outer, SWT.NONE); + customRegionGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout customRegionLayout= new GridLayout(2, false); + customRegionGroup.setLayout(customRegionLayout); + customRegionGroup.setText(FoldingMessages.DefaultJavaFoldingPreferenceBlock_custom_region_title); + addStringInput(customRegionGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_CustomRegionStart, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_START); + addStringInput(customRegionGroup, FoldingMessages.DefaultJavaFoldingPreferenceBlock_CustomRegionEnd, PreferenceConstants.EDITOR_FOLDING_CUSTOM_REGION_END); + + return outer; } private Button addCheckBox(Composite parent, String label, String key, int indentation) { @@ -145,13 +162,29 @@ private Button addCheckBox(Composite parent, String label, String key, int inden return checkBox; } + private void addStringInput(Composite parent, String label, String key) { + Label labelElement = new Label(parent, SWT.LEFT); + labelElement.setText(label); + GridData labelGridData= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + labelGridData.horizontalSpan= 1; + labelGridData.grabExcessVerticalSpace= false; + labelElement.setLayoutData(labelGridData); + + Text textInput = new Text(parent, SWT.SINGLE | SWT.BORDER); + textInput.setText(label); + textInput.addModifyListener(fModifyListener); + + GridData textGridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false); + textGridData.horizontalSpan= 1; + textGridData.grabExcessVerticalSpace= true; + textInput.setLayoutData(textGridData); + + fStringInputs.put(textInput, key); + } + private void initializeFields() { - Iterator