Skip to content

Commit

Permalink
Choose the inline prediction color based on the environment (#3808)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxian-dbw committed Sep 26, 2023
1 parent d98e1e6 commit d045b50
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
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 struct PROCESS_BASIC_INFORMATION
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

0 comments on commit d045b50

Please sign in to comment.