Skip to content

Commit 96264a3

Browse files
committed
Update the workspace status bar when the server is stopped.
- Sets the workspace status item to the Warning state to display an indicator that there has been an issue. - Provides easy access to restart the LSP server.
1 parent 3e16d35 commit 96264a3

File tree

5 files changed

+52
-16
lines changed

5 files changed

+52
-16
lines changed

l10n/bundle.l10n.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
"Failed to run test: {0}": "Failed to run test: {0}",
145145
"Failed to start debugger: {0}": "Failed to start debugger: {0}",
146146
"Test run already in progress": "Test run already in progress",
147+
"Server stopped": "Server stopped",
147148
"Workspace projects": "Workspace projects",
148149
"Your workspace has multiple Visual Studio Solution files; please select one to get full IntelliSense.": "Your workspace has multiple Visual Studio Solution files; please select one to get full IntelliSense.",
149150
"Choose": "Choose",
@@ -159,8 +160,9 @@
159160
"C# configuration has changed. Would you like to reload the window to apply your changes?": "C# configuration has changed. Would you like to reload the window to apply your changes?",
160161
"Nested Code Action": "Nested Code Action",
161162
"Fix All: ": "Fix All: ",
162-
"C# Workspace Status": "C# Workspace Status",
163163
"Open solution": "Open solution",
164+
"Restart server": "Restart server",
165+
"C# Workspace Status": "C# Workspace Status",
164166
"C# Project Context Status": "C# Project Context Status",
165167
"Active File Context": "Active File Context",
166168
"Pick a fix all scope": "Pick a fix all scope",

src/lsptoolshost/languageStatusBar.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,27 @@ class WorkspaceStatus {
3333
languageServerOptions.documentSelector,
3434
RazorLanguage.documentSelector
3535
);
36-
const item = vscode.languages.createLanguageStatusItem('csharp.workspaceStatus', documentSelector);
37-
item.name = vscode.l10n.t('C# Workspace Status');
38-
item.command = {
36+
const openSolutionCommand = {
3937
command: 'dotnet.openSolution',
4038
title: vscode.l10n.t('Open solution'),
4139
};
40+
const restartServerCommand = {
41+
command: 'dotnet.restartServer',
42+
title: vscode.l10n.t('Restart server'),
43+
};
44+
45+
const item = vscode.languages.createLanguageStatusItem('csharp.workspaceStatus', documentSelector);
46+
item.name = vscode.l10n.t('C# Workspace Status');
4247
context.subscriptions.push(item);
4348

4449
languageServerEvents.onServerStateChange((e) => {
4550
item.text = e.workspaceLabel;
4651
item.busy = e.state === ServerState.ProjectInitializationStarted;
52+
item.severity =
53+
e.state === ServerState.Stopped
54+
? vscode.LanguageStatusSeverity.Warning
55+
: vscode.LanguageStatusSeverity.Information;
56+
item.command = e.state === ServerState.Stopped ? restartServerCommand : openSolutionCommand;
4757
});
4858
}
4959
}

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export class RoslynLanguageServer {
119119
this.registerSetTrace();
120120
this.registerSendOpenSolution();
121121
this.registerProjectInitialization();
122+
this.registerServerStateChanged();
122123
this.registerReportProjectConfiguration();
123124
this.registerExtensionsChanged();
124125
this.registerTelemetryChanged();
@@ -153,6 +154,22 @@ export class RoslynLanguageServer {
153154
});
154155
}
155156

157+
private registerServerStateChanged() {
158+
this._languageClient.onDidChangeState(async (state) => {
159+
if (state.newState === State.Running) {
160+
this._languageServerEvents.onServerStateChangeEmitter.fire({
161+
state: ServerState.Started,
162+
workspaceLabel: this.workspaceDisplayName(),
163+
});
164+
} else if (state.newState === State.Stopped) {
165+
this._languageServerEvents.onServerStateChangeEmitter.fire({
166+
state: ServerState.Stopped,
167+
workspaceLabel: vscode.l10n.t('Server stopped'),
168+
});
169+
}
170+
});
171+
}
172+
156173
private registerSendOpenSolution() {
157174
this._languageClient.onDidChangeState(async (state) => {
158175
if (state.newState === State.Running) {
@@ -162,10 +179,6 @@ export class RoslynLanguageServer {
162179
await this.openDefaultSolutionOrProjects();
163180
}
164181
await this.sendOrSubscribeForServiceBrokerConnection();
165-
this._languageServerEvents.onServerStateChangeEmitter.fire({
166-
state: ServerState.Started,
167-
workspaceLabel: this.workspaceDisplayName(),
168-
});
169182
}
170183
});
171184
}

src/lsptoolshost/serverStateChange.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
export enum ServerState {
7-
Started = 0,
8-
ProjectInitializationStarted = 1,
9-
ProjectInitializationComplete = 2,
7+
Stopped = 0,
8+
Started = 1,
9+
ProjectInitializationStarted = 2,
10+
ProjectInitializationComplete = 3,
1011
}
1112

1213
export interface ServerStateChangeEvent {

src/lsptoolshost/services/projectContextService.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@ export interface ProjectContextChangeEvent {
2222
export class ProjectContextService {
2323
private readonly _contextChangeEmitter = new vscode.EventEmitter<ProjectContextChangeEvent>();
2424
private _source = new vscode.CancellationTokenSource();
25+
private readonly _emptyProjectContext: VSProjectContext = {
26+
_vs_id: '',
27+
_vs_kind: '',
28+
_vs_label: '',
29+
};
2530

2631
constructor(private _languageServer: RoslynLanguageServer, _languageServerEvents: LanguageServerEvents) {
2732
_languageServerEvents.onServerStateChange((e) => {
2833
// When the project initialization is complete, open files
2934
// could move from the miscellaneous workspace context into
3035
// an open project.
31-
if (e.state === ServerState.ProjectInitializationComplete) {
36+
if (e.state === ServerState.Stopped || e.state === ServerState.ProjectInitializationComplete) {
3237
this.refresh();
3338
}
3439
});
@@ -47,8 +52,17 @@ export class ProjectContextService {
4752
return;
4853
}
4954

55+
// If we have an open request, cancel it.
56+
this._source.cancel();
57+
this._source = new vscode.CancellationTokenSource();
58+
5059
let uri = textEditor!.document.uri;
5160

61+
if (!this._languageServer.isRunning()) {
62+
this._contextChangeEmitter.fire({ uri, context: this._emptyProjectContext });
63+
return;
64+
}
65+
5266
// If the active document is a Razor file, we need to map it back to a C# file.
5367
if (languageId === 'aspnetcorerazor') {
5468
const virtualUri = await this.getVirtualCSharpUri(uri);
@@ -59,10 +73,6 @@ export class ProjectContextService {
5973
uri = virtualUri;
6074
}
6175

62-
// If we have an open request, cancel it.
63-
this._source.cancel();
64-
this._source = new vscode.CancellationTokenSource();
65-
6676
const contextList = await this.getProjectContexts(uri, this._source.token);
6777
if (!contextList) {
6878
return;

0 commit comments

Comments
 (0)