Skip to content

Commit 67f9bf4

Browse files
committed
Add Format Enable Setting
1 parent a5ee9de commit 67f9bf4

File tree

9 files changed

+231
-35
lines changed

9 files changed

+231
-35
lines changed

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatPreProcessor.kt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.intellij.psi.util.prevLeafs
3232
import org.domaframework.doma.intellij.psi.SqlBlockComment
3333
import org.domaframework.doma.intellij.psi.SqlTypes
3434
import org.domaframework.doma.intellij.setting.SqlLanguage
35+
import org.domaframework.doma.intellij.state.DomaToolsFunctionEnableSettings
3536
import org.jetbrains.kotlin.psi.psiUtil.startOffset
3637

3738
class SqlFormatPreProcessor : PreFormatProcessor {
@@ -44,6 +45,7 @@ class SqlFormatPreProcessor : PreFormatProcessor {
4445
source: PsiFile,
4546
rangeToReformat: TextRange,
4647
): TextRange {
48+
if (!isEnableFormat()) return rangeToReformat
4749
if (source.language != SqlLanguage.INSTANCE) return rangeToReformat
4850

4951
val visitor = SqlFormatVisitor()
@@ -61,13 +63,17 @@ class SqlFormatPreProcessor : PreFormatProcessor {
6163
val documentLastElement = visitor.lastElement
6264
val documentLastRange = visitor.lastElement?.textRange
6365
if (documentLastElement != null && documentLastRange != null && documentLastRange.endOffset <= rangeToReformat.endOffset) {
64-
if (documentLastElement !is PsiWhiteSpace) {
65-
val textEnd = documentLastElement.endOffset
66-
document.insertString(textEnd, " \n")
67-
} else {
66+
if (documentLastElement is PsiWhiteSpace) {
6867
val textStart = documentLastElement.startOffset
6968
val textEnd = documentLastElement.endOffset
7069
document.replaceString(textStart, textEnd, " \n")
70+
} else if (documentLastElement.elementType == SqlTypes.LINE_COMMENT) {
71+
val textStart = documentLastElement.startOffset
72+
val textEnd = documentLastElement.endOffset
73+
document.replaceString(textStart, textEnd, "${documentLastElement.text} \n")
74+
} else {
75+
val textEnd = documentLastElement.endOffset
76+
document.insertString(textEnd, " \n")
7177
}
7278
}
7379

@@ -111,9 +117,7 @@ class SqlFormatPreProcessor : PreFormatProcessor {
111117
} else {
112118
// Remove spaces after newlines to reset indentation
113119
val nextSibling = it.nextSibling
114-
if (nextSibling.elementType == SqlTypes.LINE_COMMENT) {
115-
document.replaceString(textRangeStart, textRangeEnd, "")
116-
} else if (nextSibling.elementType == SqlTypes.BLOCK_COMMENT) {
120+
if (nextSibling.elementType == SqlTypes.BLOCK_COMMENT) {
117121
removeSpacesAroundNewline(document, it.textRange)
118122
} else if (keywordIndex < replaceKeywordList.size) {
119123
val nextElement = replaceKeywordList[keywordIndex]
@@ -150,6 +154,12 @@ class SqlFormatPreProcessor : PreFormatProcessor {
150154
return rangeToReformat.grown(visitor.replaces.size)
151155
}
152156

157+
private fun isEnableFormat(): Boolean {
158+
val setting = DomaToolsFunctionEnableSettings.getInstance()
159+
val isEnableFormat = setting.state.isEnableSqlFormat
160+
return isEnableFormat
161+
}
162+
153163
private fun removeSpacesAroundNewline(
154164
document: Document,
155165
range: TextRange,

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlFormattingModelBuilder.kt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,33 @@ import com.intellij.psi.codeStyle.CodeStyleSettings
2828
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2929
import org.domaframework.doma.intellij.psi.SqlTypes
3030
import org.domaframework.doma.intellij.setting.SqlLanguage
31+
import org.domaframework.doma.intellij.state.DomaToolsFunctionEnableSettings
3132

32-
@Suppress("ktlint:standard:no-consecutive-comments")
3333
class SqlFormattingModelBuilder : FormattingModelBuilder {
3434
override fun createModel(formattingContext: FormattingContext): FormattingModel {
3535
val codeStyleSettings = formattingContext.codeStyleSettings
36+
val setting = DomaToolsFunctionEnableSettings.getInstance()
37+
val isEnableFormat = setting.state.isEnableSqlFormat
38+
39+
val spacingBuilder =
40+
if (!isEnableFormat) {
41+
SpacingBuilder(codeStyleSettings, SqlLanguage.INSTANCE)
42+
} else {
43+
createSpaceBuilder(codeStyleSettings)
44+
}
45+
val customSpacingBuilder =
46+
if (!isEnableFormat) null else createCustomSpacingBuilder()
47+
3648
return FormattingModelProvider
3749
.createFormattingModelForPsiFile(
3850
formattingContext.containingFile,
3951
SqlBlock(
4052
formattingContext.node,
4153
Wrap.createWrap(WrapType.NONE, false),
4254
Alignment.createAlignment(),
43-
createCustomSpacingBuilder(),
44-
createSpaceBuilder(codeStyleSettings),
55+
customSpacingBuilder,
56+
spacingBuilder,
57+
isEnableFormat,
4558
),
4659
codeStyleSettings,
4760
)

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,21 @@ open class SqlBlock(
5656
alignment: Alignment?,
5757
private val customSpacingBuilder: SqlCustomSpacingBuilder?,
5858
internal val spacingBuilder: SpacingBuilder,
59+
private val enableFormat: Boolean = false,
5960
) : AbstractBlock(
6061
node,
6162
wrap,
6263
alignment,
6364
) {
65+
data class ElementIndent(
66+
var indentLevel: IndentType,
67+
var indentLen: Int,
68+
var groupIndentLen: Int,
69+
)
70+
6471
val blocks = mutableListOf<AbstractBlock>()
6572
open var parentBlock: SqlBlock? = null
6673
open val childBlocks = mutableListOf<SqlBlock>()
67-
68-
open fun setParentGroupBlock(block: SqlBlock?) {
69-
parentBlock = block
70-
parentBlock?.addChildBlock(this)
71-
}
72-
73-
open fun addChildBlock(childBlock: SqlBlock) {
74-
childBlocks.add(childBlock)
75-
}
76-
7774
open val indent: ElementIndent =
7875
ElementIndent(
7976
IndentType.FILE,
@@ -85,8 +82,19 @@ open class SqlBlock(
8582

8683
protected open val pendingCommentBlocks = mutableListOf<SqlBlock>()
8784

85+
protected fun isEnableFormat(): Boolean = enableFormat
86+
87+
open fun setParentGroupBlock(block: SqlBlock?) {
88+
parentBlock = block
89+
parentBlock?.addChildBlock(this)
90+
}
91+
92+
open fun addChildBlock(childBlock: SqlBlock) {
93+
childBlocks.add(childBlock)
94+
}
95+
8896
public override fun buildChildren(): MutableList<AbstractBlock> {
89-
if (isLeaf) return mutableListOf()
97+
if (isLeaf || !isEnableFormat()) return mutableListOf()
9098

9199
var child = node.firstChildNode
92100
var prevNonWhiteSpaceNode: ASTNode? = null
@@ -142,14 +150,14 @@ open class SqlBlock(
142150
childBlock is SqlColumnDefinitionRawGroupBlock ||
143151
childBlock is SqlColumnDefinitionGroupBlock ||
144152
(childBlock is SqlRightPatternBlock && childBlock.isNeedBeforeWhiteSpace(lastGroup)) ||
145-
// 改行があれば残す。無ければ残さない
146153
(
147154
(
148155
childBlock is SqlLineCommentBlock ||
149156
childBlock is SqlBlockCommentBlock
150157
) &&
151158
child.treePrev.text.contains("\n")
152-
)
159+
) ||
160+
(childBlock is SqlElBlockCommentBlock && childBlock.isConditionLoopBlock)
153161

154162
private fun setRightSpace(lastBlock: SqlBlock?) {
155163
val rightBlock = lastBlock as? SqlRightPatternBlock
@@ -665,6 +673,8 @@ open class SqlBlock(
665673
child1: Block?,
666674
child2: Block,
667675
): Spacing? {
676+
if (!isEnableFormat()) return null
677+
668678
// The end of a line comment element is a newline, so just add a space for the indent.
669679
if (child1 is SqlLineCommentBlock) {
670680
if (child2 is SqlBlock) {
@@ -673,12 +683,24 @@ open class SqlBlock(
673683
}
674684

675685
// Do not leave a space after the comment block of the bind variable
676-
if (child1 is SqlElBlockCommentBlock) {
686+
if (child1 is SqlElBlockCommentBlock && child2 !is SqlCommentBlock) {
677687
return Spacing.createSpacing(0, 0, 0, false, 0)
678688
}
679-
// Put a space before the comment block of the bind variable
689+
680690
if (child2 is SqlElBlockCommentBlock) {
681-
return Spacing.createSpacing(1, 1, 1, false, 1)
691+
when (child1) {
692+
is SqlElBlockCommentBlock -> {
693+
val indentLen = child2.indent.indentLen
694+
return Spacing.createSpacing(indentLen, indentLen, 1, false, 0)
695+
}
696+
697+
is SqlWhitespaceBlock -> {
698+
val indentLen = child2.indent.indentLen
699+
return Spacing.createSpacing(indentLen, indentLen, 0, false, 0)
700+
}
701+
702+
else -> return SqlCustomSpacingBuilder.normalSpacing
703+
}
682704
}
683705

684706
if (child1 is SqlWhitespaceBlock) {
@@ -748,6 +770,8 @@ open class SqlBlock(
748770
}
749771

750772
override fun getChildAttributes(newChildIndex: Int): ChildAttributes {
773+
if (!isEnableFormat()) return ChildAttributes(Indent.getNoneIndent(), null)
774+
751775
blocks
752776
.getOrNull(newChildIndex)
753777
?.let {
@@ -761,13 +785,12 @@ open class SqlBlock(
761785
return ChildAttributes(Indent.getNoneIndent(), null)
762786
}
763787

764-
override fun getChildIndent(): Indent? = Indent.getSpaceIndent(4)
788+
override fun getChildIndent(): Indent? =
789+
if (!isEnableFormat()) {
790+
Indent.getSpaceIndent(4)
791+
} else {
792+
Indent.getSpaceIndent(0)
793+
}
765794

766795
override fun isLeaf(): Boolean = myNode.firstChildNode == null
767-
768-
data class ElementIndent(
769-
var indentLevel: IndentType,
770-
var indentLen: Int,
771-
var groupIndentLen: Int,
772-
)
773796
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright Doma Tools Authors
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+
* https://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+
package org.domaframework.doma.intellij.setting
17+
18+
import com.intellij.openapi.options.Configurable
19+
import com.intellij.openapi.options.ConfigurationException
20+
import org.domaframework.doma.intellij.state.DomaToolsFunctionEnableSettings
21+
import java.util.Objects
22+
import javax.swing.JComponent
23+
24+
class DomaToolsConfigurable : Configurable {
25+
private var mySettingsComponent: SettingComponent? = SettingComponent()
26+
27+
override fun getDisplayName(): String = "Doma Tools"
28+
29+
override fun createComponent(): JComponent? = mySettingsComponent?.panel
30+
31+
override fun isModified(): Boolean {
32+
val state: DomaToolsFunctionEnableSettings.State =
33+
Objects.requireNonNull(DomaToolsFunctionEnableSettings.getInstance().getState())
34+
return mySettingsComponent?.enableFormat != state.isEnableSqlFormat
35+
}
36+
37+
@Throws(ConfigurationException::class)
38+
override fun apply() {
39+
val state: DomaToolsFunctionEnableSettings.State =
40+
Objects.requireNonNull(DomaToolsFunctionEnableSettings.getInstance().getState())
41+
state.isEnableSqlFormat = mySettingsComponent?.enableFormat == true
42+
}
43+
44+
override fun reset() {
45+
val state: DomaToolsFunctionEnableSettings.State =
46+
Objects.requireNonNull(DomaToolsFunctionEnableSettings.getInstance().getState())
47+
mySettingsComponent?.enableFormat = state.isEnableSqlFormat
48+
}
49+
50+
override fun disposeUIResources() {
51+
mySettingsComponent = null
52+
}
53+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Doma Tools Authors
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+
* https://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+
package org.domaframework.doma.intellij.setting
17+
18+
import com.intellij.ui.components.JBCheckBox
19+
import com.intellij.ui.components.JBLabel
20+
import com.intellij.util.ui.FormBuilder
21+
import org.domaframework.doma.intellij.bundle.MessageBundle
22+
import javax.swing.JPanel
23+
24+
class SettingComponent {
25+
val panel: JPanel?
26+
private val enableFormatCheckBox = JBCheckBox()
27+
28+
init {
29+
this.panel =
30+
FormBuilder
31+
.createFormBuilder()
32+
.addLabeledComponent(JBLabel(MessageBundle.message("config.enable.sql.format")), enableFormatCheckBox, 1, false)
33+
.addComponentFillVertically(JPanel(), 0)
34+
.panel
35+
}
36+
37+
var enableFormat: Boolean
38+
get() = enableFormatCheckBox.isSelected
39+
set(enabled) {
40+
enableFormatCheckBox.isSelected = enabled
41+
}
42+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Doma Tools Authors
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+
* https://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+
package org.domaframework.doma.intellij.state
17+
18+
import com.intellij.openapi.application.ApplicationManager
19+
import com.intellij.openapi.components.BaseState
20+
import com.intellij.openapi.components.PersistentStateComponent
21+
import com.intellij.openapi.components.State
22+
import com.intellij.openapi.components.Storage
23+
import com.intellij.openapi.components.StoragePathMacros
24+
25+
@State(
26+
name = "org.domaframework.doma",
27+
reloadable = true,
28+
storages = [Storage(StoragePathMacros.WORKSPACE_FILE)],
29+
)
30+
class DomaToolsFunctionEnableSettings : PersistentStateComponent<DomaToolsFunctionEnableSettings.State> {
31+
class State : BaseState() {
32+
var isEnableSqlFormat = false
33+
}
34+
35+
var myState: State = State()
36+
37+
override fun getState(): State = myState
38+
39+
override fun loadState(state: DomaToolsFunctionEnableSettings.State) {
40+
myState = state
41+
}
42+
43+
companion object {
44+
fun getInstance(): DomaToolsFunctionEnableSettings =
45+
ApplicationManager.getApplication().getService(DomaToolsFunctionEnableSettings::class.java)
46+
}
47+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
<extensions defaultExtensionNs="com.intellij">
1919
<postStartupActivity implementation="org.domaframework.doma.intellij.setting.DomaToolStartupActivity"/>
2020

21+
<applicationService
22+
serviceImplementation="org.domaframework.doma.intellij.state.DomaToolsFunctionEnableSettings"/>
23+
<applicationConfigurable groupId="org.domaframework.doma"
24+
instance="org.domaframework.doma.intellij.setting.DomaToolsConfigurable"
25+
displayName="Doma Tools" />
26+
2127
<!-- Gutter -->
2228
<codeInsight.lineMarkerProvider language="JAVA"
2329
implementationClass="org.domaframework.doma.intellij.gutter.dao.DaoMethodProvider"/>

0 commit comments

Comments
 (0)