Skip to content

Commit 3a62c7e

Browse files
Add Terminal Shell Command Handler
With the TerminalShellCommandHandler interface it is possible to connect Intellij to a custom ethersync daemon command.
1 parent a151216 commit 3a62c7e

File tree

7 files changed

+104
-29
lines changed

7 files changed

+104
-29
lines changed

build.gradle.kts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,11 @@ version = "1.0-SNAPSHOT"
99

1010
repositories {
1111
mavenCentral()
12-
maven {
13-
url = uri("https://jitpack.io")
14-
}
1512
}
1613

1714
dependencies {
18-
implementation("com.github.Osiris-Team:jansi:2.4.6")
1915
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:0.23.1")
2016
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.23.1")
21-
implementation("org.jsoup:jsoup:1.18.3")
2217
}
2318

2419
// Configure Gradle IntelliJ Plugin

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@ package io.github.ethersync
22

33
interface EthersyncService {
44

5-
fun connectToPeer(peer: String)
5+
fun start(peer: String?)
6+
7+
fun startWithCustomCommandLine(commandLine: String)
68
}

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

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package io.github.ethersync
33
import com.intellij.execution.configurations.GeneralCommandLine
44
import com.intellij.execution.process.ColoredProcessHandler
55
import com.intellij.execution.process.ProcessEvent
6-
import com.intellij.execution.process.ProcessHandler
76
import com.intellij.execution.process.ProcessListener
87
import com.intellij.execution.ui.ConsoleView
98
import com.intellij.openapi.components.Service
@@ -45,7 +44,7 @@ class EthersyncServiceImpl(
4544
) : EthersyncService {
4645

4746
private var launcher: Launcher<RemoteEthersyncClientProtocol>? = null
48-
private var daemonProcess: ProcessHandler? = null
47+
private var daemonProcess: ColoredProcessHandler? = null
4948
private var clientProcess: Process? = null
5049

5150
private val changetracker: Changetracker = Changetracker(project, cs)
@@ -99,36 +98,64 @@ class EthersyncServiceImpl(
9998
}
10099
daemonProcess?.let {
101100
it.detachProcess()
102-
it.destroyProcess()
101+
it.process.destroy()
102+
it.process.awaitExit()
103103
daemonProcess = null
104104
}
105105
changetracker.clear()
106106
cursortracker.clear()
107107
}
108108

