@@ -8,13 +8,14 @@ import com.intellij.openapi.client.ClientProjectSession
8
8
import com.intellij.openapi.diagnostic.thisLogger
9
9
import com.intellij.util.application
10
10
import com.jetbrains.rdserver.terminal.BackendTerminalManager
11
- import io.gitpod.jetbrains.remote.GitpodManager
12
11
import io.gitpod.supervisor.api.Status
13
12
import io.gitpod.supervisor.api.StatusServiceGrpc
14
13
import io.gitpod.supervisor.api.TerminalOuterClass
15
14
import io.gitpod.supervisor.api.TerminalServiceGrpc
15
+ import io.grpc.StatusRuntimeException
16
16
import io.grpc.stub.ClientCallStreamObserver
17
17
import io.grpc.stub.ClientResponseObserver
18
+ import io.grpc.stub.StreamObserver
18
19
import org.jetbrains.plugins.terminal.ShellTerminalWidget
19
20
import org.jetbrains.plugins.terminal.TerminalView
20
21
import java.util.*
@@ -30,6 +31,7 @@ class GitpodTerminalService(session: ClientProjectSession) {
30
31
private val terminalView = TerminalView .getInstance(session.project)
31
32
private val backendTerminalManager = BackendTerminalManager .getInstance(session.project)
32
33
private val terminalServiceFutureStub = TerminalServiceGrpc .newFutureStub(GitpodManager .supervisorChannel)
34
+ private val terminalServiceStub = TerminalServiceGrpc .newStub(GitpodManager .supervisorChannel)
33
35
private val statusServiceStub = StatusServiceGrpc .newStub(GitpodManager .supervisorChannel)
34
36
35
37
init { start() }
@@ -49,7 +51,7 @@ class GitpodTerminalService(session: ClientProjectSession) {
49
51
}
50
52
}
51
53
52
- private fun createSharedTerminalAndExecuteCommand (title : String , command : String ) {
54
+ private fun createSharedTerminalAndExecuteCommand (title : String , command : String ): ShellTerminalWidget ? {
53
55
val registeredTerminals = terminalView.widgets.toMutableList()
54
56
55
57
backendTerminalManager.createNewSharedTerminal(UUID .randomUUID().toString(), title)
@@ -59,8 +61,14 @@ class GitpodTerminalService(session: ClientProjectSession) {
59
61
60
62
widget.terminalTitle.change { applicationTitle = title }
61
63
62
- (widget as ShellTerminalWidget ).executeCommand(command)
64
+ val shellTerminalWidget = widget as ShellTerminalWidget
65
+
66
+ shellTerminalWidget.executeCommand(command)
67
+
68
+ return shellTerminalWidget
63
69
}
70
+
71
+ return null
64
72
}
65
73
66
74
private fun createTerminalsAttachedToTasks (
@@ -120,8 +128,9 @@ class GitpodTerminalService(session: ClientProjectSession) {
120
128
}
121
129
122
130
thisLogger().error(
123
- " gitpod: Got an error while trying to get tasks list from Supervisor. Trying again in on second." ,
124
- throwable
131
+ " gitpod: Got an error while trying to get tasks list from Supervisor. " +
132
+ " Trying again in one second." ,
133
+ throwable
125
134
)
126
135
}
127
136
@@ -150,8 +159,9 @@ class GitpodTerminalService(session: ClientProjectSession) {
150
159
}
151
160
152
161
thisLogger().error(
153
- " gitpod: Got an error while trying to get terminals list from Supervisor. Trying again in on second." ,
154
- throwable
162
+ " gitpod: Got an error while trying to get terminals list from Supervisor. " +
163
+ " Trying again in one second." ,
164
+ throwable
155
165
)
156
166
}
157
167
@@ -164,9 +174,45 @@ class GitpodTerminalService(session: ClientProjectSession) {
164
174
}
165
175
166
176
private fun createAttachedSharedTerminal (supervisorTerminal : TerminalOuterClass .Terminal ) {
167
- createSharedTerminalAndExecuteCommand(
177
+ val shellTerminalWidget = createSharedTerminalAndExecuteCommand(
168
178
supervisorTerminal.title,
169
179
" gp tasks attach ${supervisorTerminal.alias} "
180
+ ) ? : return
181
+
182
+ shellTerminalWidget.addListener {
183
+ terminalServiceFutureStub.shutdown(
184
+ TerminalOuterClass .ShutdownTerminalRequest .newBuilder()
185
+ .setAlias(supervisorTerminal.alias)
186
+ .build()
187
+ )
188
+ }
189
+
190
+ terminalServiceStub.listen(
191
+ TerminalOuterClass .ListenTerminalRequest .newBuilder()
192
+ .setAlias(supervisorTerminal.alias)
193
+ .build(),
194
+ object : StreamObserver <TerminalOuterClass .ListenTerminalResponse > {
195
+ override fun onNext (response : TerminalOuterClass .ListenTerminalResponse ) {
196
+ when {
197
+ response.hasTitle() -> shellTerminalWidget.terminalTitle.change {
198
+ applicationTitle = response.title
199
+ }
200
+ response.hasExitCode() -> shellTerminalWidget.close()
201
+ }
202
+ }
203
+
204
+ override fun onCompleted () = Unit
205
+
206
+ override fun onError (throwable : Throwable ) {
207
+ if (throwable is StatusRuntimeException &&
208
+ (throwable.status.description == " signal: terminated" ||
209
+ throwable.status.description == " signal: killed" )) return
210
+
211
+ thisLogger()
212
+ .error(" gitpod: Got an error while listening to " +
213
+ " '${supervisorTerminal.title} ' terminal." , throwable)
214
+ }
215
+ }
170
216
)
171
217
}
172
218
}
0 commit comments