Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,13 @@ public override

bool cancelInput = false;

if (!string.IsNullOrEmpty(caption))
{
// Should be a skin lookup

WriteLineToConsole();
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
}

if (!string.IsNullOrEmpty(message))
{
WriteLineToConsole(WrapToCurrentWindowWidth(message));
}
WriteCaptionAndMessage(caption, message);

if (AtLeastOneHelpMessageIsPresent(descriptions))
{
WriteLineToConsole(WrapToCurrentWindowWidth(ConsoleHostUserInterfaceStrings.PromptHelp));
WriteLineToConsole(PSStyle.DecorateAndReset(
WrapToCurrentWindowWidth(ConsoleHostUserInterfaceStrings.PromptHelp),
PSStyle.Instance.Prompt.Help));
}

int descIndex = -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,7 @@ public override int PromptForChoice(string caption, string message, Collection<C

lock (_instanceLock)
{
if (!string.IsNullOrEmpty(caption))
{
// Should be a skin lookup

WriteLineToConsole();
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
}

if (!string.IsNullOrEmpty(message))
{
WriteLineToConsole(WrapToCurrentWindowWidth(message));
}
WriteCaptionAndMessage(caption, message);

int result = defaultChoice;

Expand Down Expand Up @@ -202,18 +191,7 @@ public Collection<int> PromptForChoice(string caption,
// we lock here so that multiple threads won't interleave the various reads and writes here.
lock (_instanceLock)
{
// write caption on the console, if present.
if (!string.IsNullOrEmpty(caption))
{
// Should be a skin lookup
WriteLineToConsole();
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
}
// write message
if (!string.IsNullOrEmpty(message))
{
WriteLineToConsole(WrapToCurrentWindowWidth(message));
}
WriteCaptionAndMessage(caption, message);

string[,] hotkeysAndPlainLabels = null;
HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels);
Expand All @@ -230,7 +208,9 @@ public Collection<int> PromptForChoice(string caption,
{
// write the current prompt
string choiceMsg = StringUtil.Format(ConsoleHostUserInterfaceStrings.ChoiceMessage, choicesSelected);
WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(choiceMsg));
WriteToConsole(
PSStyle.DecorateAndReset(WrapToCurrentWindowWidth(choiceMsg), PSStyle.Instance.Prompt.ChoiceOther),
transcribeResult: true);

ReadLineResult rlResult;
string response = ReadChoiceResponse(out rlResult);
Expand Down Expand Up @@ -292,47 +272,32 @@ private void WriteChoicePrompt(string[,] hotkeysAndPlainLabels,
{
System.Management.Automation.Diagnostics.Assert(defaultChoiceKeys != null, "defaultChoiceKeys cannot be null.");

ConsoleColor fg = RawUI.ForegroundColor;
ConsoleColor bg = RawUI.BackgroundColor;
int lineLenMax = RawUI.WindowSize.Width - 1;
int lineLen = 0;

const string choiceTemplate = "[{0}] {1} ";

var prompts = new List<string>();
for (int i = 0; i < hotkeysAndPlainLabels.GetLength(1); ++i)
{
ConsoleColor cfg = PromptColor;
if (defaultChoiceKeys.ContainsKey(i))
{
// Should be a skin lookup
cfg = DefaultPromptColor;
}
var color = defaultChoiceKeys.ContainsKey(i)
? PSStyle.Instance.Prompt.ChoiceDefault
: PSStyle.Instance.Prompt.ChoiceOther;

const string choiceTemplate = "[{0}] {1}";
string choice =
string.Format(
CultureInfo.InvariantCulture,
choiceTemplate,
hotkeysAndPlainLabels[0, i],
hotkeysAndPlainLabels[1, i]);
WriteChoiceHelper(choice, cfg, bg, ref lineLen, lineLenMax);
if (shouldEmulateForMultipleChoiceSelection)
{
WriteLineToConsole();
}
}

WriteChoiceHelper(
ConsoleHostUserInterfaceStrings.PromptForChoiceHelp,
fg,
bg,
ref lineLen,
lineLenMax);
if (shouldEmulateForMultipleChoiceSelection)
{
WriteLineToConsole();
prompts.Add(PSStyle.DecorateAndReset(choice, color));
}

string defaultPrompt = string.Empty;
prompts.Add(PSStyle.DecorateAndReset(ConsoleHostUserInterfaceStrings.PromptForChoiceHelp,
PSStyle.Instance.Prompt.ChoiceHelp) + " ");

WriteToConsole(shouldEmulateForMultipleChoiceSelection
? string.Join(Environment.NewLine, prompts)
: JoinWrappedToCurrentWindowWidth(" ", prompts),
transcribeResult: true);

if (defaultChoiceKeys.Count > 0)
{
string prepend = string.Empty;
Expand All @@ -345,12 +310,14 @@ private void WriteChoicePrompt(string[,] hotkeysAndPlainLabels,
defaultStr = hotkeysAndPlainLabels[1, defaultChoice];
}

defaultChoicesBuilder.Append(CultureInfo.InvariantCulture, $"{prepend}{defaultStr}");
// Reset style after each in case it is decorated
defaultChoicesBuilder.Append(CultureInfo.InvariantCulture, $"{prepend}{defaultStr}{PSStyle.Instance.Reset}{PSStyle.Instance.Prompt.Help}");
prepend = ",";
}

string defaultChoices = defaultChoicesBuilder.ToString();

string defaultPrompt = string.Empty;
if (defaultChoiceKeys.Count == 1)
{
defaultPrompt = shouldEmulateForMultipleChoiceSelection ?
Expand All @@ -360,35 +327,77 @@ private void WriteChoicePrompt(string[,] hotkeysAndPlainLabels,
}
else
{
defaultPrompt = StringUtil.Format(ConsoleHostUserInterfaceStrings.DefaultChoicesForMultipleChoices,
defaultPrompt = StringUtil.Format(
ConsoleHostUserInterfaceStrings.DefaultChoicesForMultipleChoices,
defaultChoices);
}
}

WriteChoiceHelper(defaultPrompt,
fg,
bg,
ref lineLen,
lineLenMax);
WriteToConsole(
PSStyle.DecorateAndReset(defaultPrompt, PSStyle.Instance.Prompt.Help) + " ",
transcribeResult: true);
}
}

private void WriteChoiceHelper(string text, ConsoleColor fg, ConsoleColor bg, ref int lineLen, int lineLenMax)
/// <summary>
/// Joins lines with separator, breaking into new line if longer than window width.
/// </summary>
/// <param name="separator">
/// Separator used between strings fitting on the same line.
/// </param>
/// <param name="values">
/// Collection of strings, never broken unless cannot fit on one line by itself.
/// </param>
/// <returns>
/// Joined string.
/// </returns>
private string JoinWrappedToCurrentWindowWidth(string separator, IEnumerable<string> values)
{
int textLen = RawUI.LengthInBufferCells(text);
bool trimEnd = false;
// Avoid recalculating every time, as skipping over escapes is nontrivial
int lineLength = 0;
int maxLength = RawUI.WindowSize.Width;

if (lineLen + textLen > lineLenMax)
var result = new StringBuilder();
foreach (var value in values)
{
WriteLineToConsole();
trimEnd = true;
lineLen = textLen;
int valueLength = new StringDecorated(value).ContentLength;
if (result.Length == 0)
{
result.Append(value);
lineLength += valueLength;
}
else if (lineLength + valueLength + separator.Length < maxLength)
{
result.Append(separator);
result.Append(value);
lineLength += valueLength + separator.Length;
}
else
{
result.Append(Environment.NewLine);
result.Append(value);
lineLength = valueLength;
}
}
else

return result.ToString();
}

private void WriteCaptionAndMessage(string caption, string message)
{
if (!string.IsNullOrEmpty(caption))
{
lineLen += textLen;
WriteLineToConsole();
WriteLineToConsole(PSStyle.DecorateAndReset(
WrapToCurrentWindowWidth(caption),
PSStyle.Instance.Prompt.Caption));
}

WriteToConsole(fg, bg, trimEnd ? text.TrimEnd(null) : text);
if (!string.IsNullOrEmpty(message))
{
WriteLineToConsole(PSStyle.DecorateAndReset(
WrapToCurrentWindowWidth(message),
PSStyle.Instance.Prompt.Message));
}
}

private string ReadChoiceResponse(out ReadLineResult result)
Expand All @@ -411,56 +420,18 @@ private void ShowChoiceHelp(Collection<ChoiceDescription> choices, string[,] hot

for (int i = 0; i < choices.Count; ++i)
{
string s;

// If there's no hotkey, use the label as the help
string prompt = hotkeysAndPlainLabels[0, i].Length > 0
? ("[" + hotkeysAndPlainLabels[0, i] + "] ")
: (hotkeysAndPlainLabels[1, i] + " - ");

if (hotkeysAndPlainLabels[0, i].Length > 0)
{
s = hotkeysAndPlainLabels[0, i];
}
else
{
s = hotkeysAndPlainLabels[1, i];
}
string message = choices[i].HelpMessage;

prompt = PSStyle.DecorateAndReset(prompt, PSStyle.Instance.Prompt.ChoiceOther);
message = PSStyle.DecorateAndReset(message, PSStyle.Instance.Prompt.Help);
WriteLineToConsole(
WrapToCurrentWindowWidth(
string.Create(CultureInfo.InvariantCulture, $"{s} - {choices[i].HelpMessage}")));
}
}

/// <summary>
/// Guarantee a contrasting color for the prompt...
/// </summary>
private ConsoleColor PromptColor
{
get
{
switch (RawUI.BackgroundColor)
{
case ConsoleColor.White: return ConsoleColor.Black;
case ConsoleColor.Cyan: return ConsoleColor.Black;
case ConsoleColor.DarkYellow: return ConsoleColor.Black;
case ConsoleColor.Yellow: return ConsoleColor.Black;
case ConsoleColor.Gray: return ConsoleColor.Black;
case ConsoleColor.Green: return ConsoleColor.Black;
default: return ConsoleColor.White;
}
}
}
/// <summary>
/// Guarantee a contrasting color for the default prompt that is slightly
/// different from the other prompt elements.
/// </summary>
private ConsoleColor DefaultPromptColor
{
get
{
if (PromptColor == ConsoleColor.White)
return ConsoleColor.Yellow;
else
return ConsoleColor.Blue;
string.Create(CultureInfo.InvariantCulture, $"{prompt}{message}")));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,7 @@ public override PSCredential PromptForCredential(
string userPrompt = null;
string passwordPrompt = null;

if (!string.IsNullOrEmpty(caption))
{
// Should be a skin lookup

WriteLineToConsole();
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
}

if (!string.IsNullOrEmpty(message))
{
WriteLineToConsole(WrapToCurrentWindowWidth(message));
}
WriteCaptionAndMessage(caption, message);

if (string.IsNullOrEmpty(userName))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
<value>"{0}" must be a valid index into "{1}". "{2}" is not a valid index.</value>
</data>
<data name="PromptForChoiceHelp" xml:space="preserve">
<value>[?] Help </value>
<value>[?] Help</value>
</data>
<data name="PromptCanceledError" xml:space="preserve">
<value>The prompt was canceled.</value>
Expand All @@ -169,7 +169,7 @@
<value>(Type !? for Help.)</value>
</data>
<data name="DefaultChoicePrompt" xml:space="preserve">
<value>(default is "{0}"): </value>
<value>(default is "{0}"):</value>
</data>
<data name="DefaultChoiceForMultipleChoices" xml:space="preserve">
<value>(default is "{0}")</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ internal static IEnumerable<ExtendedTypeDefinition> GetFormatData()
yield return new ExtendedTypeDefinition(
"System.Management.Automation.PSStyle+BackgroundColor",
ViewsOf_System_Management_Automation_PSStyleBackgroundColor());

yield return new ExtendedTypeDefinition(
"System.Management.Automation.PSStyle+PromptFormatting",
ViewsOf_System_Management_Automation_PSStylePromptFormat());
}

private static IEnumerable<FormatViewDefinition> ViewsOf_System_RuntimeType()
Expand Down Expand Up @@ -2249,6 +2253,22 @@ private static IEnumerable<FormatViewDefinition> ViewsOf_System_Management_Autom
.EndList());
}

private static IEnumerable<FormatViewDefinition> ViewsOf_System_Management_Automation_PSStylePromptFormat()
{
yield return new FormatViewDefinition(
"System.Management.Automation.PSStyle+PromptFormat",
ListControl.Create()
.StartEntry()
.AddItemScriptBlock(@"$_.AsEscapeSequence('Caption')", label: "Caption")
.AddItemScriptBlock(@"$_.AsEscapeSequence('Message')", label: "Message")
.AddItemScriptBlock(@"$_.AsEscapeSequence('Help')", label: "Help")
.AddItemScriptBlock(@"$_.AsEscapeSequence('ChoiceDefault')", label: "ChoiceDefault")
.AddItemScriptBlock(@"$_.AsEscapeSequence('ChoiceOther')", label: "ChoiceOther")
.AddItemScriptBlock(@"$_.AsEscapeSequence('ChoiceHelp')", label: "ChoiceHelp")
.EndEntry()
.EndList());
}

private static IEnumerable<FormatViewDefinition> ViewsOf_System_Management_Automation_PSStyleForegroundColor()
{
yield return new FormatViewDefinition("System.Management.Automation.PSStyle+ForegroundColor",
Expand Down
Loading