Skip to content

Commit 3862c41

Browse files
Improvements for Cursor Sync
1 parent 22557f8 commit 3862c41

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

src/main/kotlin/io/github/ethersync/EthersyncServiceImpl.kt

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@ import com.intellij.openapi.editor.event.CaretEvent
99
import com.intellij.openapi.editor.event.CaretListener
1010
import com.intellij.openapi.editor.event.EditorFactoryEvent
1111
import 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.*
1613
import com.intellij.openapi.fileEditor.FileEditorManager
1714
import com.intellij.openapi.fileEditor.FileEditorManagerListener
1815
import com.intellij.openapi.fileEditor.TextEditor
1916
import com.intellij.openapi.project.Project
2017
import com.intellij.openapi.project.ProjectManager
2118
import com.intellij.openapi.project.ProjectManagerListener
2219
import com.intellij.openapi.vfs.VirtualFile
20+
import com.intellij.platform.diagnostic.telemetry.EDT
2321
import com.intellij.ui.JBColor
2422
import com.intellij.util.io.await
2523
import 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
}

src/main/kotlin/io/github/ethersync/protocol/CursorEvent.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import com.google.gson.annotations.SerializedName
44
import org.eclipse.lsp4j.Range
55

66
data class CursorEvent(
7+
@SerializedName("userid")
8+
val userId: String,
9+
@SerializedName("name")
10+
val name: String?,
711
@SerializedName("uri")
812
val documentUri: String,
913
@SerializedName("ranges")

0 commit comments

Comments
 (0)