Skip to content

Commit 84eb99f

Browse files
committed
Add miscellaneous file open notifications
1 parent 3562921 commit 84eb99f

File tree

4 files changed

+87
-10
lines changed

4 files changed

+87
-10
lines changed

l10n/bundle.l10n.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@
172172
"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?",
173173
"Nested Code Action": "Nested Code Action",
174174
"Fix All: ": "Fix All: ",
175+
"{0} is not part of the open workspace. Not all language features will be available.": "{0} is not part of the open workspace. Not all language features will be available.",
176+
"Dismiss": "Dismiss",
177+
"Do not show for this workspace": "Do not show for this workspace",
178+
"Do not show again": "Do not show again",
175179
"Open solution": "Open solution",
176180
"Restart server": "Restart server",
177181
"C# Workspace Status": "C# Workspace Status",

src/lsptoolshost/languageStatusBar.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,11 @@ import { ServerState } from './serverStateChange';
1111
import { getCSharpDevKit } from '../utils/getCSharpDevKit';
1212
import { RazorLanguage } from '../razor/src/razorLanguage';
1313

14-
let currentServerState: ServerState = ServerState.Stopped;
15-
1614
export function registerLanguageStatusItems(
1715
context: vscode.ExtensionContext,
1816
languageServer: RoslynLanguageServer,
1917
languageServerEvents: RoslynLanguageServerEvents
2018
) {
21-
// Track the current server state.
22-
languageServerEvents.onServerStateChange((e) => {
23-
currentServerState = e.state;
24-
});
25-
2619
// DevKit will provide an equivalent workspace status item.
2720
if (!getCSharpDevKit()) {
2821
WorkspaceStatus.createStatusItem(context, languageServerEvents);
@@ -85,7 +78,7 @@ class ProjectContextStatus {
8578

8679
// Show a warning when the active file is part of the Miscellaneous File workspace and
8780
// project initialization is complete.
88-
if (currentServerState === ServerState.ProjectInitializationComplete) {
81+
if (languageServer.state === ServerState.ProjectInitializationComplete) {
8982
item.severity = e.context._vs_is_miscellaneous
9083
? vscode.LanguageStatusSeverity.Warning
9184
: vscode.LanguageStatusSeverity.Information;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import { RoslynLanguageServer } from './roslynLanguageServer';
8+
import { ActionOption, showWarningMessage } from '../shared/observers/utils/showMessage';
9+
import { ServerState } from './serverStateChange';
10+
import path = require('path');
11+
12+
const NotifyMiscellaneousFilesOption = 'dotnet.miscellaneousFilesNotification.enabled';
13+
const RecentlyNotifiedDocuments = new Set<vscode.Uri>();
14+
const CooldownTime = 60 * 1000;
15+
16+
export function registerMiscellaneousFileNotifier(
17+
context: vscode.ExtensionContext,
18+
languageServer: RoslynLanguageServer
19+
) {
20+
context.workspaceState.update(NotifyMiscellaneousFilesOption, undefined);
21+
context.globalState.update(NotifyMiscellaneousFilesOption, undefined);
22+
23+
languageServer._projectContextService.onActiveFileContextChanged((e) => {
24+
if (RecentlyNotifiedDocuments.has(e.uri)) {
25+
return;
26+
}
27+
28+
if (!e.context._vs_is_miscellaneous || languageServer.state !== ServerState.ProjectInitializationComplete) {
29+
return;
30+
}
31+
32+
if (!context.globalState.get<boolean>(NotifyMiscellaneousFilesOption, true)) {
33+
return;
34+
}
35+
36+
if (!context.workspaceState.get<boolean>(NotifyMiscellaneousFilesOption, true)) {
37+
return;
38+
}
39+
40+
RecentlyNotifiedDocuments.add(e.uri);
41+
42+
const message = vscode.l10n.t(
43+
'{0} is not part of the open workspace. Not all language features will be available.',
44+
path.basename(e.uri.fsPath)
45+
);
46+
const dismissItem = vscode.l10n.t('Dismiss');
47+
const disableWorkspace: ActionOption = {
48+
title: vscode.l10n.t('Do not show for this workspace'),
49+
action: async () => {
50+
context.workspaceState.update(NotifyMiscellaneousFilesOption, false);
51+
},
52+
};
53+
const disableGlobal: ActionOption = {
54+
title: vscode.l10n.t('Do not show again'),
55+
action: async () => {
56+
context.globalState.update(NotifyMiscellaneousFilesOption, false);
57+
},
58+
};
59+
showWarningMessage(vscode, message, disableWorkspace, disableGlobal, dismissItem);
60+
61+
setTimeout(() => {
62+
RecentlyNotifiedDocuments.delete(e.uri);
63+
}, CooldownTime);
64+
});
65+
}

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import {
7575
showInformationMessage,
7676
} from '../shared/observers/utils/showMessage';
7777
import { registerSourceGeneratedFilesContentProvider } from './sourceGeneratedFilesContentProvider';
78+
import { registerMiscellaneousFileNotifier } from './miscellaneousFileNotifier';
7879

7980
let _channel: vscode.OutputChannel;
8081
let _traceChannel: vscode.OutputChannel;
@@ -115,8 +116,10 @@ export class RoslynLanguageServer {
115116

116117
public readonly _onAutoInsertFeature: OnAutoInsertFeature;
117118

118-
public _buildDiagnosticService: BuildDiagnosticsService;
119-
public _projectContextService: ProjectContextService;
119+
public readonly _buildDiagnosticService: BuildDiagnosticsService;
120+
public readonly _projectContextService: ProjectContextService;
121+
122+
private _state: ServerState = ServerState.Stopped;
120123

121124
constructor(
122125
private _languageClient: RoslynLanguageClient,
@@ -129,6 +132,7 @@ export class RoslynLanguageServer {
129132
this.registerSendOpenSolution();
130133
this.registerProjectInitialization();
131134
this.registerServerStateChanged();
135+
this.registerServerStateTracking();
132136
this.registerReportProjectConfiguration();
133137
this.registerExtensionsChanged();
134138
this.registerTelemetryChanged();
@@ -151,6 +155,10 @@ export class RoslynLanguageServer {
151155
this._onAutoInsertFeature = new OnAutoInsertFeature(this._languageClient);
152156
}
153157

158+
public get state(): ServerState {
159+
return this._state;
160+
}
161+
154162
private registerSetTrace() {
155163
// Set the language client trace level based on the log level option.
156164
// setTrace only works after the client is already running.
@@ -179,6 +187,12 @@ export class RoslynLanguageServer {
179187
});
180188
}
181189

190+
private registerServerStateTracking() {
191+
this._languageServerEvents.onServerStateChange((e) => {
192+
this._state = e.state;
193+
});
194+
}
195+
182196
private registerSendOpenSolution() {
183197
this._languageClient.onDidChangeState(async (state) => {
184198
if (state.newState === State.Running) {
@@ -1053,6 +1067,7 @@ export async function activateRoslynLanguageServer(
10531067
);
10541068

10551069
registerLanguageStatusItems(context, languageServer, languageServerEvents);
1070+
registerMiscellaneousFileNotifier(context, languageServer);
10561071
registerCopilotExtension(languageServer, _channel);
10571072

10581073
// Register any commands that need to be handled by the extension.

0 commit comments

Comments
 (0)