Skip to content

Commit d6efcab

Browse files
authored
Set the current location in PredictionClient when it's supported (#3639)
1 parent 1e84d68 commit d6efcab

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

PSReadLine/Prediction.cs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
using System;
66
using System.Collections.Generic;
7+
using System.Reflection;
78
using System.Threading.Tasks;
89
using System.Management.Automation;
10+
using System.Management.Automation.Runspaces;
911
using System.Management.Automation.Language;
1012
using System.Management.Automation.Subsystem.Prediction;
1113
using System.Diagnostics.CodeAnalysis;
@@ -16,8 +18,42 @@ namespace Microsoft.PowerShell
1618
{
1719
public partial class PSConsoleReadLine
1820
{
19-
private const string PSReadLine = "PSReadLine";
20-
private static PredictionClient s_predictionClient = new(PSReadLine, PredictionClientKind.Terminal);
21+
private const string DefaultName = "PSReadLine";
22+
private static readonly PredictionClient s_predictionClient = new(DefaultName, PredictionClientKind.Terminal);
23+
private static PropertyInfo s_pCurrentLocation = null;
24+
25+
/// <summary>
26+
/// Initialize the <see cref="PropertyInfo"/> objects for those public settable properties newly added to
27+
/// <see cref="PredictionClient"/>.
28+
/// </summary>
29+
private static void InitializePropertyInfo()
30+
{
31+
Version ver = typeof(PSObject).Assembly.GetName().Version;
32+
if (ver.Major < 7 || ver.Minor < 4)
33+
{
34+
return;
35+
}
36+
37+
Type pcType = typeof(PredictionClient);
38+
// Property added in 7.4
39+
s_pCurrentLocation = pcType.GetProperty("CurrentLocation");
40+
}
41+
42+
/// <summary>
43+
/// New public settable properties may be added to the <see cref="PredictionClient"/> type as it evolves to
44+
/// offer more helpful context information. We dynamically set those properties here to avoid any backward
45+
/// compatibility issues.
46+
/// </summary>
47+
private static void UpdatePredictionClient(Runspace runspace, EngineIntrinsics engineIntrinsics)
48+
{
49+
// Set the current location if the 'CurrentLocation' property exists.
50+
if (s_pCurrentLocation is not null)
51+
{
52+
// Set the current location if it's a local Runspace. Otherwise, set it to null.
53+
object path = runspace.RunspaceIsRemote ? null : engineIntrinsics.SessionState.Path.CurrentLocation;
54+
s_pCurrentLocation.SetValue(s_predictionClient, path);
55+
}
56+
}
2157

2258
// Stub helper methods so prediction can be mocked
2359
[ExcludeFromCodeCoverage]

PSReadLine/ReadLine.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ static PSConsoleReadLine()
652652
{
653653
_singleton = new PSConsoleReadLine();
654654
_viRegister = new ViRegister(_singleton);
655+
InitializePropertyInfo();
655656
}
656657

657658
private PSConsoleReadLine()
@@ -682,13 +683,9 @@ private PSConsoleReadLine()
682683
{
683684
}
684685
}
685-
if (hostName == null)
686-
{
687-
hostName = PSReadLine;
688-
}
689686

690687
bool usingLegacyConsole = _console is PlatformWindows.LegacyWin32Console;
691-
_options = new PSConsoleReadLineOptions(hostName, usingLegacyConsole);
688+
_options = new PSConsoleReadLineOptions(hostName ?? DefaultName, usingLegacyConsole);
692689
_prediction = new Prediction(this);
693690
SetDefaultBindings(_options.EditMode);
694691
}
@@ -698,6 +695,9 @@ private void Initialize(Runspace runspace, EngineIntrinsics engineIntrinsics)
698695
_engineIntrinsics = engineIntrinsics;
699696
_runspace = runspace;
700697

698+
// Update the client instance per every call to PSReadLine.
699+
UpdatePredictionClient(runspace, engineIntrinsics);
700+
701701
if (!_delayedOneTimeInitCompleted)
702702
{
703703
DelayedOneTimeInitialize();

0 commit comments

Comments
 (0)