Skip to content

Commit d2917a3

Browse files
committed
Add input prompt message types to protocol
This change adds input prompt messages types to the language server protocol. It also converts the existing choice prompt message types from events to requests since we now have server-to-client request support.
1 parent b37ad4f commit d2917a3

File tree

4 files changed

+249
-53
lines changed

4 files changed

+249
-53
lines changed

src/PowerShellEditorServices.Protocol/Messages/PromptEvents.cs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
namespace Microsoft.PowerShell.EditorServices.Protocol.Messages
99
{
10-
public class ShowChoicePromptNotification
10+
public class ShowChoicePromptRequest
1111
{
1212
public static readonly
13-
EventType<ShowChoicePromptNotification> Type =
14-
EventType<ShowChoicePromptNotification>.Create("powerShell/showChoicePrompt");
13+
RequestType<ShowChoicePromptRequest, ShowChoicePromptResponse> Type =
14+
RequestType<ShowChoicePromptRequest, ShowChoicePromptResponse>.Create("powerShell/showChoicePrompt");
1515

1616
public string Caption { get; set; }
1717

@@ -22,15 +22,35 @@ public static readonly
2222
public int DefaultChoice { get; set; }
2323
}
2424

25-
public class CompleteChoicePromptNotification
25+
public class ShowChoicePromptResponse
26+
{
27+
public bool PromptCancelled { get; set; }
28+
29+
public string ChosenItem { get; set; }
30+
}
31+
32+
public class ShowInputPromptRequest
2633
{
2734
public static readonly
28-
EventType<CompleteChoicePromptNotification> Type =
29-
EventType<CompleteChoicePromptNotification>.Create("powerShell/completeChoicePrompt");
35+
RequestType<ShowInputPromptRequest, ShowInputPromptResponse> Type =
36+
RequestType<ShowInputPromptRequest, ShowInputPromptResponse>.Create("powerShell/showInputPrompt");
37+
38+
/// <summary>
39+
/// Gets or sets the name of the field.
40+
/// </summary>
41+
public string Name { get; set; }
42+
43+
/// <summary>
44+
/// Gets or sets the descriptive label for the field.
45+
/// </summary>
46+
public string Label { get; set; }
47+
}
3048

49+
public class ShowInputPromptResponse
50+
{
3151
public bool PromptCancelled { get; set; }
3252

33-
public string ChosenItem { get; set; }
53+
public string ResponseText { get; set; }
3454
}
3555
}
3656

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ protected override void Initialize()
7373
this.SetRequestHandler(FindModuleRequest.Type, this.HandleFindModuleRequest);
7474
this.SetRequestHandler(InstallModuleRequest.Type, this.HandleInstallModuleRequest);
7575

76-
this.SetEventHandler(CompleteChoicePromptNotification.Type, this.HandleCompleteChoicePromptNotification);
77-
7876
this.SetRequestHandler(DebugAdapterMessages.EvaluateRequest.Type, this.HandleEvaluateRequest);
7977
}
8078

@@ -216,25 +214,6 @@ private async Task HandleFindModuleRequest(
216214
await requestContext.SendResult(moduleList);
217215
}
218216

219-
protected Task HandleCompleteChoicePromptNotification(
220-
CompleteChoicePromptNotification completeChoicePromptParams,
221-
EventContext eventContext)
222-
{
223-
if (!completeChoicePromptParams.PromptCancelled)
224-
{
225-
this.editorSession.ConsoleService.ReceiveInputString(
226-
completeChoicePromptParams.ChosenItem,
227-
false);
228-
}
229-
else
230-
{
231-
// Cancel the current prompt
232-
this.editorSession.ConsoleService.SendControlC();
233-
}
234-
235-
return Task.FromResult(true);
236-
}
237-
238217
protected Task HandleDidOpenTextDocumentNotification(
239218
DidOpenTextDocumentNotification openParams,
240219
EventContext eventContext)

src/PowerShellEditorServices.Protocol/Server/PromptHandlers.cs

Lines changed: 149 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,182 @@
66
using System;
77
using Microsoft.PowerShell.EditorServices.Console;
88
using Microsoft.PowerShell.EditorServices.Protocol.Messages;
9+
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
10+
using Microsoft.PowerShell.EditorServices.Utility;
11+
using System.Threading.Tasks;
912

