From a2388dbff1563d334deb8c8fe178cbcdfe75ebd6 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Mon, 18 Sep 2017 17:25:54 +0300 Subject: [PATCH] add simplistic code style settings import --- .../manage/CodeStyleConfigurationHandler.kt | 60 ++++++++++++++++++ .../src/META-INF/ExternalSystemExtensions.xml | 1 + .../GradleSettingsImportingTest.java | 45 +++++++++++-- .../gradle-idea-ext.jar | Bin 11278 -> 11394 bytes 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/CodeStyleConfigurationHandler.kt diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/CodeStyleConfigurationHandler.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/CodeStyleConfigurationHandler.kt new file mode 100644 index 000000000000..c5c9bb217928 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/CodeStyleConfigurationHandler.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.service.project.manage + +import com.intellij.openapi.externalSystem.model.project.ConfigurationData +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider +import com.intellij.openapi.project.Project +import com.intellij.psi.codeStyle.CodeStyleSchemes + +/** + * Created by Nikita.Skvortsov + * date: 18.09.2017. + */ +class CodeStyleConfigurationHandler: ConfigurationHandler { + + override fun apply(project: Project, modelsProvider: IdeModifiableModelsProvider, configuration: ConfigurationData) { + val importedSchemeName = "Gradle Imported" + + val codeStyleSettings: Map = configuration.find("codeStyle") as? Map ?: return + val schemes = CodeStyleSchemes.getInstance() + + val existingScheme = schemes.findPreferredScheme(importedSchemeName) + if (existingScheme.name == importedSchemeName) { + schemes.deleteScheme(existingScheme) + } + + val importedScheme = schemes.createNewScheme(importedSchemeName, schemes.defaultScheme) + + codeStyleSettings["indent"]?.let { indentType -> + val indentOptions = importedScheme.codeStyleSettings.indentOptions ?: return@let + when (indentType) { + "tabs" -> { indentOptions.USE_TAB_CHARACTER = true } + "spaces" -> { indentOptions.USE_TAB_CHARACTER = false } + else -> {} // warn? + } + } + + codeStyleSettings["indentSize"]?.let { + val indentOptions = importedScheme.codeStyleSettings.indentOptions ?: return@let + if (it is Number) { + indentOptions.INDENT_SIZE = it.toInt() + } + } + + schemes.currentScheme = importedScheme + } +} \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml index f252a29d7043..20fa7c37f4ab 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml @@ -36,6 +36,7 @@ + diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java index 4ee8f86217f2..d9bde324b662 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java @@ -25,6 +25,9 @@ import com.intellij.openapi.externalSystem.service.project.manage.FacetHandlerEx import com.intellij.openapi.externalSystem.service.project.manage.RunConfigHandlerExtension; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.psi.codeStyle.CodeStyleSettings; import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.junit.runners.Parameterized; @@ -44,14 +47,43 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { return Arrays.asList(new Object[][]{{BASE_GRADLE_VERSION}}); } + + @Test + public void testCodeStyleSettingsImport() throws Exception { + importProject( + "buildscript {\n" + + " dependencies {\n" + + " classpath files('" + getGradlePluginPath() + "')\n" + + " }\n" + + "}\n" + + "apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'\n" + + "idea {\n" + + " project.settings {\n" + + " codeStyle {\n" + + " indent 'tabs'\n" + + " indentSize 3\n" + + " }\n" + + " }\n" + + "}" + ); + + final CodeStyleScheme scheme = CodeStyleSchemes.getInstance().getCurrentScheme(); + final CodeStyleSettings settings = scheme.getCodeStyleSettings(); + + assertEquals("Gradle Imported", scheme.getName()); + assertFalse(scheme.isDefault()); + + assertTrue(settings.getIndentOptions().USE_TAB_CHARACTER); + assertEquals(3, settings.getIndentOptions().INDENT_SIZE); + } + @Test public void testCompilerConfigurationSettingsImport() throws Exception { - final String pathToPlugin = getClass().getResource("/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar").toString(); importProject( "buildscript {\n" + " dependencies {\n" + - " classpath files('" + pathToPlugin + "')\n" + + " classpath files('" + getGradlePluginPath() + "')\n" + " }\n" + "}\n" + "apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'\n" + @@ -86,7 +118,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { @Test public void testApplicationRunConfigurationSettingsImport() throws Exception { - final String pathToPlugin = getClass().getResource("/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar").toString(); final String typeName = "testRunConfig"; TestRunConfigHandlerExtension testExtension = new TestRunConfigHandlerExtension(typeName); @@ -95,7 +126,7 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { importProject( "buildscript {\n" + " dependencies {\n" + - " classpath files('" + pathToPlugin + "')\n" + + " classpath files('" + getGradlePluginPath() + "')\n" + " }\n" + "}\n" + "apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'\n" + @@ -130,7 +161,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { @Test public void testFacetSettingsImport() throws Exception { - final String pathToPlugin = getClass().getResource("/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar").toString(); TestFacetHandlerExtension testExtension = new TestFacetHandlerExtension("testFacet"); Extensions.getRootArea().getExtensionPoint(FacetHandlerExtension.EP_NAME).registerExtension(testExtension); @@ -139,7 +169,7 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { importProject( "buildscript {\n" + " dependencies {\n" + - " classpath files('" + pathToPlugin + "')\n" + + " classpath files('" + getGradlePluginPath() + "')\n" + " }\n" + "}\n" + "apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'\n" + @@ -168,6 +198,9 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { assertEquals("Test Value 2", namedSettings.get("testField")); } + private String getGradlePluginPath() { + return getClass().getResource("/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar").toString(); + } } diff --git a/plugins/gradle/tooling-extension-impl/testData/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar b/plugins/gradle/tooling-extension-impl/testData/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar index 32e75c51024063b173d14942d8bf9c67b3565fed..395fec877a984a11f7ac52ee844d605066735177 100755 GIT binary patch delta 4760 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 U5D_UPh&zv{6|y1<;r|E!AGT!>X#fBK delta 4665 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