From eb00f2b6e2d76dba8115c6296df11aef264b30ab Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 27 Mar 2023 15:52:11 -0700 Subject: [PATCH 1/2] Set the current location in PredictionClient when it's supported --- PSReadLine/Prediction.cs | 37 ++++++++++++++++++++++++++++++++++++- PSReadLine/ReadLine.cs | 10 +++++----- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/PSReadLine/Prediction.cs b/PSReadLine/Prediction.cs index dfa1f1cce..a2d8ce210 100644 --- a/PSReadLine/Prediction.cs +++ b/PSReadLine/Prediction.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; using System.Management.Automation; +using System.Management.Automation.Runspaces; using System.Management.Automation.Language; using System.Management.Automation.Subsystem.Prediction; using System.Diagnostics.CodeAnalysis; @@ -17,7 +19,40 @@ namespace Microsoft.PowerShell public partial class PSConsoleReadLine { private const string PSReadLine = "PSReadLine"; - private static PredictionClient s_predictionClient = new(PSReadLine, PredictionClientKind.Terminal); + private static readonly PredictionClient s_predictionClient = new(PSReadLine, PredictionClientKind.Terminal); + private static PropertyInfo s_pCurrentLocation = null; + + /// + /// Initialize the objects for those public settable properties newly added to + /// . + /// + private static void InitializePropertyInfo() + { + Version ver = typeof(PSObject).Assembly.GetName().Version; + if (ver.Major < 7 || ver.Minor < 4) + { + return; + } + + Type pcType = typeof(PredictionClient); + s_pCurrentLocation = pcType.GetProperty("CurrentLocation"); + } + + /// + /// New public settable properties may be added to the type as it evolves to + /// offer more helpful context information. We dynamically set those properties here to avoid any backward + /// compatibility issues. + /// + private static void UpdatePredictionClient(Runspace runspace, EngineIntrinsics engineIntrinsics) + { + // Set the current location if the 'CurrentLocation' property exists. + if (s_pCurrentLocation is not null) + { + // Set the current location if it's a local Runspace. Otherwise, set it to null. + object path = runspace.RunspaceIsRemote ? null : engineIntrinsics.SessionState.Path.CurrentLocation; + s_pCurrentLocation.SetValue(s_predictionClient, path); + } + } // Stub helper methods so prediction can be mocked [ExcludeFromCodeCoverage] diff --git a/PSReadLine/ReadLine.cs b/PSReadLine/ReadLine.cs index 33b65d06d..6bf0b9954 100644 --- a/PSReadLine/ReadLine.cs +++ b/PSReadLine/ReadLine.cs @@ -652,6 +652,7 @@ static PSConsoleReadLine() { _singleton = new PSConsoleReadLine(); _viRegister = new ViRegister(_singleton); + InitializePropertyInfo(); } private PSConsoleReadLine() @@ -682,13 +683,9 @@ private PSConsoleReadLine() { } } - if (hostName == null) - { - hostName = PSReadLine; - } bool usingLegacyConsole = _console is PlatformWindows.LegacyWin32Console; - _options = new PSConsoleReadLineOptions(hostName, usingLegacyConsole); + _options = new PSConsoleReadLineOptions(hostName ?? PSReadLine, usingLegacyConsole); _prediction = new Prediction(this); SetDefaultBindings(_options.EditMode); } @@ -698,6 +695,9 @@ private void Initialize(Runspace runspace, EngineIntrinsics engineIntrinsics) _engineIntrinsics = engineIntrinsics; _runspace = runspace; + // Update the client instance per every call to PSReadLine. + UpdatePredictionClient(runspace, engineIntrinsics); + if (!_delayedOneTimeInitCompleted) { DelayedOneTimeInitialize(); From 5d595c1d4acddc316697405a2d80aa333c16bb21 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 27 Mar 2023 16:01:29 -0700 Subject: [PATCH 2/2] Minor updates --- PSReadLine/Prediction.cs | 5 +++-- PSReadLine/ReadLine.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/PSReadLine/Prediction.cs b/PSReadLine/Prediction.cs index a2d8ce210..fc790f948 100644 --- a/PSReadLine/Prediction.cs +++ b/PSReadLine/Prediction.cs @@ -18,8 +18,8 @@ namespace Microsoft.PowerShell { public partial class PSConsoleReadLine { - private const string PSReadLine = "PSReadLine"; - private static readonly PredictionClient s_predictionClient = new(PSReadLine, PredictionClientKind.Terminal); + private const string DefaultName = "PSReadLine"; + private static readonly PredictionClient s_predictionClient = new(DefaultName, PredictionClientKind.Terminal); private static PropertyInfo s_pCurrentLocation = null; /// @@ -35,6 +35,7 @@ private static void InitializePropertyInfo() } Type pcType = typeof(PredictionClient); + // Property added in 7.4 s_pCurrentLocation = pcType.GetProperty("CurrentLocation"); } diff --git a/PSReadLine/ReadLine.cs b/PSReadLine/ReadLine.cs index 6bf0b9954..3b042a448 100644 --- a/PSReadLine/ReadLine.cs +++ b/PSReadLine/ReadLine.cs @@ -685,7 +685,7 @@ private PSConsoleReadLine() } bool usingLegacyConsole = _console is PlatformWindows.LegacyWin32Console; - _options = new PSConsoleReadLineOptions(hostName ?? PSReadLine, usingLegacyConsole); + _options = new PSConsoleReadLineOptions(hostName ?? DefaultName, usingLegacyConsole); _prediction = new Prediction(this); SetDefaultBindings(_options.EditMode); }