Skip to content
This repository was archived by the owner on Nov 18, 2022. It is now read-only.

Commit 08a2719

Browse files
authored
Merge pull request #777 from rust-lang/auto-start
Add start and stop commands for RLS
2 parents eb5cdf7 + e3fb9e0 commit 08a2719

File tree

4 files changed

+67
-13
lines changed

4 files changed

+67
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
### Unreleased
22

3+
* Add a Start/Stop the RLS command
4+
* Introduce a `rust-client.autoStartRls` (defaults to true) setting to control the auto-start
5+
behaviour when opening a relevant Rust project file
36
* (!) Don't immediately start server instances for every already opened file
47
* (!) Don't immediately start server instances for newly added workspace folders
58
* Dynamically show progress only for the active client workspace

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@
9494
"title": "Restart the RLS",
9595
"description": "Sometimes, it's just best to try turning it off and on again",
9696
"category": "Rust"
97+
},
98+
{
99+
"command": "rls.start",
100+
"title": "Start the RLS",
101+
"description": "Start the RLS (when rust-client.autoStartRls is false or when manually stopped)",
102+
"category": "Rust"
103+
},
104+
{
105+
"command": "rls.stop",
106+
"title": "Stop the RLS",
107+
"description": "Stop the RLS for a workspace until manually started again",
108+
"category": "Rust"
97109
}
98110
],
99111
"taskDefinitions": [
@@ -187,6 +199,12 @@
187199
"default": false,
188200
"description": "Update the RLS whenever the extension starts up."
189201
},
202+
"rust-client.autoStartRls": {
203+
"type": "boolean",
204+
"default": true,
205+
"description": "Start RLS automatically when opening a file or project.",
206+
"scope": "resource"
207+
},
190208
"rust-client.disableRustup": {
191209
"type": "boolean",
192210
"default": false,

src/configuration.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ export class RLSConfiguration {
118118
return this.configuration.get<string>('rust-client.rlsPath');
119119
}
120120

121+
/**
122+
* Whether RLS should be automaticallystarted when opening a relevant Rust project.
123+
*/
124+
public get autoStartRls(): boolean {
125+
return this.configuration.get<boolean>('rust-client.autoStartRls', true);
126+
}
127+
121128
// Added ignoreChannel for readChannel function. Otherwise we end in an infinite loop.
122129
public rustupConfig(ignoreChannel: boolean = false): RustupConfig {
123130
return {

src/extension.ts

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,21 @@ function onDidChangeActiveTextEditor(editor: TextEditor | undefined) {
100100
const { languageId, uri } = editor.document;
101101

102102
const workspace = clientWorkspaceForUri(uri, {
103-
startIfMissing: languageId === 'rust' || languageId === 'toml',
103+
initializeIfMissing: languageId === 'rust' || languageId === 'toml',
104104
});
105105
if (!workspace) {
106106
return;
107107
}
108108

109109
activeWorkspace = workspace;
110110

111-
const updateProgress = (progress: { message: string } | null) => {
112-
if (progress) {
111+
const updateProgress = (progress: WorkspaceProgress) => {
112+
if (progress.state === 'progress') {
113113
startSpinner(`[${workspace.folder.name}] ${progress.message}`);
114114
} else {
115-
stopSpinner(`[${workspace.folder.name}]`);
115+
const readySymbol =
116+
progress.state === 'standby' ? '$(debug-stop)' : '$(debug-start)';
117+
stopSpinner(`[${workspace.folder.name}] ${readySymbol}`);
116118
}
117119
};
118120

@@ -139,12 +141,12 @@ function whenChangingWorkspaceFolders(e: WorkspaceFoldersChangeEvent) {
139141
const workspaces: Map<string, ClientWorkspace> = new Map();
140142

141143
/**
142-
* Fetches a `ClientWorkspace` for a given URI. If missing and `startIfMissing`
144+
* Fetches a `ClientWorkspace` for a given URI. If missing and `initializeIfMissing`
143145
* option was provided, it is additionally initialized beforehand, if applicable.
144146
*/
145147
function clientWorkspaceForUri(
146148
uri: Uri,
147-
options?: { startIfMissing: boolean },
149+
options?: { initializeIfMissing: boolean },
148150
): ClientWorkspace | undefined {
149151
const rootFolder = workspace.getWorkspaceFolder(uri);
150152
if (!rootFolder) {
@@ -157,15 +159,20 @@ function clientWorkspaceForUri(
157159
}
158160

159161
const existing = workspaces.get(folder.uri.toString());
160-
if (!existing && options && options.startIfMissing) {
162+
if (!existing && options && options.initializeIfMissing) {
161163
const workspace = new ClientWorkspace(folder);
162164
workspaces.set(folder.uri.toString(), workspace);
163-
workspace.start();
165+
workspace.autoStart();
164166
}
165167

166168
return workspaces.get(folder.uri.toString());
167169
}
168170

171+
/** Denotes the state or progress the workspace is currently in. */
172+
type WorkspaceProgress =
173+
| { state: 'progress'; message: string }
174+
| { state: 'ready' | 'standby' };
175+
169176
// We run one RLS and one corresponding language client per workspace folder
170177
// (VSCode workspace, not Cargo workspace). This class contains all the per-client
171178
// and per-workspace stuff.
@@ -176,7 +183,7 @@ class ClientWorkspace {
176183
private readonly config: RLSConfiguration;
177184
private lc: LanguageClient | null = null;
178185
private disposables: Disposable[];
179-
private _progress: Observable<{ message: string } | null>;
186+
private _progress: Observable<WorkspaceProgress>;
180187
get progress() {
181188
return this._progress;
182189
}
@@ -185,11 +192,20 @@ class ClientWorkspace {
185192
this.config = RLSConfiguration.loadFromWorkspace(folder.uri.fsPath);
186193
this.folder = folder;
187194
this.disposables = [];
188-
this._progress = new Observable<{ message: string } | null>(null);
195+
this._progress = new Observable<WorkspaceProgress>({ state: 'standby' });
196+
}
197+
198+
/**
199+
* Attempts to start a server instance, if not configured otherwise via
200+
* applicable `rust-client.autoStartRls` setting.
201+
* @returns whether the server has started.
202+
*/
203+
public async autoStart() {
204+
return this.config.autoStartRls && this.start().then(() => true);
189205
}
190206

191207
public async start() {
192-
this._progress.value = { message: 'Starting' };
208+
this._progress.value = { state: 'progress', message: 'Starting' };
193209

194210
const serverOptions: ServerOptions = async () => {
195211
await this.autoUpdate();
@@ -265,6 +281,8 @@ class ClientWorkspace {
265281
public async stop() {
266282
if (this.lc) {
267283
await this.lc.stop();
284+
this.lc = null;
285+
this._progress.value = { state: 'standby' };
268286
}
269287

270288
this.disposables.forEach(d => d.dispose());
@@ -308,9 +326,9 @@ class ClientWorkspace {
308326
} else if (progress.title) {
309327
status = `[${progress.title.toLowerCase()}]`;
310328
}
311-
this._progress.value = { message: status };
329+
this._progress.value = { state: 'progress', message: status };
312330
} else {
313-
this._progress.value = null;
331+
this._progress.value = { state: 'ready' };
314332
}
315333
},
316334
);
@@ -466,6 +484,14 @@ function registerCommands(): Disposable[] {
466484
'rls.run',
467485
(cmd: Execution) => activeWorkspace && activeWorkspace.runRlsCommand(cmd),
468486
),
487+
commands.registerCommand(
488+
'rls.start',
489+
() => activeWorkspace && activeWorkspace.start(),
490+
),
491+
commands.registerCommand(
492+
'rls.stop',
493+
() => activeWorkspace && activeWorkspace.stop(),
494+
),
469495
];
470496
}
471497

0 commit comments

Comments
 (0)