diff --git a/src/main/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsService.java b/src/main/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsService.java index ad2dd4e..b5a402c 100644 --- a/src/main/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsService.java +++ b/src/main/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsService.java @@ -3,12 +3,14 @@ import com.intellij.application.options.CodeStyle; import com.intellij.openapi.components.Service; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsChangeEvent; import com.intellij.psi.codeStyle.CodeStyleSettingsListener; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.sap.cap.cds.intellij.CdsFileType; import org.jetbrains.annotations.NotNull; import org.json.JSONException; @@ -20,6 +22,7 @@ import static com.sap.cap.cds.intellij.util.JsonUtil.isJsonEqual; import static com.sap.cap.cds.intellij.util.Logger.logger; import static java.nio.file.Files.readString; +import static java.util.Arrays.stream; @Service(Service.Level.PROJECT) public final class CdsCodeStyleSettingsService { @@ -36,7 +39,9 @@ public CdsCodeStyleSettingsService(Project project) { CodeStyleSettingsManager.getInstance(project).subscribe(new CodeStyleSettingsListener() { @Override public void codeStyleSettingsChanged(@NotNull CodeStyleSettingsChangeEvent event) { - updateSettingsFile(); + if (shouldBeSavedImmediately()) { + updateSettingsFile(); + } } }); } @@ -45,6 +50,16 @@ public void codeStyleSettingsChanged(@NotNull CodeStyleSettingsChangeEvent event return CodeStyle.getDefaultSettings().getCustomSettings(CdsCodeStyleSettings.class); } + private boolean shouldBeSavedImmediately() { + if (isSettingsFilePresent()) { + return true; + } + + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + return stream(fileEditorManager.getOpenFiles()) + .anyMatch(file -> CdsFileType.EXTENSION.equalsIgnoreCase(file.getExtension())); + } + public boolean isSettingsFilePresent() { return prettierJsonManager.isJsonFilePresent(); } diff --git a/src/main/java/com/sap/cap/cds/intellij/lsp/CdsLspServerSupportProvider.java b/src/main/java/com/sap/cap/cds/intellij/lsp/CdsLspServerSupportProvider.java index 320f4b3..8c50b8a 100644 --- a/src/main/java/com/sap/cap/cds/intellij/lsp/CdsLspServerSupportProvider.java +++ b/src/main/java/com/sap/cap/cds/intellij/lsp/CdsLspServerSupportProvider.java @@ -6,6 +6,7 @@ import com.intellij.platform.lsp.api.lsWidget.LspServerWidgetItem; import com.sap.cap.cds.intellij.CdsFileType; import com.sap.cap.cds.intellij.CdsIcons; +import com.sap.cap.cds.intellij.codestyle.CdsCodeStyleSettingsService; import com.sap.cap.cds.intellij.lang.CdsLanguage; import kotlin.jvm.internal.Intrinsics; import org.jetbrains.annotations.NotNull; @@ -18,6 +19,7 @@ public void fileOpened(@NotNull Project project, @NotNull VirtualFile virtualFil if (!CdsFileType.EXTENSION.equals(virtualFile.getExtension())) { return; } + project.getService(CdsCodeStyleSettingsService.class).updateSettingsFile(); lspServerStarter.ensureServerStarted(new CdsLspServerDescriptor(project, CdsLanguage.LABEL)); } diff --git a/src/main/kotlin/com/sap/cap/cds/intellij/lifecycle/ProjectLifecycleListener.kt b/src/main/kotlin/com/sap/cap/cds/intellij/lifecycle/ProjectLifecycleListener.kt index 5a6d824..255d038 100644 --- a/src/main/kotlin/com/sap/cap/cds/intellij/lifecycle/ProjectLifecycleListener.kt +++ b/src/main/kotlin/com/sap/cap/cds/intellij/lifecycle/ProjectLifecycleListener.kt @@ -9,8 +9,6 @@ class ProjectLifecycleListener : ProjectActivity { val service = project.getService(CdsCodeStyleSettingsService::class.java) if (service.isSettingsFilePresent) { service.updateProjectSettingsFromFile() - } else { - service.updateSettingsFile() } } } \ No newline at end of file diff --git a/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceProjectSettingsTest.java b/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceProjectSettingsTest.java index 071249e..f30896d 100644 --- a/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceProjectSettingsTest.java +++ b/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceProjectSettingsTest.java @@ -67,19 +67,37 @@ public void testInvalidPrettierJson() { // Direction settings → .cdsprettier.json + // TODO test project open with non-project settings → no .cdsprettier.json + public void testProjectOpenedWithDefaultSettings_noCdsPrettierJsonCreation() throws IOException { openProject(); assertFalse(prettierJson.exists()); } - public void testSettingChanged() throws IOException { + public void testSettingChanged_createsPrettierJsonOnlyIfCdsEditorOpen() throws IOException { + CodeStyleSettingsManager codeStyleSettingsManager = CodeStyleSettingsManager.getInstance(project); + openProject(); getCdsCodeStyleSettings().tabSize = 42; - CodeStyleSettingsManager.getInstance(project).notifyCodeStyleSettingsChanged(); + codeStyleSettingsManager.notifyCodeStyleSettingsChanged(); + assertFalse(prettierJson.exists()); + + createCdsFile(); + openCdsFile(); + codeStyleSettingsManager.notifyCodeStyleSettingsChanged(); assertTrue(prettierJson.exists()); assertEquals(42, new JSONObject(readPrettierJson()).get("tabSize")); } + public void testSettingChangedWithExistingCdsPrettierJson_updatesFile() throws IOException { + openProject(); + createPrettierJson(); + writePrettierJson("{}"); + getCdsCodeStyleSettings().tabSize = 42; + CodeStyleSettingsManager.getInstance(project).notifyCodeStyleSettingsChanged(); + assertEquals(42, new JSONObject(readPrettierJson()).get("tabSize")); + } + public void testWriteOnlyLoadedOrNonDefaultOptions() throws Exception { createPrettierJson(); writePrettierJson("{ \"tabSize\": %d, \"alignAs\": %b }".formatted(defaults.tabSize, !defaults.alignAs)); diff --git a/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceTestBase.java b/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceTestBase.java index 1b846fc..70fa1a7 100644 --- a/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceTestBase.java +++ b/src/test/java/com/sap/cap/cds/intellij/codestyle/CdsCodeStyleSettingsServiceTestBase.java @@ -2,6 +2,7 @@ import com.intellij.application.options.CodeStyle; import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -23,6 +24,9 @@ @SuppressWarnings("NewClassNamingConvention") public class CdsCodeStyleSettingsServiceTestBase extends HeavyPlatformTestCase { + + private static final String SOME_CDS = "a.cds"; + protected CdsCodeStyleSettings defaults; protected Project project; protected File prettierJson; @@ -69,6 +73,14 @@ protected void createPrettierJson() { } } + protected void createCdsFile() { + try { + WriteAction.computeAndWait(() -> projectDirVFile.findOrCreateChildData(this, SOME_CDS)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + protected void deletePrettierJson() throws IOException { refreshVfsForFile(prettierJson, false); WriteAction.runAndWait(() -> getVFile(prettierJson).delete(this)); @@ -112,6 +124,11 @@ protected void openProject() { }); } + protected void openCdsFile() { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(getVFile(projectDir.resolve(SOME_CDS).toFile()), false); + } + @NotNull protected CdsCodeStyleSettings getCdsCodeStyleSettings() { return CodeStyle.getSettings(project).getCustomSettings(CdsCodeStyleSettings.class);