Skip to content

Commit 964e24e

Browse files
authored
Merge pull request #24 from Traben-0/main
Refactor, added settings, several folding improvements, enhanced condition checking, enhanced jump action, kotlin k2 fix, formatting highlights
2 parents cac3db1 + 508ed2f commit 964e24e

19 files changed

+772
-284
lines changed

src/main/kotlin/org/polyfrost/intelliprocessor/action/PreprocessorFileJumpAction.kt

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@ package org.polyfrost.intelliprocessor.action
33
import com.intellij.openapi.actionSystem.AnActionEvent
44
import com.intellij.openapi.actionSystem.LangDataKeys
55
import com.intellij.openapi.actionSystem.PlatformDataKeys
6+
import com.intellij.openapi.editor.Editor
7+
import com.intellij.openapi.editor.ScrollType
68
import com.intellij.openapi.fileEditor.FileEditorManager
79
import com.intellij.openapi.fileEditor.TextEditor
810
import com.intellij.openapi.project.DumbAwareAction
911
import com.intellij.openapi.project.Project
1012
import com.intellij.openapi.vfs.VfsUtil
13+
import com.intellij.psi.PsiFile
1114
import com.intellij.psi.PsiManager
1215
import org.polyfrost.intelliprocessor.utils.*
16+
import org.polyfrost.intelliprocessor.utils.PreprocessorVersion.Companion.preprocessorMainVersion
1317
import java.nio.file.Path
1418
import kotlin.io.path.relativeToOrNull
1519

