@@ -16,14 +16,14 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent
16
16
import com.intellij.openapi.fileEditor.FileEditorManagerListener
17
17
import com.intellij.openapi.fileEditor.TextEditor
18
18
import com.intellij.openapi.project.Project
19
+ import com.intellij.openapi.util.Disposer
19
20
import com.intellij.openapi.util.Key
20
21
import com.intellij.openapi.vfs.VirtualFile
21
22
import com.intellij.openapi.vfs.VirtualFileManager
22
23
import com.intellij.openapi.vfs.newvfs.BulkFileListener
23
24
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
24
25
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
25
26
import kotlinx.coroutines.CoroutineScope
26
- import kotlinx.coroutines.delay
27
27
import kotlinx.coroutines.launch
28
28
import org.eclipse.lsp4j.DidChangeTextDocumentParams
29
29
import org.eclipse.lsp4j.DidCloseTextDocumentParams
@@ -46,6 +46,7 @@ class TextDocumentServiceHandler(
46
46
BulkFileListener ,
47
47
DocumentListener ,
48
48
Disposable {
49
+
49
50
init {
50
51
// didOpen & didClose events
51
52
project.messageBus.connect(this ).subscribe(
@@ -68,9 +69,8 @@ class TextDocumentServiceHandler(
68
69
// open files on startup
69
70
cs.launch {
70
71
val fileEditorManager = FileEditorManager .getInstance(project)
71
- fileEditorManager.openFiles .forEach { file ->
72
+ fileEditorManager.selectedFiles .forEach { file ->
72
73
handleFileOpened(file)
73
- delay(100 )
74
74
}
75
75
}
76
76
}
@@ -84,23 +84,33 @@ class TextDocumentServiceHandler(
84
84
}
85
85
ApplicationManager .getApplication().runReadAction {
86
86
FileDocumentManager .getInstance().getDocument(file)?.addDocumentListener(listener)
87
- file.putUserData(KEY_REAL_TIME_EDIT_LISTENER , listener)
88
87
}
89
- }
88
+ file.putUserData(KEY_REAL_TIME_EDIT_LISTENER , listener)
89
+
90
+ Disposer .register(this ) {
91
+ ApplicationManager .getApplication().runReadAction {
92
+ val existingListener = file.getUserData(KEY_REAL_TIME_EDIT_LISTENER )
93
+ if (existingListener != null ) {
94
+ FileDocumentManager .getInstance().getDocument(file)?.removeDocumentListener(existingListener)
95
+ file.putUserData(KEY_REAL_TIME_EDIT_LISTENER , null )
96
+ }
97
+ }
98
+ }
90
99
91
- cs.launch {
92
- AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
93
- toUriString(file)?.let { uri ->
94
- languageServer.textDocumentService.didOpen(
95
- DidOpenTextDocumentParams ().apply {
96
- textDocument = TextDocumentItem ().apply {
97
- this .uri = uri
98
- text = file.inputStream.readAllBytes().decodeToString()
99
- languageId = file.fileType.name.lowercase()
100
- version = file.modificationStamp.toInt()
100
+ cs.launch {
101
+ AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
102
+ toUriString(file)?.let { uri ->
103
+ languageServer.textDocumentService.didOpen(
104
+ DidOpenTextDocumentParams ().apply {
105
+ textDocument = TextDocumentItem ().apply {
106
+ this .uri = uri
107
+ text = file.inputStream.readAllBytes().decodeToString()
108
+ languageId = file.fileType.name.lowercase()
109
+ version = file.modificationStamp.toInt()
110
+ }
101
111
}
102
- }
103
- )
112
+ )
113
+ }
104
114
}
105
115
}
106
116
}
@@ -116,6 +126,7 @@ class TextDocumentServiceHandler(
116
126
textDocument = TextDocumentIdentifier ().apply {
117
127
this .uri = uri
118
128
}
129
+ // TODO: should respect `textDocumentSync.save.includeText` server capability config
119
130
text = document.text
120
131
}
121
132
)
@@ -125,10 +136,12 @@ class TextDocumentServiceHandler(
125
136
}
126
137
127
138
override fun after (events : MutableList <out VFileEvent >) {
128
- cs.launch {
129
- AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
130
- events.filterIsInstance<VFileContentChangeEvent >().forEach { event ->
131
- val document = FileDocumentManager .getInstance().getCachedDocument(event.file) ? : return @forEach
139
+ events.filterIsInstance<VFileContentChangeEvent >().forEach { event ->
140
+ val document = FileDocumentManager .getInstance().getCachedDocument(event.file) ? : return @forEach
141
+
142
+ handleFileOpened(event.file)
143
+ cs.launch {
144
+ AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
132
145
toUriString(event.file)?.let { uri ->
133
146
languageServer.textDocumentService.didChange(
134
147
DidChangeTextDocumentParams ().apply {
@@ -164,17 +177,18 @@ class TextDocumentServiceHandler(
164
177
if (listener != null ) {
165
178
FileDocumentManager .getInstance().getDocument(file)?.removeDocumentListener(listener)
166
179
file.putUserData(KEY_REAL_TIME_EDIT_LISTENER , null )
167
- }
168
- cs.launch {
169
- AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
170
- toUriString(file)?.let { uri ->
171
- languageServer.textDocumentService.didClose(
172
- DidCloseTextDocumentParams ().apply {
173
- textDocument = TextDocumentIdentifier ().apply {
174
- this .uri = uri
180
+
181
+ cs.launch {
182
+ AmazonQLspService .executeAsyncIfRunning(project) { languageServer ->
183
+ toUriString(file)?.let { uri ->
184
+ languageServer.textDocumentService.didClose(
185
+ DidCloseTextDocumentParams ().apply {
186
+ textDocument = TextDocumentIdentifier ().apply {
187
+ this .uri = uri
188
+ }
175
189
}
176
- }
177
- )
190
+ )
191
+ }
178
192
}
179
193
}
180
194
}
@@ -185,10 +199,12 @@ class TextDocumentServiceHandler(
185
199
}
186
200
187
201
private fun handleActiveEditorChange (fileEditor : FileEditor ? ) {
202
+ val editor = (fileEditor as ? TextEditor )?.editor ? : return
203
+ editor.virtualFile?.let { handleFileOpened(it) }
204
+
188
205
// Extract text editor if it's a TextEditor, otherwise null
189
- val editor = (fileEditor as ? TextEditor )?.editor
190
- val textDocumentIdentifier = editor?.let { TextDocumentIdentifier (toUriString(it.virtualFile)) }
191
- val cursorState = editor?.let { getCursorState(it) }
206
+ val textDocumentIdentifier = TextDocumentIdentifier (toUriString(editor.virtualFile))
207
+ val cursorState = getCursorState(editor)
192
208
193
209
val params = mapOf (
194
210
" textDocument" to textDocumentIdentifier,
0 commit comments