diff --git a/com.microsoft.copilot.eclipse.core.test/src/com/microsoft/copilot/eclipse/core/completion/FormatOptionProviderTests.java b/com.microsoft.copilot.eclipse.core.test/src/com/microsoft/copilot/eclipse/core/completion/FormatOptionProviderTests.java index c87449dc..eeeb756d 100644 --- a/com.microsoft.copilot.eclipse.core.test/src/com/microsoft/copilot/eclipse/core/completion/FormatOptionProviderTests.java +++ b/com.microsoft.copilot.eclipse.core.test/src/com/microsoft/copilot/eclipse/core/completion/FormatOptionProviderTests.java @@ -10,10 +10,15 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.lsp4j.FormattingOptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.junit.jupiter.MockitoExtension; import com.microsoft.copilot.eclipse.core.format.FormatOptionProvider; @@ -25,7 +30,9 @@ class FormatOptionProviderTests { private IFile mockFile; private IProject mockProject; - private static final int PREFERENCE_DEFAULT_TAB_SIZE = 4; + private static final String EDITOR_PREF_NODE = "org.eclipse.ui.editors"; + private static final String TAB_WIDTH_KEY = "tabWidth"; + private static final String SPACES_FOR_TABS_KEY = "spacesForTabs"; @BeforeEach void setUp() { @@ -52,20 +59,20 @@ void testGetEclipseDefaultJavaTabCharAndSize() { assertEquals(tabSize, formatOptionProvider.getTabSize(mockFile)); } - @Test - void testGetCopilotDefaultTabCharAndSizeForUnknownLanguage() { - when(mockFile.getFileExtension()).thenReturn("js"); - - assertTrue(formatOptionProvider.useSpace(mockFile)); - assertEquals(PREFERENCE_DEFAULT_TAB_SIZE, formatOptionProvider.getTabSize(mockFile)); - } + @ParameterizedTest @NullSource @ValueSource(strings = { "js" }) + void testUsesEclipseTextEditorFormattingOptionsForUnknownOrNoExtension(String extension) { + when(mockFile.getFileExtension()).thenReturn(extension); - @Test - void testGetCopilotDefaultTabCharAndSizeForNoExtensionFile() { - when(mockFile.getFileExtension()).thenReturn(null); + // Set the Eclipse preferences to be something other than the default (false, 4) + setEditorFormattingPreferences(true, 2); assertTrue(formatOptionProvider.useSpace(mockFile)); - assertEquals(PREFERENCE_DEFAULT_TAB_SIZE, formatOptionProvider.getTabSize(mockFile)); + assertEquals(2, formatOptionProvider.getTabSize(mockFile)); } + private void setEditorFormattingPreferences(boolean useSpaces, int tabSize) { + IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(EDITOR_PREF_NODE); + prefs.putBoolean(SPACES_FOR_TABS_KEY, useSpaces); + prefs.putInt(TAB_WIDTH_KEY, tabSize); + } } diff --git a/com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/format/FormatOptionProvider.java b/com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/format/FormatOptionProvider.java index 8b06a164..b738929f 100644 --- a/com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/format/FormatOptionProvider.java +++ b/com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/format/FormatOptionProvider.java @@ -9,6 +9,8 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.lsp4j.FormattingOptions; import com.microsoft.copilot.eclipse.core.CopilotCore; @@ -26,6 +28,9 @@ public class FormatOptionProvider { private static final String CPP_LANGUAGE_ID = "cpp"; private static final String[] CPP_LANGUAGE_EXTENSIONS = new String[] { "cpp", "c++", "cc", "cp", "cxx", "h", "h++", "hh", ".hpp", ".hxx", ".inc", ".inl", ".ipp", ".tcc", ".tpp" }; + private static final String EDITOR_PREF_NODE = "org.eclipse.ui.editors"; + private static final String TAB_WIDTH_KEY = "tabWidth"; + private static final String SPACES_FOR_TABS_KEY = "spacesForTabs"; private static final boolean DEFAULT_USE_SPACE = LanguageFormatReader.PREFERENCE_DEFAULT_TAB_CHAR.equals("space"); private static final int DEFAULT_TAB_SIZE = LanguageFormatReader.PREFERENCE_DEFAULT_TAB_SIZE; @@ -85,13 +90,13 @@ private FormattingOptions getLanguageFormat(IFile file) { IProject project = file.getProject(); if (project == null) { CopilotCore.LOGGER.info("Project is null for file: " + file.getName() + "default format will be applied."); - return null; + return getEclipseTextEditorFormattingOptions(); } String fileExtension = file.getFileExtension(); if (StringUtils.isEmpty(fileExtension)) { CopilotCore.LOGGER.info("File extension is null or empty for file: " + file.getName()); - return null; + return getEclipseTextEditorFormattingOptions(); } else { fileExtension = fileExtension.toLowerCase(); } @@ -110,7 +115,7 @@ private FormattingOptions getLanguageFormat(IFile file) { if (languageFormatReaderForProject == null) { languageFormatReaderForProject = loadFormatReaderForTheProject(languageId, project); if (languageFormatReaderForProject == null) { - return new FormattingOptions(DEFAULT_TAB_SIZE, DEFAULT_USE_SPACE); + return getEclipseTextEditorFormattingOptions(); } projectToLanguageFormatReaderMap.put(project, languageFormatReaderForProject); } @@ -118,6 +123,38 @@ private FormattingOptions getLanguageFormat(IFile file) { return languageFormatReaderForProject.getFormattingOptions(); } + /** + * Attempts to read the Eclipse default text editor preferences for tab size and spaces-for-tabs. + * Falls back to hardcoded defaults if the preferences cannot be read. + */ + private FormattingOptions getEclipseTextEditorFormattingOptions() { + try { + IPreferencesService service = Platform.getPreferencesService(); + + boolean useSpaces = service.getBoolean( + EDITOR_PREF_NODE, + SPACES_FOR_TABS_KEY, + DEFAULT_USE_SPACE, + null + ); + + int tabSize = service.getInt( + EDITOR_PREF_NODE, + TAB_WIDTH_KEY, + DEFAULT_TAB_SIZE, + null + ); + + return new FormattingOptions(tabSize, useSpaces); + } catch (Exception e) { + CopilotCore.LOGGER.info( + "Failed to read Eclipse text editor preferences, using defaults"); + return new FormattingOptions(DEFAULT_TAB_SIZE, DEFAULT_USE_SPACE); + } + } + + + private LanguageFormatReader loadFormatReaderForTheProject(String languageId, IProject project) { switch (languageId) { case JAVA_LANGUAGE_ID: @@ -129,4 +166,4 @@ private LanguageFormatReader loadFormatReaderForTheProject(String languageId, IP return null; } } -} \ No newline at end of file +}