@@ -6,6 +6,7 @@ import com.intellij.openapi.vfs.VirtualFile
6
6
import com.intellij.openapi.vfs.newvfs.BulkFileListener
7
7
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
8
8
import com.intellij.ui.EditorNotifications
9
+ import java.util.concurrent.atomic.AtomicLong
9
10
10
11
/* *
11
12
* TabooLib语言文件监听器
@@ -15,45 +16,64 @@ import com.intellij.ui.EditorNotifications
15
16
* @since 1.42
16
17
*/
17
18
object LangFileListener : BulkFileListener {
19
+
20
+ private val lastRefreshTime = AtomicLong (0 )
21
+ private const val REFRESH_DEBOUNCE_MS = 300L // 防抖间隔
18
22
19
23
override fun before (events : List <VFileEvent >) {
20
24
// 文件修改前无需处理
21
25
}
22
26
23
27
override fun after (events : List <VFileEvent >) {
24
28
// 检查是否有语言文件发生变更
25
- if (events.any { LangFiles .isLangFile(it.file) }) {
26
- // 清除受影响文件的缓存
27
- events.forEach { event ->
28
- event.file?.let { file ->
29
- LangParser .clearCache(file)
30
- }
31
- }
32
-
33
- // 更新所有编辑器通知
34
- EditorNotifications .updateAll()
35
-
36
- // 更新所有项目的代码折叠和行标记
37
- updateAllProjects()
29
+ val affectedFiles = events.mapNotNull { it.file }.filter { LangFiles .isLangFile(it) }
30
+ if (affectedFiles.isEmpty()) return
31
+
32
+ // 防抖:避免频繁刷新
33
+ val currentTime = System .currentTimeMillis()
34
+ if (currentTime - lastRefreshTime.get() < REFRESH_DEBOUNCE_MS ) {
35
+ return
36
+ }
37
+ lastRefreshTime.set(currentTime)
38
+
39
+ // 清除受影响文件的缓存
40
+ affectedFiles.forEach { file ->
41
+ LangParser .clearCache(file)
42
+ }
43
+
44
+ // 更新编辑器通知(轻量级操作)
45
+ EditorNotifications .updateAll()
46
+
47
+ // 延迟刷新项目,避免阻塞文件操作
48
+ ApplicationManager .getApplication().invokeLater {
49
+ updateAffectedProjects(affectedFiles)
38
50
}
39
51
}
40
52
41
53
/* *
42
- * 更新所有项目
54
+ * 更新受影响的项目(优化版本)
43
55
*/
44
- private fun updateAllProjects () {
45
- ApplicationManager .getApplication().invokeLater {
46
- val openProjects = com.intellij.openapi.project.ProjectManager .getInstance().openProjects
47
- for (project in openProjects) {
48
- if (! project.isDisposed) {
49
- refreshProject(project)
50
- }
56
+ private fun updateAffectedProjects (affectedFiles : List <VirtualFile >) {
57
+ val projectManager = com.intellij.openapi.project.ProjectManager .getInstance()
58
+ val openProjects = projectManager.openProjects
59
+
60
+ // 只刷新实际包含受影响文件的项目
61
+ for (project in openProjects) {
62
+ if (project.isDisposed) continue
63
+
64
+ val projectBasePath = project.basePath ? : continue
65
+ val hasAffectedFiles = affectedFiles.any { file ->
66
+ file.path.startsWith(projectBasePath)
67
+ }
68
+
69
+ if (hasAffectedFiles) {
70
+ refreshProject(project)
51
71
}
52
72
}
53
73
}
54
74
55
75
/* *
56
- * 刷新项目
76
+ * 刷新项目(优化版本)
57
77
*/
58
78
private fun refreshProject (project : Project ) {
59
79
if (project.isDisposed) return
@@ -63,27 +83,19 @@ object LangFileListener : BulkFileListener {
63
83
val fileEditorManager = com.intellij.openapi.fileEditor.FileEditorManager .getInstance(project)
64
84
val daemonCodeAnalyzer = com.intellij.codeInsight.daemon.DaemonCodeAnalyzer .getInstance(project)
65
85
66
- // 刷新当前打开的所有编辑器
86
+ // 只刷新当前打开的 Kotlin 文件
67
87
fileEditorManager.allEditors.forEach { editor ->
68
88
if (editor is com.intellij.openapi.fileEditor.TextEditor ) {
69
89
val virtualFile = editor.file
70
- if (virtualFile != null && virtualFile.isValid) {
90
+ if (virtualFile != null && virtualFile.isValid && virtualFile.name.endsWith( " .kt " ) ) {
71
91
val psiFile = psiManager.findFile(virtualFile)
72
92
if (psiFile != null ) {
73
- // 强制重新分析整个文件
93
+ // 只重新分析包含 sendLang 调用的文件
74
94
daemonCodeAnalyzer.restart(psiFile)
75
95
}
76
96
}
77
97
}
78
98
}
79
-
80
- // 强制更新折叠区域和行标记
81
- val updateManager = com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl .getInstance(project)
82
- updateManager.setUpdateByTimerEnabled(false ) // 暂时关闭自动更新
83
- updateManager.setUpdateByTimerEnabled(true ) // 重新开启自动更新
84
-
85
- // 刷新所有编辑器
86
- com.intellij.codeInsight.daemon.DaemonCodeAnalyzer .getInstance(project).restart()
87
99
}
88
100
}
89
101
}
0 commit comments