1013
namespace Microsoft.PowerShell.EditorServices.Protocol.Server
1114
{
1215
internal class ProtocolPromptHandlerContext : IPromptHandlerContext
1316
{
14-
private IEventWriter eventWriter;
17+
private IMessageSender messageSender;
18+
private ConsoleService consoleService;
1519

16-
public ProtocolPromptHandlerContext(IEventWriter eventWriter)
20+
public ProtocolPromptHandlerContext(
21+
IMessageSender messageSender,
22+
ConsoleService consoleService)
1723
{
18-
this.eventWriter = eventWriter;
24+
this.messageSender = messageSender;
25+
this.consoleService = consoleService;
1926
}
2027

2128
public ChoicePromptHandler GetChoicePromptHandler()
2229
{
23-
return new ProtocolChoicePromptHandler(this.eventWriter);
30+
return new ProtocolChoicePromptHandler(
31+
this.messageSender,
32+
this.consoleService);
2433
}
2534

2635
public InputPromptHandler GetInputPromptHandler()
2736
{
28-
throw new NotImplementedException();
37+
return new ProtocolInputPromptHandler(
38+
this.messageSender,
39+
this.consoleService);
2940
}
3041
}
3142

3243
internal class ProtocolChoicePromptHandler : ChoicePromptHandler
3344
{
34-
private IEventWriter eventWriter;
45+
private IMessageSender messageSender;
46+
private ConsoleService consoleService;
3547

36-
public ProtocolChoicePromptHandler(IEventWriter eventWriter)
48+
public ProtocolChoicePromptHandler(
49+
IMessageSender messageSender,
50+
ConsoleService consoleService)
3751
{
38-
this.eventWriter = eventWriter;
52+
this.messageSender = messageSender;
53+
this.consoleService = consoleService;
3954
}
4055

4156
protected override void ShowPrompt(PromptStyle promptStyle)
4257
{
43-
eventWriter.SendEvent(
44-
ShowChoicePromptNotification.Type,
45-
new ShowChoicePromptNotification
58+
messageSender
59+
.SendRequest(
60+
ShowChoicePromptRequest.Type,
61+
new ShowChoicePromptRequest
62+
{
63+
Caption = this.Caption,
64+
Message = this.Message,
65+
Choices = this.Choices,
66+
DefaultChoice = this.DefaultChoice
67+
}, true)
68+
.ContinueWith(HandlePromptResponse)
69+
.ConfigureAwait(false);
70+
}
71+
72+
private void HandlePromptResponse(
73+
Task<ShowChoicePromptResponse> responseTask)
74+
{
75+
if (responseTask.IsCompleted)
76+
{
77+
ShowChoicePromptResponse response = responseTask.Result;
78+
79+
if (!response.PromptCancelled)
4680
{
47-
Caption = this.Caption,
48-
Message = this.Message,
49-
Choices = this.Choices,
50-
DefaultChoice = this.DefaultChoice
51-
}).ConfigureAwait(false);
81+
this.consoleService.ReceivePromptResponse(
82+
response.ChosenItem,
83+
false);
84+
}
85+
else
86+
{
87+
// Cancel the current prompt
88+
this.consoleService.SendControlC();
89+
}
90+
}
91+
else
92+
{
93+
if (responseTask.IsFaulted)
94+
{
95+
// Log the error
96+
Logger.Write(
97+
LogLevel.Error,
98+
"ShowChoicePrompt request failed with error:\r\n{0}",
99+
responseTask.Exception.ToString());
100+
}
101+
102+
// Cancel the current prompt
103+
this.consoleService.SendControlC();
104+
}
105+
}
106+
}
107+
108+
internal class ProtocolInputPromptHandler : ConsoleInputPromptHandler
109+
{
110+
private IMessageSender messageSender;
111+
private ConsoleService consoleService;
112+
113+
public ProtocolInputPromptHandler(
114+
IMessageSender messageSender,
115+
ConsoleService consoleService)
116+
: base(consoleService)
117+
{
118+
this.messageSender = messageSender;
119+
this.consoleService = consoleService;
120+
}
121+
122+
protected override void ShowErrorMessage(Exception e)
123+
{
124+
// Use default behavior for writing the error message
125+
base.ShowErrorMessage(e);
126+
}
127+
128+
protected override void ShowPromptMessage(string caption, string message)
129+
{
130+
// Use default behavior for writing the prompt message
131+
base.ShowPromptMessage(caption, message);
132+
}
133+
134+
protected override void ShowFieldPrompt(FieldDetails fieldDetails)
135+
{
136+
// Write the prompt to the console first so that there's a record
137+
// of it occurring
138+
base.ShowFieldPrompt(fieldDetails);
139+
140+
messageSender
141+
.SendRequest(
142+
ShowInputPromptRequest.Type,
143+
new ShowInputPromptRequest
144+
{
145+
Name = fieldDetails.Name,
146+
Label = fieldDetails.Label
147+
}, true)
148+
.ContinueWith(HandlePromptResponse)
149+
.ConfigureAwait(false);
150+
}
151+
152+
private void HandlePromptResponse(
153+
Task<ShowInputPromptResponse> responseTask)
154+
{
155+
if (responseTask.IsCompleted)
156+
{
157+
ShowInputPromptResponse response = responseTask.Result;
158+
159+
if (!response.PromptCancelled)
160+
{
161+
this.consoleService.ReceivePromptResponse(
162+
response.ResponseText,
163+
true);
164+
}
165+
else
166+
{
167+
// Cancel the current prompt
168+
this.consoleService.SendControlC();
169+
}
170+
}
171+
else
172+
{
173+
if (responseTask.IsFaulted)
174+
{
175+
// Log the error
176+
Logger.Write(
177+
LogLevel.Error,
178+
"ShowInputPrompt request failed with error:\r\n{0}",
179+
responseTask.Exception.ToString());
180+
}
181+
182+
// Cancel the current prompt
183+
this.consoleService.SendControlC();
184+
}
52185
}
53186
}
54187
}

0 commit comments

Comments
 (0)