Skip to content

Commit 65d332e

Browse files
authored
Reset all VT attributes for PromptText if it contains VT sequences (#1544)
1 parent 2664653 commit 65d332e

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

PSReadLine/Cmdlets.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,29 @@ public object ContinuationPromptColor
342342
/// If the prompt function is pure, this value can be inferred, e.g.
343343
/// the default prompt will use "> " for this value.
344344
/// </summary>
345-
public string[] PromptText { get; set; }
345+
public string[] PromptText
346+
{
347+
get => _promptText;
348+
set
349+
{
350+
_promptText = value;
351+
if (_promptText == null || _promptText.Length == 0)
352+
return;
353+
354+
// For texts with VT sequences, reset all attributes if not already.
355+
// We only handle the first 2 elements because that's all will potentially be used.
356+
int minLength = _promptText.Length == 1 ? 1 : 2;
357+
for (int i = 0; i < minLength; i ++)
358+
{
359+
var text = _promptText[i];
360+
if (text.Contains('\x1b') && !text.EndsWith("\x1b[0m", StringComparison.Ordinal))
361+
{
362+
_promptText[i] = string.Concat(text, "\x1b[0m");
363+
}
364+
}
365+
}
366+
}
367+
private string[] _promptText;
346368

347369
public object DefaultTokenColor
348370
{

PSReadLine/Render.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,13 @@ private bool RenderErrorPrompt(RenderData renderData, string defaultColor)
444444
{
445445
string color = renderData.errorPrompt ? _options._errorColor : defaultColor;
446446
_console.Write(color);
447+
_console.Write(promptText);
448+
_console.Write("\x1b[0m");
449+
}
450+
else
451+
{
452+
_console.Write(promptText);
447453
}
448-
_console.Write(promptText);
449-
_console.Write("\x1b[0m");
450454
}
451455

452456
return true;

test/OptionsTest.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,45 @@ public void SetInvalidColorOptions()
131131
Assert.True(throws, "Invalid color value should throw");
132132
}
133133

134+
[SkippableFact]
135+
public void SetPromptTextOption()
136+
{
137+
// For prompt texts with VT sequences, reset all attributes if not already.
138+
string[] promptTexts_1 = new[] { "\x1b[91m> " };
139+
string[] promptTexts_2 = new[] { "\x1b[91m> ", "\x1b[92m> ", "\x1b[93m> " };
140+
string[] promptTexts_3 = new[] { "> " };
141+
string[] promptTexts_4 = new[] { "> ", "] " };
142+
string[] promptTexts_5 = new[] { "\x1b[93m> \x1b[0m" };
143+
144+
PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
145+
PromptText = promptTexts_1,
146+
});
147+
Assert.Equal("\x1b[91m> \x1b[0m", promptTexts_1[0]);
148+
149+
PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
150+
PromptText = promptTexts_2,
151+
});
152+
Assert.Equal("\x1b[91m> \x1b[0m", promptTexts_2[0]);
153+
Assert.Equal("\x1b[92m> \x1b[0m", promptTexts_2[1]);
154+
Assert.Equal("\x1b[93m> ", promptTexts_2[2]);
155+
156+
PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
157+
PromptText = promptTexts_3,
158+
});
159+
Assert.Equal("> ", promptTexts_3[0]);
160+
161+
PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
162+
PromptText = promptTexts_4,
163+
});
164+
Assert.Equal("> ", promptTexts_4[0]);
165+
Assert.Equal("] ", promptTexts_4[1]);
166+
167+
PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
168+
PromptText = promptTexts_5,
169+
});
170+
Assert.Equal("\x1b[93m> \x1b[0m", promptTexts_5[0]);
171+
}
172+
134173
[SkippableFact]
135174
[ExcludeFromCodeCoverage]
136175
public void UselessStuffForBetterCoverage()

0 commit comments

Comments
 (0)