Skip to content

Commit 5743bec

Browse files
Utilize the AddToHistory delegate from PSRL proxy (#1823)
1 parent 8a2bd1c commit 5743bec

File tree

6 files changed

+44
-1
lines changed

6 files changed

+44
-1
lines changed

src/PowerShellEditorServices/Services/PowerShell/Console/IReadLine.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Console
99
internal interface IReadLine
1010
{
1111
string ReadLine(CancellationToken cancellationToken);
12+
13+
void AddToHistory(string historyEntry);
1214
}
1315
}

src/PowerShellEditorServices/Services/PowerShell/Console/PsrlReadLine.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public override string ReadLine(CancellationToken cancellationToken) => _psesHos
3838
InvokePSReadLine,
3939
cancellationToken);
4040

41+
public override void AddToHistory(string historyEntry) => _psrlProxy.AddToHistory(historyEntry);
42+
4143
protected override ConsoleKeyInfo ReadKey(CancellationToken cancellationToken) => _psesHost.ReadKey(intercept: true, cancellationToken);
4244

4345
private string InvokePSReadLine(CancellationToken cancellationToken)

src/PowerShellEditorServices/Services/PowerShell/Console/TerminalReadLine.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Console
99

1010
internal abstract class TerminalReadLine : IReadLine
1111
{
12+
public virtual void AddToHistory(string historyEntry)
13+
{
14+
// No-op by default. If the ReadLine provider is not PSRL then history is automatically
15+
// added as part of the invocation process.
16+
}
17+
1218
public abstract string ReadLine(CancellationToken cancellationToken);
1319

1420
protected abstract ConsoleKeyInfo ReadKey(CancellationToken cancellationToken);

src/PowerShellEditorServices/Services/PowerShell/Execution/ExecutionOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ public record PowerShellExecutionOptions : ExecutionOptions
3434
public bool WriteInputToHost { get; init; }
3535
public bool ThrowOnError { get; init; } = true;
3636
public bool AddToHistory { get; init; }
37+
internal bool FromRepl { get; init; }
3738
}
3839
}

src/PowerShellEditorServices/Services/PowerShell/Execution/SynchronousPowerShellTask.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ private static bool IsPromptCommand(PSCommand command)
9595
private IReadOnlyList<TResult> ExecuteNormally(CancellationToken cancellationToken)
9696
{
9797
_frame = _psesHost.CurrentFrame;
98+
MaybeAddToHistory(_psCommand);
9899
if (PowerShellExecutionOptions.WriteOutputToHost)
99100
{
100101
_psCommand.AddOutputCommand();
@@ -187,6 +188,7 @@ private IReadOnlyList<TResult> ExecuteInDebugger(CancellationToken cancellationT
187188
cancellationToken.Register(CancelDebugExecution);
188189

189190
PSDataCollection<PSObject> outputCollection = new();
191+
MaybeAddToHistory(_psCommand);
190192

191193
// Out-Default doesn't work as needed in the debugger
192194
// Instead we add Out-String to the command and collect results in a PSDataCollection
@@ -353,6 +355,33 @@ private void CancelNormalExecution()
353355
}
354356
}
355357

358+
private void MaybeAddToHistory(PSCommand command)
359+
{
360+
// Do not add PSES internal commands to history. Also exclude input that came from the
361+
// REPL (e.g. PSReadLine) as it handles history itself in that scenario.
362+
if (PowerShellExecutionOptions is { AddToHistory: false } or { FromRepl: true })
363+
{
364+
return;
365+
}
366+
367+
// Only add pure script commands with no arguments to interactive history.
368+
if (command.Commands is { Count: not 1 }
369+
|| command.Commands[0] is { Parameters.Count: not 0 } or { IsScript: false })
370+
{
371+
return;
372+
}
373+
374+
try
375+
{
376+
_psesHost.AddToHistory(command.Commands[0].CommandText);
377+
}
378+
catch
379+
{
380+
// Ignore exceptions as the user can register a scriptblock predicate that
381+
// determines if the command should be added to history.
382+
}
383+
}
384+
356385
private void CancelDebugExecution()
357386
{
358387
if (_pwsh.Runspace.RunspaceStateInfo.IsUsable())

src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ public void InvokePSDelegate(string representation, ExecutionOptions executionOp
446446
task.ExecuteAndGetResult(cancellationToken);
447447
}
448448

449+
internal void AddToHistory(string historyEntry) => _readLineProvider.ReadLine.AddToHistory(historyEntry);
450+
449451
internal Task LoadHostProfilesAsync(CancellationToken cancellationToken)
450452
{
451453
// NOTE: This is a special task run on startup!
@@ -918,7 +920,8 @@ private void InvokeInput(string input, CancellationToken cancellationToken)
918920
{
919921
AddToHistory = true,
920922
ThrowOnError = false,
921-
WriteOutputToHost = true
923+
WriteOutputToHost = true,
924+
FromRepl = true,
922925
},
923926
cancellationToken);
924927
}

0 commit comments

Comments
 (0)