xref: /aosp_15_r20/external/ktfmt/ktfmt_idea_plugin/src/main/kotlin/com/facebook/ktfmt/intellij/KtfmtSettings.kt (revision 5be3f65c8cf0e6db0a7e312df5006e8e93cdf9ec)
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