Store selected set of defaults in code style settings (KT-22252)
#KT-22252 In Progress
This commit is contained in:
@@ -60,6 +60,7 @@ public class KotlinCodeStyleSettingsProvider extends CodeStyleSettingsProvider {
|
||||
addWrappingAndBracesTab(settings);
|
||||
addBlankLinesTab(settings);
|
||||
addTab(new ImportSettingsPanelWrapper(settings));
|
||||
addTab(new KotlinSaveStylePanel(settings));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.formatter;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.util.DefaultJDOMExternalizer;
|
||||
import com.intellij.openapi.util.DifferenceFilter;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
|
||||
import com.intellij.psi.codeStyle.arrangement.ArrangementSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.xmlb.XmlSerializer;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings("UnnecessaryFinalOnLocalVariableOrParameter")
|
||||
public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
|
||||
public KotlinCommonCodeStyleSettings() {
|
||||
super(KotlinLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
//<editor-fold desc="Copied and adapted from CommonCodeStyleSettings ">
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
super.readExternal(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
CommonCodeStyleSettings defaultSettings = getDefaultSettings();
|
||||
Set<String> supportedFields = getSupportedFields();
|
||||
if (supportedFields != null) {
|
||||
supportedFields.add("FORCE_REARRANGE_MODE");
|
||||
}
|
||||
//noinspection deprecation
|
||||
DefaultJDOMExternalizer.writeExternal(this, element, new SupportedFieldsDiffFilter(this, supportedFields, defaultSettings));
|
||||
List<Integer> softMargins = getSoftMargins();
|
||||
serializeInto(softMargins, element);
|
||||
|
||||
IndentOptions myIndentOptions = getIndentOptions();
|
||||
if (myIndentOptions != null) {
|
||||
IndentOptions defaultIndentOptions = defaultSettings != null ? defaultSettings.getIndentOptions() : null;
|
||||
Element indentOptionsElement = new Element(INDENT_OPTIONS_TAG);
|
||||
myIndentOptions.serialize(indentOptionsElement, defaultIndentOptions);
|
||||
if (!indentOptionsElement.getChildren().isEmpty()) {
|
||||
element.addContent(indentOptionsElement);
|
||||
}
|
||||
}
|
||||
|
||||
ArrangementSettings myArrangementSettings = getArrangementSettings();
|
||||
if (myArrangementSettings != null) {
|
||||
Element container = new Element(ARRANGEMENT_ELEMENT_NAME);
|
||||
ArrangementUtil.writeExternal(container, myArrangementSettings, myLanguage);
|
||||
if (!container.getChildren().isEmpty()) {
|
||||
element.addContent(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonCodeStyleSettings clone(@NotNull CodeStyleSettings rootSettings) {
|
||||
CommonCodeStyleSettings commonSettings = new KotlinCommonCodeStyleSettings();
|
||||
copyPublicFieldsOwn(this, commonSettings);
|
||||
|
||||
try {
|
||||
Method setRootSettingsMethod = CommonCodeStyleSettings.class.getDeclaredMethod("setRootSettings", CodeStyleSettings.class);
|
||||
setRootSettingsMethod.setAccessible(true);
|
||||
setRootSettingsMethod.invoke(commonSettings, rootSettings);
|
||||
}
|
||||
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
commonSettings.setForceArrangeMenuAvailable(isForceArrangeMenuAvailable());
|
||||
|
||||
IndentOptions indentOptions = getIndentOptions();
|
||||
if (indentOptions != null) {
|
||||
IndentOptions targetIndentOptions = commonSettings.initIndentOptions();
|
||||
targetIndentOptions.copyFrom(indentOptions);
|
||||
}
|
||||
|
||||
ArrangementSettings arrangementSettings = getArrangementSettings();
|
||||
if (arrangementSettings != null) {
|
||||
commonSettings.setArrangementSettings(arrangementSettings.clone());
|
||||
}
|
||||
|
||||
try {
|
||||
Method setRootSettingsMethod = ArraysKt.singleOrNull(
|
||||
CommonCodeStyleSettings.class.getDeclaredMethods(),
|
||||
method -> "setSoftMargins".equals(method.getName()));
|
||||
|
||||
if (setRootSettingsMethod != null) {
|
||||
// Method was introduced in 173
|
||||
setRootSettingsMethod.setAccessible(true);
|
||||
setRootSettingsMethod.invoke(commonSettings, getSoftMargins());
|
||||
}
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
return commonSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof KotlinCommonCodeStyleSettings)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ReflectionUtil.comparePublicNonFinalFields(this, obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CommonCodeStyleSettings other = (CommonCodeStyleSettings) obj;
|
||||
if (!getSoftMargins().equals(other.getSoftMargins())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IndentOptions options = getIndentOptions();
|
||||
if ((options == null && other.getIndentOptions() != null) ||
|
||||
(options != null && !options.equals(other.getIndentOptions()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return arrangementSettingsEqual(other);
|
||||
}
|
||||
|
||||
// SoftMargins.serializeInfo
|
||||
private void serializeInto(@NotNull List<Integer> softMargins, @NotNull Element element) {
|
||||
if (softMargins.size() > 0) {
|
||||
XmlSerializer.serializeInto(this, element);
|
||||
}
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="Copied from CommonCodeStyleSettings">
|
||||
private static final String INDENT_OPTIONS_TAG = "indentOptions";
|
||||
private static final String ARRANGEMENT_ELEMENT_NAME = "arrangement";
|
||||
|
||||
private final Language myLanguage = KotlinLanguage.INSTANCE;
|
||||
|
||||
@Nullable
|
||||
private CommonCodeStyleSettings getDefaultSettings() {
|
||||
return LanguageCodeStyleSettingsProvider.getDefaultCommonSettings(myLanguage);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Set<String> getSupportedFields() {
|
||||
final LanguageCodeStyleSettingsProvider provider = LanguageCodeStyleSettingsProvider.forLanguage(myLanguage);
|
||||
return provider == null ? null : provider.getSupportedFields();
|
||||
}
|
||||
|
||||
private static class SupportedFieldsDiffFilter extends DifferenceFilter<CommonCodeStyleSettings> {
|
||||
private final Set<String> mySupportedFieldNames;
|
||||
|
||||
public SupportedFieldsDiffFilter(
|
||||
final CommonCodeStyleSettings object,
|
||||
Set<String> supportedFiledNames,
|
||||
final CommonCodeStyleSettings parentObject
|
||||
) {
|
||||
super(object, parentObject);
|
||||
mySupportedFieldNames = supportedFiledNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccept(@NotNull Field field) {
|
||||
if (mySupportedFieldNames == null ||
|
||||
mySupportedFieldNames.contains(field.getName())) {
|
||||
return super.isAccept(field);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Can't use super.copyPublicFields because the method is internal in 181
|
||||
private static void copyPublicFieldsOwn(Object from, Object to) {
|
||||
assert from != to;
|
||||
com.intellij.util.ReflectionUtil.copyFields(to.getClass().getFields(), from, to);
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.formatter
|
||||
|
||||
import com.intellij.application.options.CodeStyleAbstractPanel
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings
|
||||
import com.intellij.ui.ListCellRendererWrapper
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import com.intellij.ui.components.panels.HorizontalLayout
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import java.awt.BorderLayout
|
||||
import javax.swing.BorderFactory
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JList
|
||||
import javax.swing.JPanel
|
||||
|
||||
class KotlinSaveStylePanel(settings: CodeStyleSettings) : CodeStyleAbstractPanel(settings) {
|
||||
override fun getRightMargin() = throw UnsupportedOperationException()
|
||||
override fun createHighlighter(scheme: EditorColorsScheme) = throw UnsupportedOperationException()
|
||||
override fun getFileType() = throw UnsupportedOperationException()
|
||||
override fun getPreviewText(): String? = null
|
||||
|
||||
override fun getTabTitle(): String = "Load/Save"
|
||||
|
||||
private data class SaveItem(val label: String, val id: String?)
|
||||
|
||||
private val saveDefaultsComboBox = ComboBox<SaveItem>()
|
||||
private val saveDefaultsItems = listOf(
|
||||
SaveItem("<ide defaults>", null),
|
||||
SaveItem("Current set of defaults", "KOTLIN_OLD_DEFAULTS"),
|
||||
SaveItem(KotlinStyleGuideCodeStyle.CODE_STYLE_TITLE, KotlinStyleGuideCodeStyle.CODE_STYLE_ID)
|
||||
)
|
||||
|
||||
var selectedId: String?
|
||||
get() {
|
||||
val (_, id) = saveDefaultsComboBox.selectedItem as SaveItem
|
||||
return id
|
||||
}
|
||||
set(value) {
|
||||
saveDefaultsComboBox.selectedItem = saveDefaultsItems.firstOrNull { (_, id) -> id == value } ?: saveDefaultsItems.first()
|
||||
}
|
||||
|
||||
private val jPanel = JPanel(BorderLayout()).apply {
|
||||
add(
|
||||
JBScrollPane(
|
||||
JPanel(VerticalLayout(JBUI.scale(5))).apply {
|
||||
border = BorderFactory.createEmptyBorder(UIUtil.DEFAULT_VGAP, 10, UIUtil.DEFAULT_VGAP, 10)
|
||||
add(JPanel(HorizontalLayout(JBUI.scale(5))).apply {
|
||||
saveDefaultsItems.forEach {
|
||||
saveDefaultsComboBox.addItem(it)
|
||||
}
|
||||
|
||||
saveDefaultsComboBox.setRenderer(object : ListCellRendererWrapper<SaveItem>() {
|
||||
override fun customize(list: JList<*>?, value: SaveItem, index: Int, selected: Boolean, hasFocus: Boolean) {
|
||||
setText(value.label)
|
||||
}
|
||||
})
|
||||
|
||||
add(JLabel("Use defaults from:"))
|
||||
add(saveDefaultsComboBox)
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun apply(settings: CodeStyleSettings) {
|
||||
settings.kotlinCustomSettings.CODE_STYLE_DEFAULTS = selectedId
|
||||
settings.kotlinCommonSettings.CODE_STYLE_DEFAULTS = selectedId
|
||||
}
|
||||
|
||||
override fun isModified(settings: CodeStyleSettings): Boolean {
|
||||
return selectedId != settings.kotlinCustomSettings.CODE_STYLE_DEFAULTS ||
|
||||
selectedId != settings.kotlinCommonSettings.CODE_STYLE_DEFAULTS
|
||||
}
|
||||
|
||||
override fun getPanel() = jPanel
|
||||
|
||||
override fun resetImpl(settings: CodeStyleSettings) {
|
||||
selectedId = settings.kotlinCustomSettings.CODE_STYLE_DEFAULTS ?: settings.kotlinCommonSettings.CODE_STYLE_DEFAULTS
|
||||
}
|
||||
|
||||
override fun onSomethingChanged() {
|
||||
// There's no way settings are going to be changed from other tabs without calling resetImpl
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user