From 078a2b3cc4bcea5a07f0d08e1e11097a0ba48335 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 20 Sep 2021 09:26:12 -0700 Subject: [PATCH] Fix rendering when continuation prompt is an empty string (#2875) --- PSReadLine/Render.cs | 14 +++++++++-- test/RenderTest.cs | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/PSReadLine/Render.cs b/PSReadLine/Render.cs index 72ccbc27..f9787700 100644 --- a/PSReadLine/Render.cs +++ b/PSReadLine/Render.cs @@ -205,8 +205,11 @@ void RenderOneChar(char charToRender, bool toEmphasize) // the previous rendering string. activeColor = string.Empty; - UpdateColorsIfNecessary(Options._continuationPromptColor); - _consoleBufferLines[currentLogicalLine].Append(Options.ContinuationPrompt); + if (Options.ContinuationPrompt.Length > 0) + { + UpdateColorsIfNecessary(Options._continuationPromptColor); + _consoleBufferLines[currentLogicalLine].Append(Options.ContinuationPrompt); + } if (inSelectedRegion) { @@ -465,6 +468,13 @@ private bool RenderErrorPrompt(RenderData renderData, string defaultColor) /// private int PhysicalLineCount(int columns, bool isFirstLogicalLine, out int lenLastPhysicalLine) { + if (columns == 0) + { + // This could happen for a new logical line with an empty-string continuation prompt. + lenLastPhysicalLine = 0; + return 1; + } + int cnt = 1; int bufferWidth = _console.BufferWidth; diff --git a/test/RenderTest.cs b/test/RenderTest.cs index 1ef7b263..bfbffd28 100644 --- a/test/RenderTest.cs +++ b/test/RenderTest.cs @@ -203,6 +203,65 @@ public void MultiLine() _.Enter, CheckThat(() => AssertCursorLeftTopIs(0, 2)))); } + [SkippableFact] + public void MultiLine_ScreenCheck() + { + TestSetup(KeyMode.Cmd); + + var defaultContinuationPrompt = PSConsoleReadLineOptions.DefaultContinuationPrompt; + var defaultContinuationPromptColors = Tuple.Create(_console.ForegroundColor, _console.BackgroundColor); + + Test("@'\n\n hello\n\n world\n'@", + Keys( + "@'", _.Enter, _.Enter, + " hello", _.Enter, _.Enter, + " world", _.Enter, "'@", + CheckThat(() => AssertScreenIs(6, + TokenClassification.String, "@'", + NextLine, + defaultContinuationPromptColors, defaultContinuationPrompt, + NextLine, + defaultContinuationPromptColors, defaultContinuationPrompt, + TokenClassification.String, " hello", + NextLine, + defaultContinuationPromptColors, defaultContinuationPrompt, + NextLine, + defaultContinuationPromptColors, defaultContinuationPrompt, + TokenClassification.String, " world", + NextLine, + defaultContinuationPromptColors, defaultContinuationPrompt, + TokenClassification.String, "'@")) + )); + + string emptyLine = new string(' ', _console.BufferWidth); + // Set the continuation prompt to be an empty string. + var setOption = new SetPSReadLineOption { ContinuationPrompt = string.Empty }; + PSConsoleReadLine.SetOptions(setOption); + + try + { + Test("@'\n\n hello\n\n world\n'@", + Keys( + "@'", _.Enter, _.Enter, + " hello", _.Enter, _.Enter, + " world", _.Enter, "'@", + CheckThat(() => AssertScreenIs(6, + TokenClassification.String, "@'", NextLine, + TokenClassification.None, emptyLine, + TokenClassification.String, " hello", NextLine, + TokenClassification.None, emptyLine, + TokenClassification.String, " world", NextLine, + TokenClassification.String, "'@")) + )); + } + finally + { + // Restore to the default continuation prompt. + setOption.ContinuationPrompt = defaultContinuationPrompt; + PSConsoleReadLine.SetOptions(setOption); + } + } + [SkippableFact] public void LongLine() {