From 40f934d07eb20445e811c6e86228d745700917ec Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 16 Jan 2020 22:46:30 -0800 Subject: [PATCH 1/7] Fix debugging output location --- .../PowerShellContext/PowerShellContextService.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 30eff8760..014632a2e 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -1076,9 +1076,19 @@ public async Task ExecuteScriptWithArgsAsync(string script, string arguments = n if (writeInputToHost) { + // We need to abort ReadLine first because otherwise PSReadLine will attempt to reset + // the cursor position to the position it's at before the call to this.WriteOutput(...) below. + if (this.isPSReadLineEnabled) + { + this.PromptContext.AbortReadLine(); + } + + // TODO: Figure out why with PSReadLine turned on, we get a random newline somewhere in our output. + // It appears to happen at this line but more testing needs to be done: + // https://github.com/PowerShell/PowerShellEditorServices/blob/3b890c3018b0ef8d92d77edf1215d345d55604eb/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs#L148 this.WriteOutput( - script + Environment.NewLine, - true); + script, + includeNewLine: true); } await this.ExecuteCommandAsync( From 1987454be29faa1287e2a414f5fc557987d93468 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 21 Jan 2020 15:22:50 -0800 Subject: [PATCH 2/7] gets rid of a rouge newline --- .../Session/Host/EditorServicesPSHostUserInterface.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs index adb20b7ef..edb8f8890 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs @@ -848,14 +848,6 @@ private async Task StartReplLoopAsync(CancellationToken cancellationToken) Logger.LogException("Caught exception while reading command line", e); } - finally - { - if (!cancellationToken.IsCancellationRequested && - originalCursorTop == await ConsoleProxy.GetCursorTopAsync(cancellationToken).ConfigureAwait(false)) - { - this.WriteLine(); - } - } if (!string.IsNullOrWhiteSpace(commandString)) { From aab821aa7044a30864395231be3910c97b5a4baa Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 21 Jan 2020 15:26:13 -0800 Subject: [PATCH 3/7] update comment --- .../Services/PowerShellContext/PowerShellContextService.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 014632a2e..1202062cb 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -1083,9 +1083,8 @@ public async Task ExecuteScriptWithArgsAsync(string script, string arguments = n this.PromptContext.AbortReadLine(); } - // TODO: Figure out why with PSReadLine turned on, we get a random newline somewhere in our output. - // It appears to happen at this line but more testing needs to be done: - // https://github.com/PowerShell/PowerShellEditorServices/blob/3b890c3018b0ef8d92d77edf1215d345d55604eb/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs#L148 + // Write the script path out and include a newline to start so the output can start + // on the next line. this.WriteOutput( script, includeNewLine: true); From 492041e67426986a9e1e0036a89d3dfcf291b048 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 21 Jan 2020 17:06:13 -0800 Subject: [PATCH 4/7] don't use this.WriteOutput at all --- .../PowerShellContextService.cs | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 1202062cb..c26bb277c 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -680,7 +680,9 @@ public async Task> ExecuteCommandAsync( runspaceHandle = await this.GetRunspaceHandleAsync(executionOptions.IsReadLine).ConfigureAwait(false); if (executionOptions.WriteInputToHost) { - this.WriteOutput(psCommand.Commands[0].CommandText, true); + this.WriteOutput( + psCommand.Commands[0].CommandText, + includeNewLine: true); } if (executionTarget == ExecutionTarget.Debugger) @@ -1074,27 +1076,17 @@ public async Task ExecuteScriptWithArgsAsync(string script, string arguments = n command.AddCommand(script, false); } - if (writeInputToHost) - { - // We need to abort ReadLine first because otherwise PSReadLine will attempt to reset - // the cursor position to the position it's at before the call to this.WriteOutput(...) below. - if (this.isPSReadLineEnabled) - { - this.PromptContext.AbortReadLine(); - } - - // Write the script path out and include a newline to start so the output can start - // on the next line. - this.WriteOutput( - script, - includeNewLine: true); - } await this.ExecuteCommandAsync( - command, - errorMessages: null, - sendOutputToHost: true, - addToHistory: true).ConfigureAwait(false); + command, + errorMessages: null, + new ExecutionOptions + { + WriteInputToHost = true, + WriteOutputToHost = true, + WriteErrorsToHost = true, + AddToHistory = true, + }).ConfigureAwait(false); } /// From e33f985066959d8606d68643e539837ae6830777 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 22 Jan 2020 09:22:05 -0800 Subject: [PATCH 5/7] Bring back finally for Legacy ReadLine --- .../PowerShellContextService.cs | 2 +- .../Host/EditorServicesPSHostUserInterface.cs | 16 ++++++++++++++++ .../Session/Host/ProtocolPSHostUserInterface.cs | 6 +++++- .../Session/Host/TerminalPSHostUserInterface.cs | 8 +++++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index c26bb277c..6780b019a 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -199,7 +199,7 @@ public static PowerShellContextService Create( EditorServicesPSHostUserInterface hostUserInterface = hostStartupInfo.ConsoleReplEnabled - ? (EditorServicesPSHostUserInterface)new TerminalPSHostUserInterface(powerShellContext, logger, hostStartupInfo.PSHost) + ? (EditorServicesPSHostUserInterface) new TerminalPSHostUserInterface(powerShellContext, hostStartupInfo.PSHost, shouldUsePSReadLine, logger) : new ProtocolPSHostUserInterface(languageServer, powerShellContext, logger); EditorServicesPSHost psHost = diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs index edb8f8890..bb417b70d 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs @@ -37,6 +37,7 @@ public abstract class EditorServicesPSHostUserInterface : private PromptHandler activePromptHandler; private PSHostRawUserInterface rawUserInterface; private CancellationTokenSource commandLoopCancellationToken; + private bool _isPSReadLineEnabled; /// /// The PowerShellContext to use for executing commands. @@ -104,11 +105,13 @@ public abstract class EditorServicesPSHostUserInterface : public EditorServicesPSHostUserInterface( PowerShellContextService powerShellContext, PSHostRawUserInterface rawUserInterface, + bool isPSReadLineEnabled, ILogger logger) { this.Logger = logger; this.powerShellContext = powerShellContext; this.rawUserInterface = rawUserInterface; + _isPSReadLineEnabled = isPSReadLineEnabled; this.powerShellContext.DebuggerStop += PowerShellContext_DebuggerStop; this.powerShellContext.DebuggerResumed += PowerShellContext_DebuggerResumed; @@ -848,6 +851,19 @@ private async Task StartReplLoopAsync(CancellationToken cancellationToken) Logger.LogException("Caught exception while reading command line", e); } + finally + { + // This supplies the newline in the Legacy ReadLine when executing code in the terminal via hitting the ENTER key. + // Without this, hitting ENTER with a no input looks like it does nothing (no new prompt is written) + // and also the output would show up on the same line as the code you wanted to execute (the prompt line). + // Since PSReadLine handles ENTER internally to itself, we only want to do this when using the Legacy ReadLine. + if (!_isPSReadLineEnabled && + !cancellationToken.IsCancellationRequested && + originalCursorTop == await ConsoleProxy.GetCursorTopAsync(cancellationToken).ConfigureAwait(false)) + { + this.WriteLine(); + } + } if (!string.IsNullOrWhiteSpace(commandString)) { diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/ProtocolPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/ProtocolPSHostUserInterface.cs index 6053245c2..32415922e 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/ProtocolPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/ProtocolPSHostUserInterface.cs @@ -30,7 +30,11 @@ public ProtocolPSHostUserInterface( ILanguageServer languageServer, PowerShellContextService powerShellContext, ILogger logger) - : base(powerShellContext, new SimplePSHostRawUserInterface(logger), logger) + : base ( + powerShellContext, + new SimplePSHostRawUserInterface(logger), + isPSReadLineEnabled: false, + logger) { _languageServer = languageServer; } diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs index 93e8173ad..ce6edee46 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/TerminalPSHostUserInterface.cs @@ -37,11 +37,13 @@ public class TerminalPSHostUserInterface : EditorServicesPSHostUserInterface /// The InternalHost instance from the origin runspace. public TerminalPSHostUserInterface( PowerShellContextService powerShellContext, - ILogger logger, - PSHost internalHost) - : base( + PSHost internalHost, + bool isPSReadLineEnabled, + ILogger logger) + : base ( powerShellContext, new TerminalPSHostRawUserInterface(logger, internalHost), + isPSReadLineEnabled, logger) { this.internalHostUI = internalHost.UI; From b63acf2049e73fb6d89bddd158e321d730f5de2c Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 22 Jan 2020 10:13:15 -0800 Subject: [PATCH 6/7] codacy --- .../Session/Host/EditorServicesPSHostUserInterface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs index bb417b70d..fc76e1645 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs @@ -37,7 +37,7 @@ public abstract class EditorServicesPSHostUserInterface : private PromptHandler activePromptHandler; private PSHostRawUserInterface rawUserInterface; private CancellationTokenSource commandLoopCancellationToken; - private bool _isPSReadLineEnabled; + private readonly bool _isPSReadLineEnabled; /// /// The PowerShellContext to use for executing commands. From c7cdca694f9f3f8cc65c5062bfaf1146d54d6ae7 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 23 Jan 2020 09:10:37 -0800 Subject: [PATCH 7/7] patrick feedback --- .../Session/Host/EditorServicesPSHostUserInterface.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs index fc76e1645..7cd740931 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/EditorServicesPSHostUserInterface.cs @@ -34,10 +34,11 @@ public abstract class EditorServicesPSHostUserInterface : private readonly ConcurrentDictionary currentProgressMessages = new ConcurrentDictionary(); + + private readonly bool _isPSReadLineEnabled; private PromptHandler activePromptHandler; private PSHostRawUserInterface rawUserInterface; private CancellationTokenSource commandLoopCancellationToken; - private readonly bool _isPSReadLineEnabled; /// /// The PowerShellContext to use for executing commands.