@@ -15,11 +15,19 @@ import java.nio.file.Files
1515import java.nio.file.Path
1616import java.util.stream.Collectors
1717import kotlin.io.path.*
18+ import kotlin.time.Duration
19+ import kotlin.time.Duration.Companion.milliseconds
20+
21+ private const val upToDateNotificationDuration = 1500
1822
1923class CodeStyleSyncActivity : ProjectActivity {
24+
2025 override suspend fun execute (project : Project ) {
26+ println (" Syncing code style..." )
27+
2128 try {
2229 syncCodeStyle()
30+ println (" Code style sync complete" )
2331 } catch (e: Exception ) {
2432 printlnError(" Failed to sync code style: $e " )
2533 }
@@ -30,7 +38,7 @@ class CodeStyleSyncActivity : ProjectActivity {
3038
3139 if (config.state.repoUrl.isBlank()) {
3240 showNotification(
33- " Repository URL is not configured. Please set it in Settings | Tools | Mold." ,
41+ " Repository URL is not configured. Please set it in Settings -> Tools -> Mold." ,
3442 NotificationType .ERROR
3543 )
3644 return
@@ -39,7 +47,6 @@ class CodeStyleSyncActivity : ProjectActivity {
3947 val tempDir = Files .createTempDirectory(" maxxton-codestyle" )
4048
4149 try {
42- // Use config.state.repoUrl instead of hardcoded value
4350 val process = ProcessBuilder ()
4451 .command(" git" , " clone" , " --depth" , " 1" , config.state.repoUrl.trim(), tempDir.toString())
4552 .start()
@@ -53,48 +60,60 @@ class CodeStyleSyncActivity : ProjectActivity {
5360 throw IllegalStateException (" Git clone failed" )
5461 }
5562
56- // Get IntelliJ config directory
57- val configDir = getConfigDir() ? : throw IllegalStateException (" Could not find IntelliJ config directory" )
63+ updateConfigFiles(tempDir)
64+ } finally {
65+ tempDir.toFile().deleteRecursively()
66+ }
67+ }
5868
59- // Setup directories
60- val codestyleDir = configDir.resolve(" codestyles" ).apply { createDirectories() }
61- val inspectionsDir = configDir.resolve(" inspection" ).apply { createDirectories() }
62- val optionsDir = configDir.resolve(" options" ).apply { createDirectories() }
69+ private fun updateConfigFiles (tempDir : Path ) {
70+ // Get IntelliJ config directory
71+ val configDir = getConfigDir() ? : throw IllegalStateException (" Could not find IntelliJ config directory" )
6372
64- // Copy files
65- var hasChanged = copyIfDifferent(
66- tempDir.resolve(" intellij/MaxxtonCodeStyle.xml" ),
67- codestyleDir.resolve(" MaxxtonCodeStyle.xml" )
68- )
73+ // Setup directories
74+ val codestyleDir = configDir.resolve(" codestyles" ).apply { createDirectories() }
75+ val inspectionsDir = configDir.resolve(" inspection" ).apply { createDirectories() }
76+ val optionsDir = configDir.resolve(" options" ).apply { createDirectories() }
6977
70- hasChanged = hasChanged || copyIfDifferent(
71- tempDir.resolve(" intellij/MaxxtonInspections.xml" ),
72- inspectionsDir.resolve(" MaxxtonInspections.xml" )
73- )
78+ // Copy files
79+ val changes = mutableListOf<String >()
7480
75- if (hasChanged) {
76- showNotification(" Updating IDE settings..." )
77- updateCodeStyleSchemes(optionsDir)
78- updateInspections(optionsDir)
79- showRestartNotification()
80- } else {
81- showNotification(" IDE settings are up to date!" )
82- }
83- } finally {
84- tempDir.toFile().deleteRecursively()
81+ if (copyIfDifferent(tempDir.resolve(" intellij/MaxxtonCodeStyle.xml" ), codestyleDir.resolve(" MaxxtonCodeStyle.xml" ))) {
82+ changes.add(" MaxxtonCodeStyle.xml" )
83+ }
84+
85+ if (copyIfDifferent(tempDir.resolve(" intellij/MaxxtonInspections.xml" ), inspectionsDir.resolve(" MaxxtonInspections.xml" ))) {
86+ changes.add(" MaxxtonInspections.xml" )
87+ }
88+
89+ if (changes.isNotEmpty()) {
90+ updateCodeStyleSchemes(optionsDir)
91+ updateInspections(optionsDir)
92+ showRestartNotification(changes)
93+ } else {
94+ showNotification(" IDE Config is up-to-date!" , NotificationType .INFORMATION , upToDateNotificationDuration.milliseconds)
8595 }
8696 }
8797
88- private fun showNotification (content : String , type : NotificationType = NotificationType .INFORMATION ) {
98+ private fun showNotification (content : String , type : NotificationType = NotificationType .INFORMATION , duration : Duration = Duration . ZERO ) {
8999 ApplicationManager .getApplication().invokeLater {
90100 val notification = NotificationGroupManager .getInstance()
91101 .getNotificationGroup(" Mold" )
92102 .createNotification(content, type)
103+
93104 notification.notify(null )
105+
106+ // auto-expire the notification when a duration is specified
107+ if (duration.inWholeMilliseconds > 0 ) {
108+ ApplicationManager .getApplication().executeOnPooledThread {
109+ Thread .sleep(duration.inWholeMilliseconds)
110+ notification.expire()
111+ }
112+ }
94113 }
95114 }
96115
97- private fun showRestartNotification () {
116+ private fun showRestartNotification (changes : List < String > ) {
98117 ApplicationManager .getApplication().invokeLater {
99118 val notification = NotificationGroupManager .getInstance()
100119 .getNotificationGroup(" Mold" )
@@ -111,6 +130,15 @@ class CodeStyleSyncActivity : ProjectActivity {
111130 }
112131 })
113132
133+ if (changes.isNotEmpty()) {
134+ notification.addAction(object : NotificationAction (" View changes" ) {
135+ override fun actionPerformed (e : AnActionEvent , notification : Notification ) {
136+ notification.expire()
137+ showNotification(" Updated files: ${changes.joinToString(" , " )} " )
138+ }
139+ })
140+ }
141+
114142 notification.notify(null )
115143 }
116144 }
@@ -181,4 +209,4 @@ class CodeStyleSyncActivity : ProjectActivity {
181209 """ .trimIndent()
182210 editorFile.writeText(content)
183211 }
184- }
212+ }
0 commit comments