@@ -9,17 +9,15 @@ import com.intellij.openapi.editor.event.CaretEvent
99import com.intellij.openapi.editor.event.CaretListener
1010import com.intellij.openapi.editor.event.EditorFactoryEvent
1111import com.intellij.openapi.editor.event.EditorFactoryListener
12- import com.intellij.openapi.editor.markup.HighlighterLayer
13- import com.intellij.openapi.editor.markup.HighlighterTargetArea
14- import com.intellij.openapi.editor.markup.RangeHighlighter
15- import com.intellij.openapi.editor.markup.TextAttributes
12+ import com.intellij.openapi.editor.markup.*
1613import com.intellij.openapi.fileEditor.FileEditorManager
1714import com.intellij.openapi.fileEditor.FileEditorManagerListener
1815import com.intellij.openapi.fileEditor.TextEditor
1916import com.intellij.openapi.project.Project
2017import com.intellij.openapi.project.ProjectManager
2118import com.intellij.openapi.project.ProjectManagerListener
2219import com.intellij.openapi.vfs.VirtualFile
20+ import com.intellij.platform.diagnostic.telemetry.EDT
2321import com.intellij.ui.JBColor
2422import com.intellij.util.io.await
2523import com.intellij.util.io.awaitExit
@@ -73,6 +71,12 @@ class EthersyncServiceImpl(
7371 }
7472 }
7573
74+ for (editor in FileEditorManager .getInstance(project).allEditors) {
75+ if (editor is TextEditor ) {
76+ editor.editor.caretModel.addCaretListener(caretListener)
77+ }
78+ }
79+
7680 EditorFactory .getInstance().addEditorFactoryListener(object : EditorFactoryListener {
7781 override fun editorCreated (event : EditorFactoryEvent ) {
7882 event.editor.caretModel.addCaretListener(caretListener)
@@ -83,8 +87,8 @@ class EthersyncServiceImpl(
8387 }
8488 }, project)
8589
86- bus.subscribe( ProjectManager . TOPIC , object : ProjectManagerListener {
87- override fun projectClosing (project : Project ) {
90+ ProjectManager .getInstance().addProjectManagerListener(project , object : ProjectManagerListener {
91+ override fun projectClosingBeforeSave (project : Project ) {
8892 if (clientProcess != null ) {
8993 cs.launch {
9094 clientProcess!! .destroy()
@@ -122,15 +126,21 @@ class EthersyncServiceImpl(
122126
123127 val notifier = project.messageBus.syncPublisher(DaemonOutputNotifier .CHANGE_ACTION_TOPIC )
124128
125- val stdout = BufferedReader (InputStreamReader (daemonProcess.inputStream))
126- stdout.use {
127- while (true ) {
128- val line = stdout.readLineAsync() ? : break ;
129- LOG .trace(line)
130- notifier.logOutput(line)
129+ cs.launch {
130+ val stdout = BufferedReader (InputStreamReader (daemonProcess.inputStream))
131+ stdout.use {
132+ while (true ) {
133+ val line = stdout.readLineAsync() ? : break ;
134+ LOG .trace(line)
135+ cs.launch {
136+ withContext(Dispatchers .EDT ) {
137+ notifier.logOutput(line)
138+ }
139+ }
131140
132- if (line.contains(" Others can connect with" )) {
133- launchEthersyncClient(socket, projectDirectory)
141+ if (line.contains(" Others can connect with" )) {
142+ launchEthersyncClient(socket, projectDirectory)
143+ }
134144 }
135145 }
136146 }
@@ -142,17 +152,23 @@ class EthersyncServiceImpl(
142152 while (true ) {
143153 val line = stderr.readLineAsync() ? : break ;
144154 LOG .trace(line)
145- notifier.logOutput(line)
155+ cs.launch {
156+ withContext(Dispatchers .EDT ) {
157+ notifier.logOutput(line)
158+ }
159+ }
146160 }
147161 }
148162
149- notifier.logOutput(" ethersync exited with exit code: " + daemonProcess.exitValue())
163+ withContext(Dispatchers .EDT ) {
164+ notifier.logOutput(" ethersync exited with exit code: " + daemonProcess.exitValue())
165+ }
150166 }
151167 }
152168 }
153169
154170 private fun createProtocolHandler (): EthersyncEditorProtocol {
155- val highlighter = LinkedList < RangeHighlighter >()
171+ val highlighter = HashMap < String , List < RangeHighlighter > >()
156172
157173 return object : EthersyncEditorProtocol {
158174 override fun cursor (cursorEvent : CursorEvent ) {
@@ -169,20 +185,24 @@ class EthersyncServiceImpl(
169185 synchronized(highlighter) {
170186 val markupModel = editor.markupModel
171187
172- for (hl in highlighter) {
173- markupModel.removeHighlighter(hl)
188+ val previous = highlighter.remove(cursorEvent.userId)
189+ if (previous != null ) {
190+ for (hl in previous) {
191+ markupModel.removeHighlighter(hl)
192+ }
174193 }
175- highlighter.clear()
176194
195+ val newHighlighter = LinkedList <RangeHighlighter >()
177196 for (range in cursorEvent.ranges) {
178197 val startPosition = editor.logicalPositionToOffset(LogicalPosition (range.start.line, range.start.character))
179198 val endPosition = editor.logicalPositionToOffset(LogicalPosition (range.end.line, range.end.character))
180199
181200 val textAttributes = TextAttributes ().apply {
182- backgroundColor = JBColor (JBColor .YELLOW , JBColor .DARK_GRAY )
201+ // foregroundColor = JBColor(JBColor.YELLOW, JBColor.DARK_GRAY)
202+
183203 // TODO: unclear which is the best effect type
184- // effectType = EffectType.LINE_UNDERSCORE
185- // effectColor = JBColor(JBColor.YELLOW, JBColor.DARK_GRAY)
204+ effectType = EffectType .ROUNDED_BOX
205+ effectColor = JBColor (JBColor .YELLOW , JBColor .DARK_GRAY )
186206 }
187207
188208 val hl = markupModel.addRangeHighlighter(
@@ -192,9 +212,13 @@ class EthersyncServiceImpl(
192212 textAttributes,
193213 HighlighterTargetArea .EXACT_RANGE
194214 )
215+ if (cursorEvent.name != null ) {
216+ hl.errorStripeTooltip = cursorEvent.name
217+ }
195218
196- highlighter .add(hl)
219+ newHighlighter .add(hl)
197220 }
221+ highlighter[cursorEvent.userId] = newHighlighter
198222 }
199223 }
200224 }
0 commit comments