109-
override fun connectToPeer(peer: String) {
110-
val projectDirectory = File(project.basePath!!)
111-
val ethersyncDirectory = File(projectDirectory, ".ethersync")
109+
override fun start(peer: String?) {
112110
val socket = "ethersync-%s-socket".format(project.name)
113111

114-
if (!ethersyncDirectory.exists()) {
115-
LOG.debug("Creating ethersync directory")
116-
ethersyncDirectory.mkdir()
117-
}
118-
119112
val cmd = GeneralCommandLine(AppSettings.getInstance().state.ethersyncBinaryPath)
120-
cmd.workDirectory = projectDirectory
113+
121114
cmd.addParameter("daemon")
122-
if (peer.isNotBlank()) {
123-
cmd.addParameter("--peer")
124-
cmd.addParameter(peer)
115+
peer?.let {
116+
if (peer.isNotBlank()) {
117+
cmd.addParameter("--peer")
118+
cmd.addParameter(peer)
119+
}
125120
}
126121
cmd.addParameter("--socket-name")
127122
cmd.addParameter(socket)
128123

124+
launchDaemon(cmd)
125+
}
126+
127+
override fun startWithCustomCommandLine(commandLine: String) {
128+
// TODO: splitting by " " is probably insufficient if there is an argument with spaces in it…
129+
val cmd = GeneralCommandLine(commandLine.split(" "))
130+
131+
launchDaemon(cmd)
132+
}
133+
134+
private fun launchDaemon(cmd: GeneralCommandLine) {
135+
val projectDirectory = File(project.basePath!!)
136+
val ethersyncDirectory = File(projectDirectory, ".ethersync")
137+
cmd.workDirectory = projectDirectory
138+
139+
var socket: String? = null
140+
if (cmd.parametersList.hasParameter("--socket-name") || cmd.parametersList.hasParameter("-s")) {
141+
for (i in 0..(cmd.parametersList.parametersCount - 1)) {
142+
val name = cmd.parametersList[i]
143+
144+
if (name == "--socket-name" || name == "-s") {
145+
socket = cmd.parametersList[i + 1]
146+
break
147+
}
148+
}
149+
}
150+
129151
cs.launch {
130152
shutdown()
131153

154+
if (!ethersyncDirectory.exists()) {
155+
LOG.debug("Creating ethersync directory")
156+
ethersyncDirectory.mkdir()
157+
}
158+
132159
withUiContext {
133160
daemonProcess = ColoredProcessHandler(cmd)
134161

@@ -175,12 +202,21 @@ class EthersyncServiceImpl(
175202
}
176203
}
177204

178-
private fun launchEthersyncClient(socket: String, projectDirectory: File) {
205+
private fun launchEthersyncClient(socket: String?, projectDirectory: File) {
179206
if (clientProcess != null) {
180207
return
181208
}
182209

183210
cs.launch {
211+
val cmd = GeneralCommandLine(AppSettings.getInstance().state.ethersyncBinaryPath)
212+
cmd.workDirectory = projectDirectory
213+
cmd.addParameter("client")
214+
215+
socket?.let {
216+
cmd.addParameter("--socket-name")
217+
cmd.addParameter(it)
218+
}
219+
184220
LOG.info("Starting ethersync client")
185221
// TODO: try catch not existing binary
186222
val clientProcessBuilder = ProcessBuilder(

src/main/kotlin/io/github/ethersync/ConnectToPeerAction.kt renamed to src/main/kotlin/io/github/ethersync/StartEthersyncDaemonAction.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ import com.intellij.openapi.actionSystem.AnActionEvent
55
import com.intellij.openapi.components.service
66
import com.intellij.openapi.ui.Messages
77

8-
class ConnectToPeerAction : AnAction() {
8+
class StartEthersyncDaemonAction : AnAction() {
99

1010
override fun actionPerformed(e: AnActionEvent) {
1111
val project = e.project ?: return
1212

1313
val address = Messages.showInputDialog(
1414
project,
15-
"Provide ethersync peer address",
15+
"Provide ethersync peer address. Leave empty if you want to host a new session.",
1616
"Peer Address",
1717
Icons.PluginIcon
1818
)
1919

2020
if (address != null) {
2121
val service = project.service<EthersyncService>()
2222

23-
service.connectToPeer(address)
23+
service.start(address)
2424
}
2525
}
2626
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.github.ethersync
2+
3+
import com.intellij.execution.Executor
4+
import com.intellij.openapi.components.service
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.terminal.TerminalShellCommandHandler
7+
import io.github.ethersync.settings.AppSettings
8+
9+
class StartEthersyncDaemonTerminalShellCommandHandler : TerminalShellCommandHandler {
10+
override fun execute(
11+
project: Project,
12+
workingDirectory: String?,
13+
localSession: Boolean,
14+
command: String,
15+
executor: Executor
16+
): Boolean {
17+
workingDirectory?.let {
18+
if (project.basePath != it) {
19+
return false
20+
}
21+
}
22+
val ethersyncService = project.service<EthersyncService>()
23+
ethersyncService.startWithCustomCommandLine(command)
24+
return true
25+
}
26+
27+
override fun matches(project: Project, workingDirectory: String?, localSession: Boolean, command: String): Boolean {
28+
val ethersyncBinary = AppSettings.getInstance().state.ethersyncBinaryPath
29+
30+
if (!command.startsWith(ethersyncBinary)) {
31+
return false
32+
}
33+
34+
val rest = command.substring(ethersyncBinary.length).trim()
35+
36+
return rest.startsWith("daemon")
37+
}
38+
}

src/main/kotlin/io/github/ethersync/sync/Changetracker.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Changetracker(
2727
private val cs: CoroutineScope,
2828
) : DocumentListener {
2929

30+
// TODO: remove because that seems brittle…
3031
private val ignoreChangeEvent = AtomicBoolean(false)
3132

3233
private data class FileRevision(

src/main/resources/META-INF/plugin.xml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
id="ethersync"
2929
icon="io.github.ethersync.Icons.PluginIcon"
3030
factoryClass="io.github.ethersync.EthersyncToolWindowFactory"/>
31+
32+
<terminal.shellCommandHandler
33+
implementation="io.github.ethersync.StartEthersyncDaemonTerminalShellCommandHandler"/>
3134
</extensions>
3235

3336
<actions>
3437
<action
35-
id="ConnectToPeerAction"
36-
class="io.github.ethersync.ConnectToPeerAction"
37-
text="Connect to Ethersync Peer"
38-
description="Connect to a running ethersync daemon"
38+
id="StartEthersyncDaemon"
39+
class="io.github.ethersync.StartEthersyncDaemonAction"
40+
text="Code with Ethersync"
41+
description="Connect to a running ethersync daemon or start a new peer"
3942
icon="io.github.ethersync.Icons.PluginIcon">
4043
<add-to-group group-id="ToolsMenu" anchor="first"/>
4144
</action>

0 commit comments

Comments
 (0)