Skip to content

Choose the inline prediction color based on the environment #3808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 26, 2023
Merged
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
55 changes: 41 additions & 14 deletions PSReadLine/Cmdlets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,14 @@ public class PSConsoleReadLineOptions

// Find the most suitable color using https://stackoverflow.com/a/33206814
// Default prediction color settings:
// - use FG color 'dim white italic' for the inline-view suggestion text
// - use FG color 'yellow' for the list-view suggestion text
// - use BG color 'dark black' for the selected list-view suggestion text
public const string DefaultInlinePredictionColor = "\x1b[97;2;3m";
public const string DefaultListPredictionColor = "\x1b[33m";
public const string DefaultListPredictionSelectedColor = "\x1b[48;5;238m";
public const string DefaultListPredictionTooltipColor = "\x1b[97;2;3m";

public static EditMode DefaultEditMode = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? EditMode.Windows
: EditMode.Emacs;
public static readonly string DefaultInlinePredictionColor;
public static readonly string DefaultListPredictionTooltipColor;
public static readonly EditMode DefaultEditMode;

public const string DefaultContinuationPrompt = ">> ";

Expand Down Expand Up @@ -166,6 +163,40 @@ public class PSConsoleReadLineOptions
/// </summary>
public const int DefaultAnsiEscapeTimeout = 100;

static PSConsoleReadLineOptions()
{
// For inline-view suggestion text, we use the new FG color 'dim white italic' when possible, because it provides
// sufficient contrast in terminals that don't use a pure black background (like VSCode terminal).
// However, on Windows 10 and Windows Server, the ConHost doesn't support font effect VT sequences, such as 'dim'
// and 'italic', so we need to use the old FG color 'dark black' as in the v2.2.6.
const string newInlinePredictionColor = "\x1b[97;2;3m";
const string oldInlinePredictionColor = "\x1b[38;5;238m";

ColorSetters = null;
DefaultEditMode = EditMode.Emacs;
DefaultInlinePredictionColor = newInlinePredictionColor;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
DefaultEditMode = EditMode.Windows;

// Our tests expect that the default inline-view color is set to the new color, so we configure
// the color based on system environment only if we are not in test runs.
if (AppDomain.CurrentDomain.FriendlyName is not "PSReadLine.Tests")
{
DefaultInlinePredictionColor =
Environment.OSVersion.Version.Build >= 22621 // on Windows 11 22H2 or newer versions
|| Environment.GetEnvironmentVariable("WT_SESSION") is not null // in Windows Terminal
? newInlinePredictionColor
: oldInlinePredictionColor;
}
}

// Use the same color for the list prediction tooltips.
DefaultListPredictionTooltipColor = DefaultInlinePredictionColor;
DefaultAddToHistoryHandler = s => PSConsoleReadLine.GetDefaultAddToHistoryOption(s);
}

public PSConsoleReadLineOptions(string hostName, bool usingLegacyConsole)
{
ResetColors();
Expand Down Expand Up @@ -285,8 +316,7 @@ public object ContinuationPromptColor
/// or added to memory only, or added to both memory and history file.
/// </summary>
public Func<string, object> AddToHistoryHandler { get; set; }
public static readonly Func<string, object> DefaultAddToHistoryHandler =
s => PSConsoleReadLine.GetDefaultAddToHistoryOption(s);
public static readonly Func<string, object> DefaultAddToHistoryHandler;

/// <summary>
/// This handler is called from ValidateAndAcceptLine.
Expand All @@ -305,7 +335,6 @@ public object ContinuationPromptColor
/// odd things with script blocks, we create a white-list of commands
/// that do invoke the script block - this covers the most useful cases.
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public HashSet<string> CommandsToValidateScriptBlockArguments { get; set; }

/// <summary>
Expand Down Expand Up @@ -555,7 +584,7 @@ internal void ResetColors()
SelectionColor = VTColorUtils.AsEscapeSequence(bg, fg);
}

private static Dictionary<string, Action<PSConsoleReadLineOptions, object>> ColorSetters = null;
private static Dictionary<string, Action<PSConsoleReadLineOptions, object>> ColorSetters;

internal void SetColor(string property, object value)
{
Expand Down Expand Up @@ -830,7 +859,6 @@ public class ChangePSReadLineKeyHandlerCommandBase : PSCmdlet
[Parameter(Position = 0, Mandatory = true)]
[Alias("Key")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Chord { get; set; }

[Parameter]
Expand Down Expand Up @@ -903,8 +931,7 @@ protected override void EndProcessing()
}
}

private readonly Lazy<RuntimeDefinedParameterDictionary> _dynamicParameters =
new Lazy<RuntimeDefinedParameterDictionary>(CreateDynamicParametersResult);
private readonly Lazy<RuntimeDefinedParameterDictionary> _dynamicParameters = new(CreateDynamicParametersResult);

private static RuntimeDefinedParameterDictionary CreateDynamicParametersResult()
{
Expand Down Expand Up @@ -1027,7 +1054,7 @@ public static class VTColorUtils

public const ConsoleColor UnknownColor = (ConsoleColor) (-1);
private static readonly Dictionary<string, ConsoleColor> ConsoleColors =
new Dictionary<string, ConsoleColor>(StringComparer.OrdinalIgnoreCase)
new(StringComparer.OrdinalIgnoreCase)
{
{"Black", ConsoleColor.Black},
{"DarkBlue", ConsoleColor.DarkBlue},
Expand Down
5 changes: 1 addition & 4 deletions PSReadLine/PlatformWindows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,7 @@ internal static extern int NtQueryInformationProcess(
internal static int GetParentPid(Process process)
{
// (This is how ProcessCodeMethods in pwsh does it.)
PROCESS_BASIC_INFORMATION pbi;
int size;
var res = NtQueryInformationProcess(process.Handle, 0, out pbi, Marshal.SizeOf<PROCESS_BASIC_INFORMATION>(), out size);

var res = NtQueryInformationProcess(process.Handle, 0, out PROCESS_BASIC_INFORMATION pbi, Marshal.SizeOf<PROCESS_BASIC_INFORMATION>(), out _);
return res != 0 ? InvalidProcessId : pbi.InheritedFromUniqueProcessId.ToInt32();
}

Expand Down
2 changes: 0 additions & 2 deletions PSReadLine/ReadLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

namespace Microsoft.PowerShell
{
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")]
[SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable")]
class ExitException : Exception { }

public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods
Expand Down