16-
class PreprocessorFileJumpAction : DumbAwareAction() {
20+
open class PreprocessorFileJumpAction : DumbAwareAction() {
1721

1822
private companion object {
1923
private const val GROUP_ID = "Jump Failure"
@@ -32,7 +36,7 @@ class PreprocessorFileJumpAction : DumbAwareAction() {
3236
val rootDirectory = findModuleDirForFile(currentPsiFile)
3337
?.toPath()
3438
?: return warning(project, "Could not find module directory for file")
35-
val mainVersion = MainProject.get(currentPsiFile)
39+
val mainVersion = currentPsiFile.preprocessorMainVersion
3640
?: return warning(project, "Could not find mainProject. Is this a preprocessor project?")
3741
val currentlyEditingFile = currentPsiFile.virtualFile?.toNioPath()
3842
?: return warning(project, "Could not find file on disk")
@@ -55,8 +59,12 @@ class PreprocessorFileJumpAction : DumbAwareAction() {
5559
val ideView = LangDataKeys.IDE_VIEW.getData(e.dataContext)
5660
?: return warning(project, "Could not find IDE view")
5761

58-
val caret = editor.caretModel.currentCaret.visualPosition
59-
SourceSetFileDialog(project, targets) { selected ->
62+
val caret = editor.caretModel.currentCaret.offset
63+
64+
// For if the caret is inside a preprocessor conditional block, test each target version against the conditions
65+
val foundConditionContext = testTargetsAgainstPreprocessorConditions(currentPsiFile, editor, targets)
66+
67+
SourceSetFileDialog(project, targets, foundConditionContext) { selected ->
6068
val virtualFile = VfsUtil.findFile(rootDirectory.resolve(selected.toRelativePath()), true)
6169
if (virtualFile == null) {
6270
warning(
@@ -76,13 +84,28 @@ class PreprocessorFileJumpAction : DumbAwareAction() {
7684
ideView.selectElement(psiFile)
7785
val newEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile)
7886
if (newEditor is TextEditor) {
79-
newEditor.editor.caretModel.moveToVisualPosition(caret)
87+
newEditor.editor.caretModel.moveToOffset(caret)
88+
newEditor.editor.scrollingModel.scrollToCaret(ScrollType.CENTER)
8089
} else {
8190
warning(project, "Could not set cursor for non-text file")
8291
}
8392
}.show()
8493
}
8594

95+
// If the caret is inside a preprocessor conditional block, test each target version against the conditions there
96+
private fun testTargetsAgainstPreprocessorConditions(
97+
file: PsiFile,
98+
editor: Editor,
99+
targets: List<SourceSetFile>
100+
): Boolean {
101+
val selectedPos = editor.caretModel.currentCaret.offset
102+
val conditions = PreprocessorConditions.findEnclosingConditionsOrNull(selectedPos, file)
103+
if (conditions != null) {
104+
targets.forEach { it.metOpeningCondition = conditions.testVersion(it.version) }
105+
}
106+
return conditions != null
107+
}
108+
86109
private fun getSourceSetFrom(path: List<Path>, mainVersion: String, rootDirectory: Path): SourceSetFile? {
87110
if (path.size < 4) {
88111
return null
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package org.polyfrost.intelliprocessor.config
2+
3+
import com.intellij.openapi.options.Configurable
4+
import javax.swing.BoxLayout
5+
import javax.swing.JCheckBox
6+
import javax.swing.JComponent
7+
import javax.swing.JLabel
8+
import javax.swing.JPanel
9+
import javax.swing.border.EtchedBorder
10+
import javax.swing.border.TitledBorder
11+
12+
class PluginConfigurable : Configurable {
13+
private lateinit var panel: JPanel
14+
private lateinit var foldInactiveBlocksByDefaultCheckbox: JCheckBox
15+
private lateinit var foldAllBlocksByDefaultCheckbox: JCheckBox
16+
private lateinit var inspectionHighlightNonIndentedNestedIfsCheckbox: JCheckBox
17+
private lateinit var inspectionHighlightCommentsNotMatchingIfIndentsCheckbox: JCheckBox
18+
private lateinit var hideUnmatchedVersionsCheckbox: JCheckBox
19+
private lateinit var addPreprocessorCommentOnEnterCheckbox: JCheckBox
20+
21+
22+
override fun getDisplayName(): String = "IntelliProcessor"
23+
24+
override fun createComponent(): JComponent {
25+
26+
// Setup components
27+
28+
fun <J : JComponent> J.tooltip(str: String): J = apply { toolTipText = str }
29+
30+
foldInactiveBlocksByDefaultCheckbox = JCheckBox("Fold inactive preprocessor blocks by default")
31+
.tooltip("Automatically folds preprocessor blocks that are conditionally inactive. (E.G. 'MC>=1.20' blocks in a 1.19 file)")
32+
33+
foldAllBlocksByDefaultCheckbox = JCheckBox("Fold all preprocessor blocks by default").apply {
34+
addChangeListener { event ->
35+
// Disable the "fold inactive blocks" option if "fold all blocks" is enabled
36+
foldInactiveBlocksByDefaultCheckbox.isEnabled = !(event.source as JCheckBox).isSelected
37+
}
38+
}
39+
40+
inspectionHighlightNonIndentedNestedIfsCheckbox =
41+
JCheckBox("Highlight non-indented nested \"if\" preprocessor directives (Code clarity)")
42+
.tooltip(
43+
"Highlights nested \"if\" preprocessor directives that are not indented more than their enclosing preprocessor block.\n" +
44+
"\nThis does not break preprocessing, but can help improve code clarity by visually indicating the nested structure of preprocessor blocks."
45+
)
46+
47+
inspectionHighlightCommentsNotMatchingIfIndentsCheckbox =
48+
JCheckBox("Highlight preprocessor comments not matching their \"if\"'s indent (Code clarity)")
49+
.tooltip(
50+
"Highlights preprocessor comments whose indent does not match the indent of the corresponding \"if\" directive.\n" +
51+
"\nThis does not break preprocessing, but can help improve code clarity by visually linking preprocessor comments to their corresponding \"if\" directives."
52+
)
53+
54+
hideUnmatchedVersionsCheckbox = JCheckBox("Hide results that do not meet preprocessor conditions at the caret")
55+
.tooltip("Hides version results in the 'Jump To Pre-Processed File' dialog that do not match the current file's preprocessor conditions found at the caret position.")
56+
57+
addPreprocessorCommentOnEnterCheckbox = JCheckBox("Add preprocessor comment '//$$ ' automatically to new lines in a disabled preprocessor block")
58+
.tooltip("When pressing Enter inside a disabled preprocessor block, automatically adds a preprocessor comment '//$$ ' to the new line.")
59+
60+
// Arrange components
61+
62+
fun titledBlock(str: String, block: JPanel.() -> Unit): JPanel = JPanel().apply {
63+
border = TitledBorder(EtchedBorder(),str)
64+
layout = BoxLayout(this, BoxLayout.Y_AXIS)
65+
block()
66+
}
67+
68+
panel = JPanel()
69+
70+
panel.apply {
71+
layout = BoxLayout(this, BoxLayout.Y_AXIS)
72+
73+
add(titledBlock("Folding") {
74+
add(foldAllBlocksByDefaultCheckbox)
75+
add(foldInactiveBlocksByDefaultCheckbox)
76+
})
77+
78+
add(titledBlock("Formatting") {
79+
add(inspectionHighlightNonIndentedNestedIfsCheckbox)
80+
add(inspectionHighlightCommentsNotMatchingIfIndentsCheckbox)
81+
})
82+
83+
add(titledBlock("Jump To Pre-Processed File Action") {
84+
add(hideUnmatchedVersionsCheckbox)
85+
})
86+
87+
add(titledBlock("Misc") {
88+
add(addPreprocessorCommentOnEnterCheckbox)
89+
})
90+
91+
add(titledBlock("Info") {
92+
add(JLabel("The keybinds can be configured from: Keymap > Plugins > IntelliProcessor"))
93+
})
94+
}
95+
96+
reset()
97+
return panel
98+
}
99+
100+
override fun isModified(): Boolean =
101+
foldAllBlocksByDefaultCheckbox.isSelected != PluginSettings.instance.foldAllBlocksByDefault
102+
|| foldInactiveBlocksByDefaultCheckbox.isSelected != PluginSettings.instance.foldInactiveBlocksByDefault
103+
|| inspectionHighlightNonIndentedNestedIfsCheckbox.isSelected != PluginSettings.instance.inspectionHighlightNonIndentedNestedIfs
104+
|| inspectionHighlightCommentsNotMatchingIfIndentsCheckbox.isSelected != PluginSettings.instance.inspectionHighlightCommentsNotMatchingIfIndents
105+
|| hideUnmatchedVersionsCheckbox.isSelected != PluginSettings.instance.hideUnmatchedVersions
106+
|| addPreprocessorCommentOnEnterCheckbox.isSelected != PluginSettings.instance.addPreprocessorCommentOnEnter
107+
108+
override fun apply() {
109+
PluginSettings.instance.foldAllBlocksByDefault = foldAllBlocksByDefaultCheckbox.isSelected
110+
PluginSettings.instance.foldInactiveBlocksByDefault = foldInactiveBlocksByDefaultCheckbox.isSelected
111+
PluginSettings.instance.inspectionHighlightNonIndentedNestedIfs = inspectionHighlightNonIndentedNestedIfsCheckbox.isSelected
112+
PluginSettings.instance.inspectionHighlightCommentsNotMatchingIfIndents = inspectionHighlightCommentsNotMatchingIfIndentsCheckbox.isSelected
113+
PluginSettings.instance.hideUnmatchedVersions = hideUnmatchedVersionsCheckbox.isSelected
114+
PluginSettings.instance.addPreprocessorCommentOnEnter = addPreprocessorCommentOnEnterCheckbox.isSelected
115+
}
116+
117+
override fun reset() {
118+
foldAllBlocksByDefaultCheckbox.isSelected = PluginSettings.instance.foldAllBlocksByDefault
119+
foldInactiveBlocksByDefaultCheckbox.isSelected = PluginSettings.instance.foldInactiveBlocksByDefault
120+
inspectionHighlightNonIndentedNestedIfsCheckbox.isSelected = PluginSettings.instance.inspectionHighlightNonIndentedNestedIfs
121+
inspectionHighlightCommentsNotMatchingIfIndentsCheckbox.isSelected = PluginSettings.instance.inspectionHighlightCommentsNotMatchingIfIndents
122+
hideUnmatchedVersionsCheckbox.isSelected = PluginSettings.instance.hideUnmatchedVersions
123+
addPreprocessorCommentOnEnterCheckbox.isSelected = PluginSettings.instance.addPreprocessorCommentOnEnter
124+
}
125+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.polyfrost.intelliprocessor.config
2+
3+
import com.intellij.openapi.components.PersistentStateComponent
4+
import com.intellij.openapi.components.Service
5+
import com.intellij.openapi.components.State
6+
import com.intellij.openapi.components.Storage
7+
import com.intellij.openapi.components.service
8+
9+
@State(name = "IntelliProcessor", storages = [Storage("IntelliProcessor.xml")])
10+
@Service
11+
class PluginSettings : PersistentStateComponent<PluginSettings> {
12+
var foldAllBlocksByDefault: Boolean = false
13+
var foldInactiveBlocksByDefault: Boolean = true
14+
var inspectionHighlightNonIndentedNestedIfs: Boolean = true
15+
var inspectionHighlightCommentsNotMatchingIfIndents: Boolean = true
16+
var hideUnmatchedVersions: Boolean = false
17+
var addPreprocessorCommentOnEnter = true
18+
19+
override fun getState(): PluginSettings = this
20+
21+
override fun loadState(state: PluginSettings) {
22+
this.foldAllBlocksByDefault = state.foldAllBlocksByDefault
23+
this.foldInactiveBlocksByDefault = state.foldInactiveBlocksByDefault
24+
this.inspectionHighlightNonIndentedNestedIfs = state.inspectionHighlightNonIndentedNestedIfs
25+
this.inspectionHighlightCommentsNotMatchingIfIndents = state.inspectionHighlightCommentsNotMatchingIfIndents
26+
this.hideUnmatchedVersions = state.hideUnmatchedVersions
27+
this.addPreprocessorCommentOnEnter = state.addPreprocessorCommentOnEnter
28+
}
29+
30+
companion object {
31+
val instance: PluginSettings
32+
get() = service()
33+
34+
// Helper to modify settings and correctly persist changes
35+
fun modify(action: PluginSettings.() -> Unit) {
36+
val settings = PluginSettings().also { it.loadState(instance) }
37+
settings.action()
38+
instance.loadState(settings) // Pass changes back to instance via loadState() to persist
39+
}
40+
}
41+
}

src/main/kotlin/org/polyfrost/intelliprocessor/editor/PreprocessorFolding.kt

Lines changed: 0 additions & 83 deletions
This file was deleted.

0 commit comments

Comments
 (0)