diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..e69de29 diff --git a/com.vogella.adapters/.settings/org.eclipse.core.resources.prefs b/com.vogella.adapters/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.adapters/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.adapters/.settings/org.eclipse.m2e.core.prefs b/com.vogella.adapters/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.adapters/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.contribute.parts/.settings/org.eclipse.core.resources.prefs b/com.vogella.contribute.parts/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.contribute.parts/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.contribute.parts/.settings/org.eclipse.m2e.core.prefs b/com.vogella.contribute.parts/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.contribute.parts/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.eclipse.css/.settings/org.eclipse.core.resources.prefs b/com.vogella.eclipse.css/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.eclipse.css/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.eclipse.css/.settings/org.eclipse.m2e.core.prefs b/com.vogella.eclipse.css/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.eclipse.css/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.ide.editor.asciidoc.tests/.classpath b/com.vogella.ide.editor.asciidoc.tests/.classpath deleted file mode 100644 index 2e721e8..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/.classpath +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/.project b/com.vogella.ide.editor.asciidoc.tests/.project deleted file mode 100644 index d4ccfc8..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - com.vogella.ide.editor.asciidoc.tests - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/.settings/org.eclipse.jdt.core.prefs b/com.vogella.ide.editor.asciidoc.tests/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 84cddbe..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 -org.eclipse.jdt.core.compiler.compliance=21 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=21 \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/META-INF/MANIFEST.MF b/com.vogella.ide.editor.asciidoc.tests/META-INF/MANIFEST.MF deleted file mode 100644 index e3bd2cb..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/META-INF/MANIFEST.MF +++ /dev/null @@ -1,10 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Tests for AsciiDoc Editor -Bundle-SymbolicName: com.vogella.ide.editor.asciidoc.tests -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: VOGELLA -Fragment-Host: com.vogella.ide.editor.asciidoc;bundle-version="1.0.0" -Require-Bundle: junit-jupiter-api;bundle-version="5.11.0" -Automatic-Module-Name: com.vogella.ide.editor.asciidoc.tests -Bundle-RequiredExecutionEnvironment: JavaSE-21 \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/build.properties b/com.vogella.ide.editor.asciidoc.tests/build.properties deleted file mode 100644 index 5b359b5..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/pom.xml b/com.vogella.ide.editor.asciidoc.tests/pom.xml deleted file mode 100644 index 03e40aa..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - 4.0.0 - - - com.vogella.tycho - releng - 1.0.0-SNAPSHOT - - - com.vogella.ide.editor - com.vogella.ide.editor.asciidoc.tests - 1.0.0-SNAPSHOT - eclipse-test-plugin - - - - - org.eclipse.tycho - tycho-surefire-plugin - - false - false - - - - - org.apache.felix.scr - 2 - true - - - com.vogella.ide.editor.asciidoc - 3 - true - - - - - - - - \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocContentAssistProcessorTests.java b/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocContentAssistProcessorTests.java deleted file mode 100644 index a2d8b92..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocContentAssistProcessorTests.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.vogella.ide.editor.asciidoc.tests; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import com.vogella.ide.editor.asciidoc.AsciidocContentAssistProcessor; - -/** - * Test class for the AsciidocContentAssistProcessor. - * - * This test class focuses on testing basic initialization and behavior of the processor. - * Full integration tests that require Eclipse workbench context would need to be run - * in an Eclipse environment with actual editors. - */ -class AsciidocContentAssistProcessorTests { - - @Test - @DisplayName("AsciidocContentAssistProcessor can be initialized") - void testCanBeInitialized() { - AsciidocContentAssistProcessor processor = new AsciidocContentAssistProcessor(); - assertNotNull(processor, "AsciidocContentAssistProcessor should be successfully instantiated"); - } - - @Test - @DisplayName("Processor has predefined AsciiDoc proposals") - void testHasPredefinedProposals() { - assertNotNull(AsciidocContentAssistProcessor.PROPOSALS, - "PROPOSALS list should not be null"); - assertFalse(AsciidocContentAssistProcessor.PROPOSALS.isEmpty(), - "PROPOSALS list should contain at least one element"); - - // Check for expected proposal keywords - boolean hasImageProposal = AsciidocContentAssistProcessor.PROPOSALS.stream() - .anyMatch(p -> p.contains("image::")); - assertTrue(hasImageProposal, "Should have image:: proposal"); - - boolean hasIncludeProposal = AsciidocContentAssistProcessor.PROPOSALS.stream() - .anyMatch(p -> p.contains("include::")); - assertTrue(hasIncludeProposal, "Should have include:: proposal"); - } - - @Test - @DisplayName("Processor returns empty auto-activation characters") - void testAutoActivationCharacters() { - AsciidocContentAssistProcessor processor = new AsciidocContentAssistProcessor(); - char[] autoActivationChars = processor.getCompletionProposalAutoActivationCharacters(); - assertNotNull(autoActivationChars, "Auto-activation characters should not be null"); - assertEquals(0, autoActivationChars.length, - "Auto-activation characters array should be empty by default"); - } - - @Test - @DisplayName("Path parsing logic - extracting directory and prefix") - void testPathParsingLogic() { - // Test parsing of various path formats - // These are the expected behaviors based on the implementation: - - // Case 1: "../OSGi/215-" should parse to directory="../OSGi/" and prefix="215-" - String path1 = "../OSGi/215-"; - int lastSlash1 = Math.max(path1.lastIndexOf("/"), path1.lastIndexOf("\\")); - String dir1 = path1.substring(0, lastSlash1); - String prefix1 = path1.substring(lastSlash1 + 1); - assertEquals("../OSGi", dir1, "Directory should be ../OSGi"); - assertEquals("215-", prefix1, "Prefix should be 215-"); - - // Case 2: "subfolder/test" should parse to directory="subfolder" and prefix="test" - String path2 = "subfolder/test"; - int lastSlash2 = Math.max(path2.lastIndexOf("/"), path2.lastIndexOf("\\")); - String dir2 = path2.substring(0, lastSlash2); - String prefix2 = path2.substring(lastSlash2 + 1); - assertEquals("subfolder", dir2, "Directory should be subfolder"); - assertEquals("test", prefix2, "Prefix should be test"); - - // Case 3: "file.adoc" has no directory separator - String path3 = "file.adoc"; - int lastSlash3 = Math.max(path3.lastIndexOf("/"), path3.lastIndexOf("\\")); - assertTrue(lastSlash3 < 0, "Should not have directory separator"); - - // Case 4: Empty string - String path4 = ""; - int lastSlash4 = Math.max(path4.lastIndexOf("/"), path4.lastIndexOf("\\")); - assertTrue(lastSlash4 < 0, "Empty string should not have directory separator"); - } - - @Test - @DisplayName("Path parsing handles Windows and Unix separators") - void testCrossPlatformSeparators() { - // Test Unix-style path - String unixPath = "folder/subfolder/file"; - int unixSlash = Math.max(unixPath.lastIndexOf("/"), unixPath.lastIndexOf("\\")); - assertEquals(16, unixSlash, "Should find last forward slash at position 16"); - - // Test Windows-style path - String winPath = "folder\\subfolder\\file"; - int winSlash = Math.max(winPath.lastIndexOf("/"), winPath.lastIndexOf("\\")); - assertEquals(16, winSlash, "Should find last backslash at position 16"); - - // Test mixed path (should work with either) - String mixedPath = "folder/subfolder\\file"; - int mixedSlash = Math.max(mixedPath.lastIndexOf("/"), mixedPath.lastIndexOf("\\")); - assertEquals(16, mixedSlash, "Should find last separator (backslash) at position 16"); - } - - @Test - @DisplayName("Path reconstruction maintains original path prefix") - void testPathReconstruction() { - // Test that pathPrefix + filename reconstructs the original path - String originalPath = "../OSGi/215-example.adoc"; - int lastSlash = Math.max(originalPath.lastIndexOf("/"), originalPath.lastIndexOf("\\")); - String pathPrefix = originalPath.substring(0, lastSlash + 1); // Include the separator - String filename = originalPath.substring(lastSlash + 1); - - String reconstructed = pathPrefix + filename; - assertEquals(originalPath, reconstructed, "Reconstructed path should match original"); - assertEquals("../OSGi/", pathPrefix, "Path prefix should include trailing separator"); - assertEquals("215-example.adoc", filename, "Filename should be extracted correctly"); - } -} diff --git a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocMergeViewerCreatorTests.java b/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocMergeViewerCreatorTests.java deleted file mode 100644 index 320ed52..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/AsciidocMergeViewerCreatorTests.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.vogella.ide.editor.asciidoc.tests; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import com.vogella.ide.editor.asciidoc.AsciidocMergeViewerCreator; - -/** - * Test class for the AsciidocMergeViewerCreator. - * - * This test class focuses on testing the basic initialization and structure - * of the AsciidocMergeViewerCreator. Full integration tests that require a - * complete Eclipse workbench context would need to be run in an Eclipse environment. - */ -class AsciidocMergeViewerCreatorTests { - - @Test - @DisplayName("AsciidocMergeViewerCreator can be initialized") - void testCanBeInitialized() { - AsciidocMergeViewerCreator creator = new AsciidocMergeViewerCreator(); - assertNotNull(creator, "AsciidocMergeViewerCreator should be successfully instantiated"); - } - - @Test - @DisplayName("AsciidocMergeViewerCreator implements IViewerCreator") - void testImplementsIViewerCreator() { - AsciidocMergeViewerCreator creator = new AsciidocMergeViewerCreator(); - assertTrue(creator instanceof org.eclipse.compare.IViewerCreator, - "AsciidocMergeViewerCreator should implement IViewerCreator"); - } -} diff --git a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/IncludeHyperlinkDetectorTests.java b/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/IncludeHyperlinkDetectorTests.java deleted file mode 100644 index a96cc8a..0000000 --- a/com.vogella.ide.editor.asciidoc.tests/src/com/vogella/ide/editor/asciidoc/tests/IncludeHyperlinkDetectorTests.java +++ /dev/null @@ -1,403 +0,0 @@ -package com.vogella.ide.editor.asciidoc.tests; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import com.vogella.ide.editor.asciidoc.IncludeHyperlinkDetector; - -/** - * Test class for the IncludeHyperlinkDetector. - * - * This test class focuses on testing the static utility methods and basic initialization - * of the IncludeHyperlinkDetector. More complex integration tests that require a full - * Eclipse workbench context would need to be run in an Eclipse environment. - */ -class IncludeHyperlinkDetectorTests { - - @Test - @DisplayName("IncludeHyperlinkDetector can be initialized") - void testCanBeInitialized() { - IncludeHyperlinkDetector detector = new IncludeHyperlinkDetector(); - assertNotNull(detector, "IncludeHyperlinkDetector should be successfully instantiated"); - } - - @Test - @DisplayName("containsSubfolder method detects subfolders correctly") - void testContainsSubfolder() { - // Test with subfolder path after "../" - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../exercises/exercise1.adoc"), - "Should detect subfolder in '../exercises/exercise1.adoc'"); - - // Test without subfolder after "../" - assertFalse(IncludeHyperlinkDetector.containsSubfolder("../exercise_settings.adoc"), - "Should not detect subfolder in '../exercise_settings.adoc'"); - - // Test with relative path with subfolder after "../" - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../common/header.adoc"), - "Should detect subfolder in '../common/header.adoc'"); - - // Test with multiple subfolders - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../exercises/chapter1/intro.adoc"), - "Should detect subfolder in '../exercises/chapter1/intro.adoc'"); - - // Test with current directory subfolder - this method only handles "../" not "./" - assertFalse(IncludeHyperlinkDetector.containsSubfolder("./subfolder/file.adoc"), - "Method only handles '../' patterns, not './' patterns"); - - // Test with just filename - assertFalse(IncludeHyperlinkDetector.containsSubfolder("file.adoc"), - "Should not detect subfolder in 'file.adoc'"); - } - - @Test - @DisplayName("containsSubfolder handles Windows-style paths") - void testContainsSubfolderWindowsPaths() { - // Test with Windows-style backslashes - assertTrue(IncludeHyperlinkDetector.containsSubfolder("..\\exercises\\exercise1.adoc"), - "Should detect subfolder in Windows-style path '..\\exercises\\exercise1.adoc'"); - - assertFalse(IncludeHyperlinkDetector.containsSubfolder("..\\exercise_settings.adoc"), - "Should not detect subfolder in '..\\exercise_settings.adoc'"); - - // Test mixed separators (Windows/Unix) - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../exercises\\chapter1/intro.adoc"), - "Should detect subfolder with mixed separators '../exercises\\chapter1/intro.adoc'"); - } - - @Test - @DisplayName("containsSubfolder handles edge cases") - void testContainsSubfolderEdgeCases() { - // Empty string - assertFalse(IncludeHyperlinkDetector.containsSubfolder(""), - "Empty string should not contain subfolder"); - - // Just path separators - assertFalse(IncludeHyperlinkDetector.containsSubfolder("/"), - "Single forward slash should not contain subfolder"); - - assertFalse(IncludeHyperlinkDetector.containsSubfolder("\\"), - "Single backslash should not contain subfolder"); - - // Just parent directory - assertFalse(IncludeHyperlinkDetector.containsSubfolder("../"), - "Parent directory with trailing slash should not contain subfolder"); - - // Multiple parent directories but no subfolder - assertFalse(IncludeHyperlinkDetector.containsSubfolder("../../file.adoc"), - "Multiple parent directories without subfolder should not contain subfolder"); - - // Multiple parent directories with subfolder - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../../parent/file.adoc"), - "Multiple parent directories with subfolder should contain subfolder"); - } - - @Test - @DisplayName("containsSubfolder handles complex path scenarios") - void testContainsSubfolderComplexPaths() { - // Test deep nested paths - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../level1/level2/level3/file.adoc"), - "Deep nested path should contain subfolder"); - - // Test paths with special characters in directory names - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../my-folder/my_file.adoc"), - "Path with special characters should contain subfolder"); - - // Test paths that start with current directory - method only handles "../" - assertFalse(IncludeHyperlinkDetector.containsSubfolder("./docs/readme.adoc"), - "Method only handles '../' patterns, not './' patterns"); - - assertFalse(IncludeHyperlinkDetector.containsSubfolder("./readme.adoc"), - "Current directory without subfolder should not contain subfolder"); - } - - @Test - @DisplayName("containsSubfolder verifies normalization behavior") - void testContainsSubfolderNormalization() { - // The method should normalize backslashes to forward slashes - // Test that backslashes are properly handled - String windowsPath = "..\\exercises\\test.adoc"; - String normalizedPath = windowsPath.replace("\\", "/"); - - // Both should give same result after normalization - boolean windowsResult = IncludeHyperlinkDetector.containsSubfolder(windowsPath); - boolean unixResult = IncludeHyperlinkDetector.containsSubfolder(normalizedPath); - - assertEquals(windowsResult, unixResult, - "Windows and Unix-style paths should produce same result after normalization"); - assertTrue(windowsResult, "Both paths should contain subfolders"); - } - - @Test - @DisplayName("containsSubfolder validates lastIndexOfParent logic") - void testContainsSubfolderParentLogic() { - // Test the specific logic: lastIndexOfParent and subsequent slash search - - // Path with multiple ../ but no subfolder after the last one - assertFalse(IncludeHyperlinkDetector.containsSubfolder("../../file.adoc"), - "No subfolder after last parent directory reference"); - - // Path with multiple ../ and subfolder after the last one - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../../folder/file.adoc"), - "Subfolder exists after last parent directory reference"); - - // Path with ../ in the middle but not at the end - assertTrue(IncludeHyperlinkDetector.containsSubfolder("../parent/../child/file.adoc"), - "Complex path with parent navigation should contain subfolder"); - } - - @Test - @DisplayName("containsSubfolder handles simple relative paths") - void testContainsSubfolderSimpleRelativePaths() { - // Test the issue case: simple relative paths without ./ or ../ - assertFalse(IncludeHyperlinkDetector.containsSubfolder("res/practical/asciidoc_validator.py"), - "containsSubfolder method is designed only for ../ patterns, not simple relative paths"); - - assertFalse(IncludeHyperlinkDetector.containsSubfolder("folder/file.adoc"), - "containsSubfolder method is designed only for ../ patterns, not simple relative paths"); - - assertFalse(IncludeHyperlinkDetector.containsSubfolder("deep/nested/path/file.txt"), - "containsSubfolder method is designed only for ../ patterns, not simple relative paths"); - - // Test backslashes too - assertFalse(IncludeHyperlinkDetector.containsSubfolder("folder\\file.adoc"), - "containsSubfolder method is designed only for ../ patterns, not simple relative paths"); - } - - @Test - @DisplayName("Test cases for the issue: include::res/practical/asciidoc_validator.py[]") - void testIssueSpecificCases() { - // This test validates the fix for the specific issue mentioned - - // Test the exact path from the issue - String issueExamplePath = "res/practical/asciidoc_validator.py"; - - // The containsSubfolder method should return false for simple relative paths - // because it's designed only for ../ patterns - assertFalse(IncludeHyperlinkDetector.containsSubfolder(issueExamplePath), - "containsSubfolder should return false for simple relative paths"); - - // However, the new logic in detectHyperlinks should handle these paths - // by detecting the slash and splitting folder from filename - assertTrue(issueExamplePath.contains("/"), - "Issue example path should contain forward slash"); - - // Verify the folder splitting logic would work correctly - int slashIndex = issueExamplePath.lastIndexOf("/"); - String expectedFolder = issueExamplePath.substring(0, slashIndex); - String expectedFileName = issueExamplePath.substring(slashIndex + 1); - - assertEquals("res/practical", expectedFolder, - "Folder part should be extracted correctly"); - assertEquals("asciidoc_validator.py", expectedFileName, - "Filename part should be extracted correctly"); - - // Test other similar cases - assertTrue("subfolder/file.txt".contains("/"), - "Simple subfolder paths should contain slash"); - assertTrue("docs/images/diagram.png".contains("/"), - "Multi-level paths should contain slash"); - assertTrue("code\\examples\\test.java".contains("\\"), - "Windows-style paths should contain backslash"); - } - - @Test - @DisplayName("Test edge cases for path resolution logic") - void testPathResolutionEdgeCases() { - // Test cases to ensure the new path resolution logic is robust - - // Test paths with multiple levels - String deepPath = "level1/level2/level3/file.txt"; - assertTrue(deepPath.contains("/"), "Deep paths should contain slash"); - int slashIndex = deepPath.lastIndexOf("/"); - assertEquals("level1/level2/level3", deepPath.substring(0, slashIndex), - "Deep folder extraction should work"); - assertEquals("file.txt", deepPath.substring(slashIndex + 1), - "Deep filename extraction should work"); - - // Test Windows-style paths - String windowsPath = "folder\\subfolder\\file.doc"; - assertTrue(windowsPath.contains("\\"), "Windows paths should contain backslash"); - int backslashIndex = windowsPath.lastIndexOf("\\"); - assertEquals("folder\\subfolder", windowsPath.substring(0, backslashIndex), - "Windows folder extraction should work"); - assertEquals("file.doc", windowsPath.substring(backslashIndex + 1), - "Windows filename extraction should work"); - - // Test mixed separators (should pick the last one) - String mixedPath = "folder/subfolder\\file.txt"; - int lastSeparator = Math.max(mixedPath.lastIndexOf("/"), mixedPath.lastIndexOf("\\")); - assertEquals(mixedPath.lastIndexOf("\\"), lastSeparator, - "Should pick the last separator regardless of type"); - assertEquals("folder/subfolder", mixedPath.substring(0, lastSeparator), - "Mixed path folder extraction should work"); - assertEquals("file.txt", mixedPath.substring(lastSeparator + 1), - "Mixed path filename extraction should work"); - - // Test simple single-level paths (should not trigger the new logic) - String simplePath = "simple-file.txt"; - assertFalse(simplePath.contains("/"), "Simple paths should not contain slash"); - assertFalse(simplePath.contains("\\"), "Simple paths should not contain backslash"); - - // Test paths with different extensions - assertTrue("images/diagram.png".contains("/"), "Image paths should work"); - assertTrue("scripts/build.sh".contains("/"), "Script paths should work"); - assertTrue("data/config.json".contains("/"), "Config paths should work"); - } - - @Test - @DisplayName("Test the bug fix for ./path handling") - void testCurrentDirectoryPathHandling() { - // Test the specific bug fix: ./path should not use substring(3) - - // Test paths that should work with proper prefix removal - String currentDirPath = "./readme.adoc"; - String parentDirPath = "../copyright.adoc"; - - // These tests verify the logic that would be used in the actual detector - // For paths starting with "../" - remove 3 characters - assertTrue(parentDirPath.startsWith("../"), "Parent dir path should start with ../"); - assertEquals("copyright.adoc", parentDirPath.substring(3), - "Parent dir path should remove ../ correctly"); - - // For paths starting with "./" - remove 2 characters (this was the bug) - assertTrue(currentDirPath.startsWith("./"), "Current dir path should start with ./"); - assertEquals("readme.adoc", currentDirPath.substring(2), - "Current dir path should remove ./ correctly"); - - // The bug was using substring(3) for both cases - assertNotEquals("readme.adoc", currentDirPath.substring(3), - "Using substring(3) on ./ path should NOT produce correct result"); - assertEquals("eadme.adoc", currentDirPath.substring(3), - "Using substring(3) on ./ path produces incorrect result (the bug)"); - } - - @Test - @DisplayName("Test various prefix scenarios that should be handled correctly") - void testPrefixHandling() { - // Test that the detector logic handles various prefixes correctly - - // Parent directory cases - assertTrue("../file.adoc".startsWith("../")); - assertTrue("../../file.adoc".startsWith("../")); - assertTrue("../subfolder/file.adoc".startsWith("../")); - - // Current directory cases - assertTrue("./file.adoc".startsWith("./")); - assertTrue("./subfolder/file.adoc".startsWith("./")); - - // Simple relative paths (no prefix) - assertFalse("subfolder/file.adoc".startsWith("../")); - assertFalse("subfolder/file.adoc".startsWith("./")); - assertTrue("subfolder/file.adoc".contains("/")); // Should use relative path logic - - // Simple files (no path separators) - assertFalse("file.adoc".startsWith("../")); - assertFalse("file.adoc".startsWith("./")); - assertFalse("file.adoc".contains("/")); - assertFalse("file.adoc".contains("\\")); - } - - @Test - @DisplayName("Test case for hyperlinking include::../copyright.adoc[] - the specific issue scenario") - void testIncludeCopyrightAdocHyperlink() { - // This test validates the specific scenario from the issue: include::../copyright.adoc[] - String issueExamplePath = "../copyright.adoc"; - - // Verify this path starts with "../" and should be handled by the parent directory logic - assertTrue(issueExamplePath.startsWith("../"), - "Copyright include path should start with '../'"); - - // Since it doesn't contain a subfolder (no slash after removing "../"), - // containsSubfolder should return false - assertFalse(IncludeHyperlinkDetector.containsSubfolder(issueExamplePath), - "../copyright.adoc should not be detected as containing a subfolder"); - - // Verify the path processing logic that would be applied - // The detector should remove the "../" prefix and look for "copyright.adoc" - String expectedFileName = issueExamplePath.substring(3); // Remove "../" - assertEquals("copyright.adoc", expectedFileName, - "After removing '../' prefix, filename should be 'copyright.adoc'"); - - // Verify this is not a complex path scenario - String pathAfterPrefix = issueExamplePath.substring(3); - assertFalse(pathAfterPrefix.contains("/"), - "After '../', there should be no additional path separators"); - assertFalse(pathAfterPrefix.contains("\\"), - "After '../', there should be no Windows-style path separators"); - - // Test the string processing that the hyperlink detector would perform - String processedPath = issueExamplePath; - if (processedPath.startsWith("../")) { - // This simulates the logic in detectHyperlinks method - if (!IncludeHyperlinkDetector.containsSubfolder(processedPath)) { - processedPath = processedPath.substring(3); // Remove "../" - } - } - - assertEquals("copyright.adoc", processedPath, - "Processed path should result in just the filename"); - } - - @Test - @DisplayName("Test various ../filename.adoc scenarios for comprehensive coverage") - void testParentDirectoryFilePatterns() { - // Test multiple variations of the ../filename.adoc pattern - String[] testPaths = { - "../copyright.adoc", // The specific issue case - "../readme.adoc", // Another common case - "../license.txt", // Non-adoc file - "../settings.xml", // XML file - "../config.properties" // Properties file - }; - - for (String path : testPaths) { - // All should start with "../" - assertTrue(path.startsWith("../"), - String.format("Path '%s' should start with '../'", path)); - - // None should contain subfolders (according to containsSubfolder logic) - assertFalse(IncludeHyperlinkDetector.containsSubfolder(path), - String.format("Path '%s' should not contain subfolders", path)); - - // All should process to just the filename - String fileName = path.substring(3); - assertFalse(fileName.contains("/"), - String.format("Filename '%s' should not contain path separators", fileName)); - assertFalse(fileName.contains("\\"), - String.format("Filename '%s' should not contain Windows separators", fileName)); - } - } - - @Test - @DisplayName("Test contrast between ../filename.adoc and ../subfolder/filename.adoc") - void testParentVsParentSubfolder() { - // Test the difference between simple parent file reference vs parent subfolder reference - - // Simple parent file (like the issue case) - String simpleParentPath = "../copyright.adoc"; - assertFalse(IncludeHyperlinkDetector.containsSubfolder(simpleParentPath), - "Simple parent file should not contain subfolder"); - - // Parent with subfolder - String parentSubfolderPath = "../docs/copyright.adoc"; - assertTrue(IncludeHyperlinkDetector.containsSubfolder(parentSubfolderPath), - "Parent with subfolder should be detected as containing subfolder"); - - // Verify the processing difference - // Simple parent: just remove "../" - assertEquals("copyright.adoc", simpleParentPath.substring(3), - "Simple parent should process to just filename"); - - // Parent with subfolder: needs folder extraction - int lastSlash = parentSubfolderPath.lastIndexOf("/"); - String folderPart = parentSubfolderPath.substring(0, lastSlash); - String filePart = parentSubfolderPath.substring(lastSlash + 1); - - assertEquals("../docs", folderPart, - "Folder part should include parent navigation and subfolder"); - assertEquals("copyright.adoc", filePart, - "File part should be just the filename"); - } -} \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc/.settings/org.eclipse.m2e.core.prefs b/com.vogella.ide.editor.asciidoc/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.ide.editor.asciidoc/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.ide.editor.asciidoc/plugin.xml b/com.vogella.ide.editor.asciidoc/plugin.xml index e7bfb11..26e72d4 100644 --- a/com.vogella.ide.editor.asciidoc/plugin.xml +++ b/com.vogella.ide.editor.asciidoc/plugin.xml @@ -44,79 +44,5 @@ icon="icons/asciidoc.png"> - - - - - - - - - - - - - - - - - - diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocContentAssistProcessor.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocContentAssistProcessor.java deleted file mode 100644 index 812e9a0..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocContentAssistProcessor.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import org.eclipse.jface.text.contentassist.CompletionProposal; -import org.eclipse.jface.text.contentassist.IContentAssistProcessor; -import org.eclipse.jface.text.contentassist.IContextInformation; -import org.eclipse.jface.text.contentassist.IContextInformationValidator; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.texteditor.ITextEditor; -import org.eclipse.jface.text.contentassist.ICompletionProposal; -import org.eclipse.jface.text.ITextViewer; - -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import org.eclipse.core.resources.IFile; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; - -public class AsciidocContentAssistProcessor implements IContentAssistProcessor { - - // Common AsciiDoc syntax elements for completion - public static final List PROPOSALS = Arrays.asList("= Title", // Header level 1 - "== Subtitle", // Header level 2 - "=== Subsubtitle", // Header level 3 - "* List item", // Unordered list - "1. Ordered list item", // Ordered list - """ - [source, java] - ---- - - ---- - """, ":attribute:", // Attribute - "image::[]", // Image - "include::[]" // Included Files - ); - - public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { - String typedText = getTypedTextAtOffset(viewer, offset); - - // If "image::" is typed, suggest image files - if (typedText.startsWith("image::")) { - String pathAfterImage = typedText.substring("image::".length()); - List imageFiles = getImageFiles(pathAfterImage); - return imageFiles.stream() - .map(filePath -> new CompletionProposal("image::" + filePath + "[]", - offset - typedText.length(), - typedText.length(), - ("image::" + filePath + "[]").length())) - .toArray(ICompletionProposal[]::new); - } - - // If "include::" is typed, suggest .adoc files - if (typedText.startsWith("include::")) { - String pathAfterInclude = typedText.substring("include::".length()); - List includeFiles = getIncludeFiles(pathAfterInclude); - return includeFiles.stream() - .map(filePath -> new CompletionProposal("include::" + filePath + "[]", - offset - typedText.length(), - typedText.length(), - ("include::" + filePath + "[]").length())) - .toArray(ICompletionProposal[]::new); - } - - // Filter proposals that match the typed text for other cases - return getMatchingProposals(typedText, offset); - } - - private ICompletionProposal[] getMatchingProposals(String typedText, int offset) { - // Match proposals that start with the typed text - List filteredProposals = PROPOSALS.stream() - .filter(proposal -> proposal.toLowerCase().startsWith(typedText.toLowerCase())) - .collect(Collectors.toList()); - - return filteredProposals.stream().map(proposal -> new CompletionProposal(proposal, offset - typedText.length(), - typedText.length(), proposal.length())).toArray(ICompletionProposal[]::new); - } - - private String getTypedTextAtOffset(ITextViewer viewer, int offset) { - try { - IDocument document = viewer.getDocument(); - int lineStartOffset = document.getLineOffset(document.getLineOfOffset(offset)); - return document.get(lineStartOffset, offset - lineStartOffset); - } catch (BadLocationException e) { - return ""; - } - } - - private List getImageFiles(String pathAfterImage) { - String directoryPath = getDirectoryPath(); - if (directoryPath == null) { - return Collections.emptyList(); - } - - // Images are expected in an "img" subdirectory - File folder = new File(directoryPath, "img"); - if (!folder.exists() || !folder.isDirectory()) { - return Collections.emptyList(); - } - - File[] files = folder.listFiles((dir, name) -> - (name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".jpg")) - && name.startsWith(pathAfterImage) - ); - - if (files == null) { - return Collections.emptyList(); - } - - return Arrays.stream(files).map(File::getName).collect(Collectors.toList()); - } - - // Method to get files for include:: - private List getIncludeFiles(String pathAfterInclude) { - String directoryPath = getDirectoryPath(); - if (directoryPath == null) { - return Collections.emptyList(); - } - - // Parse the path to extract directory and filename prefix - String targetDirectory = directoryPath; - String filePrefix = pathAfterInclude; - - // Handle paths with directory separators - if (pathAfterInclude.contains("/") || pathAfterInclude.contains("\\")) { - int lastSeparatorIndex = Math.max( - pathAfterInclude.lastIndexOf("/"), - pathAfterInclude.lastIndexOf("\\") - ); - - String relativePath = pathAfterInclude.substring(0, lastSeparatorIndex); - filePrefix = pathAfterInclude.substring(lastSeparatorIndex + 1); - - // Build the target directory path - targetDirectory = new File(directoryPath, relativePath).getAbsolutePath(); - } - - File folder = new File(targetDirectory); - if (!folder.exists() || !folder.isDirectory()) { - return Collections.emptyList(); - } - - // Filter files by extension and prefix - final String finalPrefix = filePrefix; - File[] files = folder.listFiles((dir, name) -> - name.endsWith(".adoc") && name.startsWith(finalPrefix) - ); - - if (files == null) { - return Collections.emptyList(); - } - - // Build the full path for each file (including the directory part) - String pathPrefix = pathAfterInclude.substring(0, pathAfterInclude.length() - filePrefix.length()); - return Arrays.stream(files) - .map(file -> pathPrefix + file.getName()) - .collect(Collectors.toList()); - } - - private String getDirectoryPath() { - - IEditorPart activeEditor = Util.getActiveEditor(); - // Get the editor file's path (assuming the document is backed by a file) - - if (activeEditor == null) { - return null; - } - IEditorInput editorInput = activeEditor.getEditorInput(); - - if (!(editorInput instanceof IFileEditorInput)) { - return null; // Return null if the editor is not backed by a file - } - - IFile file = ((IFileEditorInput) editorInput).getFile(); - return file.getParent().getLocation().toOSString(); // Return the directory path of the file - } - - @Override - public char[] getCompletionProposalAutoActivationCharacters() { - return new char[0]; - } - - @Override - public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { - // TODO Auto-generated method stub - return null; - } - - @Override - public char[] getContextInformationAutoActivationCharacters() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getErrorMessage() { - // TODO Auto-generated method stub - return null; - } - - @Override - public IContextInformationValidator getContextInformationValidator() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewer.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewer.java deleted file mode 100644 index 19d7a65..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.contentmergeviewer.TextMergeViewer; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Composite; - -public class AsciidocMergeViewer extends TextMergeViewer { - - public AsciidocMergeViewer(Composite parent, int style, CompareConfiguration configuration) { - super(parent, style, configuration); - configuration.setProperty("org.eclipse.compare.INCOMING_COLOR", new RGB(0, 255, 0)); - configuration.setProperty("org.eclipse.compare.OUTGOING_COLOR", new RGB(255, 0, 0)); - } -} diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewerCreator.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewerCreator.java deleted file mode 100644 index c38fd20..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/AsciidocMergeViewerCreator.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.IViewerCreator; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; - -public class AsciidocMergeViewerCreator implements IViewerCreator { - - @Override - public Viewer createViewer(Composite parent, CompareConfiguration config) { - return new AsciidocMergeViewer(parent, SWT.NONE, config); - } -} \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHover.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHover.java deleted file mode 100644 index 89b6360..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHover.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextHover; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Region; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PlatformUI; - -import java.io.File; - -public class ImageHover implements ITextHover { - - private static final String IMAGE_PREFIX = "image::"; - private static final String IMAGE_DIRECTORY = "img"; // Directory for images - - @Override - public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { - int offset = hoverRegion.getOffset(); - IDocument document = textViewer.getDocument(); - - try { - int lineNumber = document.getLineOfOffset(offset); - IRegion lineInformation = document.getLineInformation(lineNumber); - String lineContent = document.get(lineInformation.getOffset(), lineInformation.getLength()); - - // Check if the line contains the image syntax - if (lineContent.contains(IMAGE_PREFIX)) { - // Extract the image name - int startIndex = lineContent.indexOf(IMAGE_PREFIX) + IMAGE_PREFIX.length(); - int endIndex = lineContent.indexOf("[]", startIndex); - - if (endIndex > startIndex) { - String imageName = lineContent.substring(startIndex, endIndex).trim(); - - - IContainer parent = getParentFolder(); - IContainer imgFolder = parent.getFolder(IPath.fromOSString("img")); - - - IFile imageFile = imgFolder.getFile(IPath.fromOSString(imageName)); // Replace "filename.ext" with your actual file name - - - // Check if image file exists - if (imageFile.exists()) { - // Load and display the image in the hover (assuming HTML rendering is supported) - return "\"""; - } else { - return "Image not found in 'img' directory: " + imageName; - } - } - } - - // If no image syntax, return the full line - return lineContent; - - } catch (BadLocationException e) { - e.printStackTrace(); - } - - return ""; - } - - @Override - public IRegion getHoverRegion(ITextViewer textViewer, int offset) { - return new Region(offset, 0); - } - - - private IContainer getParentFolder() { - IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class); - Object object = context.get("activeEditor"); - - if (object instanceof IEditorPart activeEditor) { - - IEditorInput editorInput = activeEditor.getEditorInput(); - IResource adapter = editorInput.getAdapter(IResource.class); - IContainer parent = adapter.getParent(); - return parent; - } - return null; - } -} diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHyperlinkDetector.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHyperlinkDetector.java deleted file mode 100644 index 83d9278..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ImageHyperlinkDetector.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import java.util.Arrays; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; -import org.eclipse.jface.text.hyperlink.IHyperlink; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -public class ImageHyperlinkDetector extends AbstractHyperlinkDetector { - - private static final String IMAGE_PROPERTY = "image::"; - - @Override - public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { - - IDocument document = textViewer.getDocument(); - - try { - int offset = region.getOffset(); - - IRegion lineInformationOfOffset = document.getLineInformationOfOffset(offset); - String lineContent = document.get(lineInformationOfOffset.getOffset(), lineInformationOfOffset.getLength()); - - // Content assist should only be used in the dependent line - if (lineContent.startsWith(IMAGE_PROPERTY)) { - String dependentResourceName = lineContent.substring(IMAGE_PROPERTY.length(), lineContent.indexOf("[")) - .trim(); - - Region targetRegion = new Region(lineInformationOfOffset.getOffset() + IMAGE_PROPERTY.length(), - lineInformationOfOffset.getLength() - IMAGE_PROPERTY.length()); - - IContainer parent = getParentFolder(); - IContainer imgFolder = parent.getFolder(IPath.fromOSString("img")); - - // Only take resources, which have the "png" file extension - IHyperlink[] result = Arrays.stream(imgFolder.members()) - .filter(res -> res instanceof IFile && res.getName().equals(dependentResourceName) - && res.getFileExtension().equals("png")) - .map(res -> new ResourceHyperlink(targetRegion, res.getName(), (IFile) res)) - .toArray(IHyperlink[]::new); - - return result.length == 0 ? null : result; - - } - - } catch (CoreException | BadLocationException e) { - e.printStackTrace(); - } - // do not return new IHyperlink[0] because the array may only be null or not - // empty - return null; - - } - - private IContainer getParentFolder() { - IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class); - Object object = context.get("activeEditor"); - - if (object instanceof IEditorPart activeEditor) { - - IEditorInput editorInput = activeEditor.getEditorInput(); - IResource adapter = editorInput.getAdapter(IResource.class); - IContainer parent = adapter.getParent(); - return parent; - } - return null; - } - - -} diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/IncludeHyperlinkDetector.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/IncludeHyperlinkDetector.java deleted file mode 100644 index cff53ce..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/IncludeHyperlinkDetector.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import java.util.Arrays; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Path; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; -import org.eclipse.jface.text.hyperlink.IHyperlink; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PlatformUI; - -public class IncludeHyperlinkDetector extends AbstractHyperlinkDetector { - - private static final String HYPERLINK_PROPERTY = "include::"; - - @Override - public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { - - IDocument document = textViewer.getDocument(); - IContainer parent = getParentFolder(); - - try { - int offset = region.getOffset(); - - IRegion lineInformationOfOffset = document.getLineInformationOfOffset(offset); - String lineContent = document.get(lineInformationOfOffset.getOffset(), lineInformationOfOffset.getLength()); - - if (lineContent.startsWith(HYPERLINK_PROPERTY)) { - String dependentResourceName = lineContent - .substring(HYPERLINK_PROPERTY.length(), lineContent.indexOf("[")).trim(); - - Region targetRegion = new Region(lineInformationOfOffset.getOffset() + HYPERLINK_PROPERTY.length(), - lineInformationOfOffset.getLength() - HYPERLINK_PROPERTY.length()); - - String fileName; - - // Check if the dependent resource starts with "./" or "../" - if (dependentResourceName.startsWith("../") || dependentResourceName.startsWith("./")) { - - if (containsSubfolder(dependentResourceName)) { - // Handle cases with subdirectories - int lastSlashIndex = dependentResourceName.lastIndexOf("/"); - String folder = dependentResourceName.substring(0, lastSlashIndex); - dependentResourceName = dependentResourceName.substring(lastSlashIndex + 1); - IContainer subfolder = parent.getFolder(new Path(folder)); - parent = subfolder; - } else { - // Handle cases like "../exercise_settings.adoc" or "./exercise_settings.adoc" without a folder structure - if (dependentResourceName.startsWith("../")) { - dependentResourceName = dependentResourceName.substring(3); // Remove "../" - } else if (dependentResourceName.startsWith("./")) { - dependentResourceName = dependentResourceName.substring(2); // Remove "./" - } - } - } else if (dependentResourceName.contains("/") || dependentResourceName.contains("\\")) { - // Handle simple relative paths like "res/practical/asciidoc_validator.py" - int lastSlashIndex = Math.max(dependentResourceName.lastIndexOf("/"), - dependentResourceName.lastIndexOf("\\")); - String folder = dependentResourceName.substring(0, lastSlashIndex); - dependentResourceName = dependentResourceName.substring(lastSlashIndex + 1); - IContainer subfolder = parent.getFolder(new Path(folder)); - parent = subfolder; - } - - if (!parent.exists()) { - return null; - } - - fileName = dependentResourceName; - IResource[] members = parent.members(); - // Only take resources with the "adoc" file extension and skip the current - // resource itself - IHyperlink[] result = Arrays.stream(members) - .filter(res -> res instanceof IFile && res.getName().equals(fileName)) - .map(res -> new ResourceHyperlink(targetRegion, res.getName(), (IFile) res)) - .toArray(IHyperlink[]::new); - - return result.length == 0 ? null : result; - } - - } catch (CoreException | BadLocationException e) { - e.printStackTrace(); - } - // do not return new IHyperlink[0] because the array may only be null or not - // empty - return null; - } - - public static boolean containsSubfolder(String relativePath) { - String normalizedPath = relativePath.replace("\\", "/"); // Normalize for cross-platform - int lastIndexOfParent = normalizedPath.lastIndexOf("../"); - return lastIndexOfParent != -1 && normalizedPath.indexOf("/", lastIndexOfParent + 3) != -1; - } - - private IContainer getParentFolder() { - IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class); - Object object = context.get("activeEditor"); - - if (object instanceof IEditorPart activeEditor) { - - IEditorInput editorInput = activeEditor.getEditorInput(); - IResource adapter = editorInput.getAdapter(IResource.class); - IContainer parent = adapter.getParent(); - return parent; - } - return null; - } - -} \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/LinkHyperlinkDetector.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/LinkHyperlinkDetector.java deleted file mode 100644 index b8b87bd..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/LinkHyperlinkDetector.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import java.util.Arrays; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Path; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; -import org.eclipse.jface.text.hyperlink.IHyperlink; -import org.eclipse.swt.program.Program; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PlatformUI; - -public class LinkHyperlinkDetector extends AbstractHyperlinkDetector { - - private static final String HYPERLINK_PROPERTY = "link:"; - - @Override - public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { - - IDocument document = textViewer.getDocument(); - IContainer parent = getParentFolder(); - - try { - int offset = region.getOffset(); - - IRegion lineInformationOfOffset = document.getLineInformationOfOffset(offset); - String lineContent = document.get(lineInformationOfOffset.getOffset(), lineInformationOfOffset.getLength()); - - if (lineContent.contains(HYPERLINK_PROPERTY)) { - int start = lineContent.indexOf(HYPERLINK_PROPERTY); - int end = lineContent.indexOf("[", start); - if (end == -1) { - return null; - } - - String target = lineContent.substring(start + HYPERLINK_PROPERTY.length(), end).trim(); - Region targetRegion = new Region(lineInformationOfOffset.getOffset() + start, - end - start); - - if (target.startsWith("http://") || target.startsWith("https://")) { - // External link → open in browser - return new IHyperlink[] { - new IHyperlink() { - @Override - public IRegion getHyperlinkRegion() { - return targetRegion; - } - - @Override - public String getTypeLabel() { - return "Open external link"; - } - - @Override - public String getHyperlinkText() { - return "Open " + target + " in browser"; - } - - @Override - public void open() { - Program.launch(target); - } - } - }; - } else if (target.startsWith("./") || target.startsWith("../")) { - // Internal file link → open in Eclipse editor - if (parent != null && parent.exists()) { - IResource resource = parent.findMember(new Path(target)); - if (resource instanceof IFile file) { - return new IHyperlink[] { - new ResourceHyperlink(targetRegion, resource.getName(), file) - }; - } - } - } - } - } catch (BadLocationException e) { - e.printStackTrace(); - } - - return null; - } - - private IContainer getParentFolder() { - IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class); - Object object = context.get("activeEditor"); - - if (object instanceof IEditorPart activeEditor) { - IEditorInput editorInput = activeEditor.getEditorInput(); - IResource adapter = editorInput.getAdapter(IResource.class); - if (adapter != null) { - return adapter.getParent(); - } - } - return null; - } -} diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ResourceHyperlink.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ResourceHyperlink.java deleted file mode 100644 index 7846b74..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/ResourceHyperlink.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.vogella.ide.editor.asciidoc; -import org.eclipse.core.resources.IFile; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.hyperlink.IHyperlink; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.ide.IDE; - -public class ResourceHyperlink implements IHyperlink { - - private IRegion region; - private String hyperlinkText; - private IFile resource; - - public ResourceHyperlink(IRegion region, String hyperlinkText, IFile resource) { - this.region = region; - this.hyperlinkText = hyperlinkText; - this.resource = resource; - } - - @Override - public IRegion getHyperlinkRegion() { - return region; - } - - @Override - public String getTypeLabel() { - return null; - } - - @Override - public String getHyperlinkText() { - return hyperlinkText; - } - - @Override - public void open() { - IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - try { - IDE.openEditor(activePage, resource); - } catch (PartInitException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/Util.java b/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/Util.java deleted file mode 100644 index 3c749b4..0000000 --- a/com.vogella.ide.editor.asciidoc/src/com/vogella/ide/editor/asciidoc/Util.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.vogella.ide.editor.asciidoc; - -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -public class Util { - - private Util() { - // only helper - } - - public static boolean testRun; - - public static IEditorPart getActiveEditor() { - if (testRun) { - return null; - } - IWorkbench workbench = PlatformUI.getWorkbench(); - IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); - if (null == activeWorkbenchWindow) { - activeWorkbenchWindow = workbench.getWorkbenchWindows()[0]; - } - IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage(); - if (activePage == null) { - return null; - } - return activePage.getActiveEditor(); - } -} \ No newline at end of file diff --git a/com.vogella.ide.editor.gradle/.settings/org.eclipse.core.resources.prefs b/com.vogella.ide.editor.gradle/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.ide.editor.gradle/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.ide.editor.gradle/.settings/org.eclipse.m2e.core.prefs b/com.vogella.ide.editor.gradle/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.ide.editor.gradle/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.ide.editor.shell/.settings/org.eclipse.m2e.core.prefs b/com.vogella.ide.editor.shell/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.ide.editor.shell/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.ide.editor.tasks/.settings/org.eclipse.core.resources.prefs b/com.vogella.ide.editor.tasks/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.ide.editor.tasks/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.ide.editor.tasks/.settings/org.eclipse.m2e.core.prefs b/com.vogella.ide.editor.tasks/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.ide.editor.tasks/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.ide.first/.settings/org.eclipse.core.resources.prefs b/com.vogella.ide.first/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.ide.first/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.ide.first/.settings/org.eclipse.m2e.core.prefs b/com.vogella.ide.first/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.ide.first/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.languageserver.dart/.settings/org.eclipse.m2e.core.prefs b/com.vogella.languageserver.dart/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.languageserver.dart/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.preferences.page/.settings/org.eclipse.core.resources.prefs b/com.vogella.preferences.page/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.preferences.page/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.preferences.page/.settings/org.eclipse.m2e.core.prefs b/com.vogella.preferences.page/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.preferences.page/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.resources/.settings/org.eclipse.core.resources.prefs b/com.vogella.resources/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.resources/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.resources/.settings/org.eclipse.m2e.core.prefs b/com.vogella.resources/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.resources/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.swt.widgets/.settings/org.eclipse.core.resources.prefs b/com.vogella.swt.widgets/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.swt.widgets/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.swt.widgets/.settings/org.eclipse.m2e.core.prefs b/com.vogella.swt.widgets/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.swt.widgets/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.events/.settings/org.eclipse.core.resources.prefs b/com.vogella.tasks.events/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.tasks.events/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.tasks.events/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.events/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.events/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.core.resources.prefs b/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.extendedsupplier/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.model/.settings/org.eclipse.core.resources.prefs b/com.vogella.tasks.model/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.tasks.model/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.tasks.model/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.model/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.model/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.services.tests/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.services.tests/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.services.tests/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.services/.settings/org.eclipse.core.resources.prefs b/com.vogella.tasks.services/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.tasks.services/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.tasks.services/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.services/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.services/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/com.vogella.tasks.ui/.settings/org.eclipse.core.resources.prefs b/com.vogella.tasks.ui/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/com.vogella.tasks.ui/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/com.vogella.tasks.ui/.settings/org.eclipse.m2e.core.prefs b/com.vogella.tasks.ui/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/com.vogella.tasks.ui/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/pom.xml b/pom.xml index beb62fe..662df9f 100644 --- a/pom.xml +++ b/pom.xml @@ -139,7 +139,6 @@ com.vogella.tasks.services.tests - com.vogella.ide.editor.asciidoc.tests updatesite diff --git a/updatesite/.settings/org.eclipse.m2e.core.prefs b/updatesite/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/updatesite/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/z.ex.search/.settings/org.eclipse.m2e.core.prefs b/z.ex.search/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/z.ex.search/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1