1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.facebook.ktfmt.intellij 18 19 import com.facebook.ktfmt.format.Formatter 20 import com.facebook.ktfmt.format.FormattingOptions 21 import com.facebook.ktfmt.intellij.KtfmtSettings.EnabledState.Disabled 22 import com.facebook.ktfmt.intellij.KtfmtSettings.EnabledState.Enabled 23 import com.facebook.ktfmt.intellij.KtfmtSettings.EnabledState.Unknown 24 import com.facebook.ktfmt.intellij.UiFormatterStyle.Meta 25 import com.intellij.openapi.components.BaseState 26 import com.intellij.openapi.components.Service 27 import com.intellij.openapi.components.Service.Level.PROJECT 28 import com.intellij.openapi.components.SimplePersistentStateComponent 29 import com.intellij.openapi.components.State 30 import com.intellij.openapi.components.Storage 31 import com.intellij.openapi.components.service 32 import com.intellij.openapi.diagnostic.thisLogger 33 import com.intellij.openapi.project.Project 34 35 @Service(PROJECT) 36 @State(name = "KtfmtSettings", storages = [Storage("ktfmt.xml")]) 37 internal class KtfmtSettings(private val project: Project) : 38 SimplePersistentStateComponent<KtfmtSettings.State>(State()) { 39 val isUninitialized: Boolean 40 get() = state.enableKtfmt == Unknown 41 42 var uiFormatterStyle: UiFormatterStyle 43 get() = state.uiFormatterStyle 44 set(uiFormatterStyle) { 45 state.uiFormatterStyle = uiFormatterStyle 46 } 47 48 var customFormattingOptions: FormattingOptions 49 get() = 50 FormattingOptions( 51 state.customMaxLineLength, 52 state.customBlockIndent, 53 state.customContinuationIndent, 54 state.customManageTrailingCommas, 55 state.customRemoveUnusedImports, 56 ) 57 set(customFormattingOptions) { 58 state.applyCustomFormattingOptions(customFormattingOptions) 59 } 60 61 var customMaxLineLength: Int 62 get() = state.customMaxLineLength 63 set(maxLineLength) { 64 state.customMaxLineLength = maxLineLength.coerceAtLeast(1) 65 } 66 67 var customBlockIndent: Int 68 get() = state.customBlockIndent 69 set(blockIndent) { 70 state.customBlockIndent = blockIndent.coerceAtLeast(1) 71 } 72 73 var customContinuationIndent: Int 74 get() = state.customContinuationIndent 75 set(continuationIndent) { 76 state.customContinuationIndent = continuationIndent.coerceAtLeast(1) 77 } 78 79 var customManageTrailingCommas: Boolean 80 get() = state.customManageTrailingCommas 81 set(manageTrailingCommas) { 82 state.customManageTrailingCommas = manageTrailingCommas 83 } 84 85 var customRemoveUnusedImports: Boolean 86 get() = state.customRemoveUnusedImports 87 set(removeUnusedImports) { 88 state.customRemoveUnusedImports = removeUnusedImports 89 } 90 91 var isEnabled: Boolean 92 get() = state.enableKtfmt == Enabled 93 set(enabled) { 94 setEnabled(if (enabled) Enabled else Disabled) 95 } 96 setEnablednull97 fun setEnabled(enabled: EnabledState) { 98 state.enableKtfmt = enabled 99 } 100 loadStatenull101 override fun loadState(state: State) { 102 val migrated = loadOrMigrateIfNeeded(state) 103 super.loadState(migrated) 104 } 105 loadOrMigrateIfNeedednull106 private fun loadOrMigrateIfNeeded(state: State): State { 107 val migrationSettings = project.service<KtfmtSettingsMigration>() 108 109 return when (val stateVersion = migrationSettings.stateVersion) { 110 KtfmtSettingsMigration.CURRENT_VERSION -> state 111 1 -> migrationSettings.migrateFromV1ToCurrent(state) 112 else -> { 113 thisLogger().error("Cannot migrate settings from $stateVersion. Using defaults.") 114 State() 115 } 116 } 117 } 118 119 internal enum class EnabledState { 120 Unknown, 121 Enabled, 122 Disabled, 123 } 124 125 internal class State : BaseState() { 126 @Deprecated("Deprecated in V2. Use enableKtfmt instead.") var enabled by string() 127 128 var enableKtfmt by enum<EnabledState>(Unknown) 129 var uiFormatterStyle by enum<UiFormatterStyle>(Meta) 130 131 var customMaxLineLength by property(Formatter.META_FORMAT.maxWidth) 132 var customBlockIndent by property(Formatter.META_FORMAT.blockIndent) 133 var customContinuationIndent by property(Formatter.META_FORMAT.continuationIndent) 134 var customManageTrailingCommas by property(Formatter.META_FORMAT.manageTrailingCommas) 135 var customRemoveUnusedImports by property(Formatter.META_FORMAT.removeUnusedImports) 136 applyCustomFormattingOptionsnull137 fun applyCustomFormattingOptions(formattingOptions: FormattingOptions) { 138 customMaxLineLength = formattingOptions.maxWidth 139 customBlockIndent = formattingOptions.blockIndent 140 customContinuationIndent = formattingOptions.continuationIndent 141 customManageTrailingCommas = formattingOptions.manageTrailingCommas 142 customRemoveUnusedImports = formattingOptions.removeUnusedImports 143 144 incrementModificationCount() 145 } 146 } 147 148 companion object { 149 @JvmStatic getInstancenull150 fun getInstance(project: Project): KtfmtSettings = project.getService(KtfmtSettings::class.java) 151 } 152 } 153