Skip to content

Commit a00ba59

Browse files
committed
WIP
1 parent 9d0417c commit a00ba59

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed

vscode/src/sorbet.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as vscode from "vscode";
2+
import {
3+
LanguageClient,
4+
ServerOptions,
5+
LanguageClientOptions,
6+
RevealOutputChannelOn,
7+
} from "vscode-languageclient/node";
8+
9+
import { WorkspaceChannel } from "./workspaceChannel";
10+
import { Ruby } from "./ruby";
11+
12+
export default class SorbetClient extends LanguageClient {
13+
constructor(
14+
ruby: Ruby,
15+
workspaceFolder: vscode.WorkspaceFolder,
16+
outputChannel: WorkspaceChannel,
17+
) {
18+
const serverOptions: ServerOptions = {
19+
command: "bundle",
20+
args: ["exec", "srb", "tc", "--lsp"],
21+
options: {
22+
cwd: workspaceFolder.uri.fsPath,
23+
env: ruby.env,
24+
shell: true,
25+
},
26+
};
27+
28+
const clientOptions: LanguageClientOptions = {
29+
documentSelector: [
30+
{ language: "ruby", pattern: `${workspaceFolder.uri.fsPath}/**/*` },
31+
],
32+
workspaceFolder,
33+
diagnosticCollectionName: "sorbet",
34+
outputChannel,
35+
revealOutputChannelOn: RevealOutputChannelOn.Never,
36+
};
37+
38+
super("sorbet", serverOptions, clientOptions);
39+
}
40+
}

vscode/src/workspace.ts

+48-24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
debounce,
1212
} from "./common";
1313
import { WorkspaceChannel } from "./workspaceChannel";
14+
import SorbetClient from "./sorbet";
1415

1516
export class Workspace implements WorkspaceInterface {
1617
public lspClient?: Client;
@@ -22,6 +23,7 @@ export class Workspace implements WorkspaceInterface {
2223
private readonly isMainWorkspace: boolean;
2324
private readonly telemetry: vscode.TelemetryLogger;
2425
private needsRestart = false;
26+
private sorbetClient?: SorbetClient;
2527
#rebaseInProgress = false;
2628
#error = false;
2729

@@ -96,6 +98,10 @@ export class Workspace implements WorkspaceInterface {
9698
await this.lspClient.stop();
9799
await this.lspClient.dispose();
98100
}
101+
if (this.sorbetClient) {
102+
await this.sorbetClient.stop();
103+
await this.sorbetClient.dispose();
104+
}
99105

100106
this.lspClient = new Client(
101107
this.context,
@@ -106,11 +112,17 @@ export class Workspace implements WorkspaceInterface {
106112
this.outputChannel,
107113
this.isMainWorkspace,
108114
);
115+
this.sorbetClient = new SorbetClient(
116+
this.ruby,
117+
this.workspaceFolder,
118+
this.outputChannel,
119+
);
109120

110121
try {
111122
STATUS_EMITTER.fire(this);
112123
await this.lspClient.start();
113124
await this.lspClient.afterStart();
125+
await this.sorbetClient.start();
114126
STATUS_EMITTER.fire(this);
115127

116128
// If something triggered a restart while we were still booting, then now we need to perform the restart since the
@@ -127,6 +139,7 @@ export class Workspace implements WorkspaceInterface {
127139

128140
async stop() {
129141
await this.lspClient?.stop();
142+
await this.sorbetClient?.stop();
130143
}
131144

132145
async restart() {
@@ -138,39 +151,50 @@ export class Workspace implements WorkspaceInterface {
138151
this.error = false;
139152

140153
// If there's no client, then we can just start a new one
141-
if (!this.lspClient) {
142-
return this.start();
143-
}
144-
145-
switch (this.lspClient.state) {
146-
// If the server is still starting, then it may not be ready to handle a shutdown request yet. Trying to send
147-
// one could lead to a hanging process. Instead we set a flag and only restart once the server finished booting
148-
// in `start`
149-
case State.Starting:
150-
this.needsRestart = true;
151-
break;
152-
// If the server is running, we want to stop it, dispose of the client and start a new one
153-
case State.Running:
154-
await this.stop();
155-
await this.lspClient.dispose();
156-
this.lspClient = undefined;
157-
await this.start();
158-
break;
159-
// If the server is already stopped, then we need to dispose it and start a new one
160-
case State.Stopped:
161-
await this.lspClient.dispose();
162-
this.lspClient = undefined;
163-
await this.start();
164-
break;
154+
if (this.lspClient && this.sorbetClient) {
155+
try {
156+
await this.sorbetClient.stop();
157+
await this.sorbetClient.dispose();
158+
} catch (error: any) {
159+
this.outputChannel.error(
160+
`Error restarting the Sorbet server: ${error.message}`,
161+
);
162+
}
163+
this.sorbetClient = undefined;
164+
165+
switch (this.lspClient.state) {
166+
// If the server is still starting, then it may not be ready to handle a shutdown request yet. Trying to send
167+
// one could lead to a hanging process. Instead we set a flag and only restart once the server finished
168+
// booting in `start`
169+
case State.Starting:
170+
this.needsRestart = true;
171+
break;
172+
// If the server is running, we want to stop it, dispose of the client and start a new one
173+
case State.Running:
174+
await this.stop();
175+
await this.lspClient.dispose();
176+
this.lspClient = undefined;
177+
await this.start();
178+
break;
179+
// If the server is already stopped, then we need to dispose it and start a new one
180+
case State.Stopped:
181+
await this.lspClient.dispose();
182+
this.lspClient = undefined;
183+
await this.start();
184+
break;
185+
}
165186
}
166187
} catch (error: any) {
167188
this.error = true;
168189
this.outputChannel.error(`Error restarting the server: ${error.message}`);
169190
}
191+
192+
return this.start();
170193
}
171194

172195
async dispose() {
173196
await this.lspClient?.dispose();
197+
await this.sorbetClient?.dispose();
174198
}
175199

176200
// Install or update the `ruby-lsp` gem globally with `gem install ruby-lsp` or `gem update ruby-lsp`. We only try to

0 commit comments

Comments
 (0)