Skip to content

Commit 261e9f2

Browse files
committed
fix(amazonq): only send textDocument/didOpen for explicitly focused editors
delay does not appear sufficent to satisfy LSP sensitivity to message floods on start (perhaps some weird stdio buffer overflow issue on windows) instead, match observed behavior of VSC/Eclipse and only send editors that have seen focus at least once
1 parent 2a30ddd commit 261e9f2

File tree

1 file changed

+49
-33
lines changed

1 file changed

+49
-33
lines changed

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent
1616
import com.intellij.openapi.fileEditor.FileEditorManagerListener
1717
import com.intellij.openapi.fileEditor.TextEditor
1818
import com.intellij.openapi.project.Project
19+
import com.intellij.openapi.util.Disposer
1920
import com.intellij.openapi.util.Key
2021
import com.intellij.openapi.vfs.VirtualFile
2122
import com.intellij.openapi.vfs.VirtualFileManager
2223
import com.intellij.openapi.vfs.newvfs.BulkFileListener
2324
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
2425
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
2526
import kotlinx.coroutines.CoroutineScope
26-
import kotlinx.coroutines.delay
2727
import kotlinx.coroutines.launch
2828
import org.eclipse.lsp4j.DidChangeTextDocumentParams
2929
import org.eclipse.lsp4j.DidCloseTextDocumentParams
@@ -46,6 +46,7 @@ class TextDocumentServiceHandler(
4646
BulkFileListener,
4747
DocumentListener,
4848
Disposable {
49+
4950
init {
5051
// didOpen & didClose events
5152
project.messageBus.connect(this).subscribe(
@@ -68,9 +69,8 @@ class TextDocumentServiceHandler(
6869
// open files on startup
6970
cs.launch {
7071
val fileEditorManager = FileEditorManager.getInstance(project)
71-
fileEditorManager.openFiles.forEach { file ->
72+
fileEditorManager.selectedFiles.forEach { file ->
7273
handleFileOpened(file)
73-
delay(100)
7474
}
7575
}
7676
}
@@ -86,21 +86,31 @@ class TextDocumentServiceHandler(
8686
FileDocumentManager.getInstance().getDocument(file)?.addDocumentListener(listener)
8787
file.putUserData(KEY_REAL_TIME_EDIT_LISTENER, listener)
8888
}
89-
}
9089

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()
90+
Disposer.register(this) {
91+
ApplicationManager.getApplication().runReadAction {
92+
val listener = file.getUserData(KEY_REAL_TIME_EDIT_LISTENER)
93+
if (listener != null) {
94+
FileDocumentManager.getInstance().getDocument(file)?.removeDocumentListener(listener)
95+
file.putUserData(KEY_REAL_TIME_EDIT_LISTENER, null)
96+
}
97+
}
98+
}
99+
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+
}
101111
}
102-
}
103-
)
112+
)
113+
}
104114
}
105115
}
106116
}
@@ -116,6 +126,7 @@ class TextDocumentServiceHandler(
116126
textDocument = TextDocumentIdentifier().apply {
117127
this.uri = uri
118128
}
129+
// TODO: should respect `textDocumentSync.save.includeText` server capability config
119130
text = document.text
120131
}
121132
)
@@ -125,10 +136,12 @@ class TextDocumentServiceHandler(
125136
}
126137

127138
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 ->
132145
toUriString(event.file)?.let { uri ->
133146
languageServer.textDocumentService.didChange(
134147
DidChangeTextDocumentParams().apply {
@@ -164,17 +177,18 @@ class TextDocumentServiceHandler(
164177
if (listener != null) {
165178
FileDocumentManager.getInstance().getDocument(file)?.removeDocumentListener(listener)
166179
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+
}
175189
}
176-
}
177-
)
190+
)
191+
}
178192
}
179193
}
180194
}
@@ -185,10 +199,12 @@ class TextDocumentServiceHandler(
185199
}
186200

187201
private fun handleActiveEditorChange(fileEditor: FileEditor?) {
202+
val editor = (fileEditor as? TextEditor)?.editor ?: return
203+
editor.virtualFile?.let { handleFileOpened(it) }
204+
188205
// 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)
192208

193209
val params = mapOf(
194210
"textDocument" to textDocumentIdentifier,

0 commit comments

Comments
 (0)