Skip to content

Commit be44edc

Browse files
committed
Add handling of configuration events from client
This change introduces the 'workspace/didChangeConfiguration' notification which the client will send to the language server when the user changes their settings. It also introduces a new configuration section for script analysis settings so that the user can turn on/off script analysis. More settings will be added later.
1 parent ae5e861 commit be44edc

File tree

5 files changed

+138
-13
lines changed

5 files changed

+138
-13
lines changed

src/PowerShellEditorServices.Host/LanguageServer.cs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ internal class LanguageServer : IMessageProcessor
2525
private static CancellationTokenSource existingRequestCancellation;
2626

2727
private MessageDispatcher<EditorSession> messageDispatcher;
28+
private LanguageServerSettings currentSettings = new LanguageServerSettings();
2829

2930
public LanguageServer()
3031
{
@@ -42,6 +43,7 @@ public void Initialize()
4243
this.AddEventHandler(DidOpenTextDocumentNotification.Type, this.HandleDidOpenTextDocumentNotification);
4344
this.AddEventHandler(DidCloseTextDocumentNotification.Type, this.HandleDidCloseTextDocumentNotification);
4445
this.AddEventHandler(DidChangeTextDocumentNotification.Type, this.HandleDidChangeTextDocumentNotification);
46+
this.AddEventHandler(DidChangeConfigurationNotification<SettingsWrapper>.Type, this.HandleDidChangeConfigurationNotification);
4547

4648
this.AddRequestHandler(DefinitionRequest.Type, this.HandleDefinitionRequest);
4749
this.AddRequestHandler(ReferencesRequest.Type, this.HandleReferencesRequest);
@@ -226,6 +228,36 @@ protected Task HandleDidChangeTextDocumentNotification(
226228
return Task.FromResult(true);
227229
}
228230

231+
protected async Task HandleDidChangeConfigurationNotification(
232+
DidChangeConfigurationParams<SettingsWrapper> configChangeParams,
233+
EditorSession editorSession,
234+
EventContext eventContext)
235+
{
236+
bool oldScriptAnalysisEnabled =
237+
this.currentSettings.ScriptAnalysis.Enable.HasValue;
238+
239+
this.currentSettings.Update(
240+
configChangeParams.Settings.Powershell);
241+
242+
if (oldScriptAnalysisEnabled != this.currentSettings.ScriptAnalysis.Enable)
243+
{
244+
// If the user just turned off script analysis, send a diagnostics
245+
// event to clear the analysis markers that they already have
246+
if (!this.currentSettings.ScriptAnalysis.Enable.Value)
247+
{
248+
ScriptFileMarker[] emptyAnalysisDiagnostics = new ScriptFileMarker[0];
249+
250+
foreach (var scriptFile in editorSession.Workspace.GetOpenedFiles())
251+
{
252+
await PublishScriptDiagnostics(
253+
scriptFile,
254+
emptyAnalysisDiagnostics,
255+
eventContext);
256+
}
257+
}
258+
}
259+
}
260+
229261
protected async Task HandleDefinitionRequest(
230262
TextDocumentPosition textDocumentPosition,
231263
EditorSession editorSession,
@@ -744,6 +776,12 @@ private Task RunScriptDiagnostics(
744776
EditorSession editorSession,
745777
EventContext eventContext)
746778
{
779+
if (!this.currentSettings.ScriptAnalysis.Enable.Value)
780+
{
781+
// If the user has disabled script analysis, skip it entirely
782+
return TaskConstants.Completed;
783+
}
784+
747785
// If there's an existing task, attempt to cancel it
748786
try
749787
{
@@ -827,24 +865,36 @@ private static async Task DelayThenInvokeDiagnostics(
827865

828866
var allMarkers = scriptFile.SyntaxMarkers.Concat(semanticMarkers);
829867

830-
// Always send syntax and semantic errors. We want to
831-
// make sure no out-of-date markers are being displayed.
832-
await eventContext.SendEvent(
833-
PublishDiagnosticsNotification.Type,
834-
new PublishDiagnosticsNotification
835-
{
836-
Uri = scriptFile.ClientFilePath,
837-
Diagnostics =
838-
allMarkers
839-
.Select(GetDiagnosticFromMarker)
840-
.ToArray()
841-
});
842-
868+
await PublishScriptDiagnostics(
869+
scriptFile,
870+
semanticMarkers,
871+
eventContext);
843872
}
844873

845874
Logger.Write(LogLevel.Verbose, "Analysis complete.");
846875
}
847876

877+
private async static Task PublishScriptDiagnostics(
878+
ScriptFile scriptFile,
879+
ScriptFileMarker[] semanticMarkers,
880+
EventContext eventContext)
881+
{
882+
var allMarkers = scriptFile.SyntaxMarkers.Concat(semanticMarkers);
883+
884+
// Always send syntax and semantic errors. We want to
885+
// make sure no out-of-date markers are being displayed.
886+
await eventContext.SendEvent(
887+
PublishDiagnosticsNotification.Type,
888+
new PublishDiagnosticsNotification
889+
{
890+
Uri = scriptFile.ClientFilePath,
891+
Diagnostics =
892+
allMarkers
893+
.Select(GetDiagnosticFromMarker)
894+
.ToArray()
895+
});
896+
}
897+
848898
private static Diagnostic GetDiagnosticFromMarker(ScriptFileMarker scriptFileMarker)
849899
{
850900
return new Diagnostic
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
namespace Microsoft.PowerShell.EditorServices.Host
7+
{
8+
internal class LanguageServerSettings
9+
{
10+
public ScriptAnalysisSettings ScriptAnalysis { get; set; }
11+
12+
public LanguageServerSettings()
13+
{
14+
this.ScriptAnalysis = new ScriptAnalysisSettings();
15+
}
16+
17+
public void Update(LanguageServerSettings settings)
18+
{
19+
if (settings != null)
20+
{
21+
this.ScriptAnalysis.Update(settings.ScriptAnalysis);
22+
}
23+
}
24+
}
25+
26+
internal class ScriptAnalysisSettings
27+
{
28+
public bool? Enable { get; set; }
29+
30+
public ScriptAnalysisSettings()
31+
{
32+
this.Enable = true;
33+
}
34+
35+
public void Update(ScriptAnalysisSettings settings)
36+
{
37+
if (settings != null)
38+
{
39+
this.Enable = settings.Enable;
40+
}
41+
}
42+
}
43+
44+
internal class SettingsWrapper
45+
{
46+
// NOTE: This property is capitalized as 'Powershell' because the
47+
// mode name sent from the client is written as 'powershell' and
48+
// JSON.net is using camelCasing.
49+
50+
public LanguageServerSettings Powershell { get; set; }
51+
}
52+
}

src/PowerShellEditorServices.Host/PowerShellEditorServices.Host.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<Compile Include="DebugAdapter.cs" />
6363
<Compile Include="IMessageProcessor.cs" />
6464
<Compile Include="LanguageServer.cs" />
65+
<Compile Include="LanguageServerSettings.cs" />
6566
<Compile Include="MessageLoop.cs" />
6667
<Compile Include="Program.cs" />
6768
<Compile Include="Properties\AssemblyInfo.cs" />
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
7+
8+
namespace Microsoft.PowerShell.EditorServices.Protocol.LanguageServer
9+
{
10+
public class DidChangeConfigurationNotification<TConfig>
11+
{
12+
public static readonly
13+
EventType<DidChangeConfigurationParams<TConfig>> Type =
14+
EventType<DidChangeConfigurationParams<TConfig>>.Create("workspace/didChangeConfiguration");
15+
}
16+
17+
public class DidChangeConfigurationParams<TConfig>
18+
{
19+
public TConfig Settings { get; set; }
20+
}
21+
}

src/PowerShellEditorServices.Protocol/PowerShellEditorServices.Protocol.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
<Compile Include="DebugAdapter\V8MessageSerializer.cs" />
9090
<Compile Include="DebugAdapter\Variable.cs" />
9191
<Compile Include="DebugAdapter\VariablesRequest.cs" />
92+
<Compile Include="LanguageServer\Configuration.cs" />
9293
<Compile Include="LanguageServer\Definition.cs" />
9394
<Compile Include="LanguageServer\DocumentHighlight.cs" />
9495
<Compile Include="LanguageServer\Hover.cs" />

0 commit comments

Comments
 (0)