From 18743d9c88752f447060140e4a9a5f53905c11cf Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 15:48:02 -0500 Subject: [PATCH 1/6] add test --- .../UnitTests_Control/ControlCoreTests.cpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index 63f20f9058e..d33d6362a04 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -40,6 +40,7 @@ namespace ControlUnitTests TEST_METHOD(TestSelectCommandSimple); TEST_METHOD(TestSelectOutputSimple); + TEST_METHOD(TestCommandContext); TEST_METHOD(TestSelectOutputScrolling); TEST_METHOD(TestSelectOutputExactWrap); @@ -509,6 +510,54 @@ namespace ControlUnitTests VERIFY_ARE_EQUAL(expectedEnd, end); } } + void ControlCoreTests::TestCommandContext() + { + auto [settings, conn] = _createSettingsAndConnection(); + Log::Comment(L"Create ControlCore object"); + auto core = createCore(*settings, *conn); + VERIFY_IS_NOT_NULL(core); + _standardInit(core); + + Log::Comment(L"Print some text"); + + _writePrompt(conn, L"C:\\Windows"); + conn->WriteInput(L"Foo-bar"); + conn->WriteInput(L"\x1b]133;C\x7"); + + conn->WriteInput(L"\r\n"); + conn->WriteInput(L"This is some text \r\n"); + conn->WriteInput(L"with varying amounts \r\n"); + conn->WriteInput(L"of whitespace \r\n"); + + _writePrompt(conn, L"C:\\Windows"); + + Log::Comment(L"Check the command context"); + + const WEX::TestExecution::DisableVerifyExceptions disableExceptionsScope; + { + auto historyContext{ core->CommandHistory() }; + VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); + VERIFY_ARE_EQUAL(L"", historyContext.CurrentCommandline()); + } + + Log::Comment(L"Write 'Bar' to the command..."); + conn->WriteInput(L"Bar"); + { + auto historyContext{ core->CommandHistory() }; + VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); + VERIFY_ARE_EQUAL(L"Bar", historyContext.CurrentCommandline()); + } + + Log::Comment(L"then delete it"); + conn->WriteInput(L"\b \b"); + conn->WriteInput(L"\b \b"); + conn->WriteInput(L"\b \b"); + { + auto historyContext{ core->CommandHistory() }; + VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); + VERIFY_ARE_EQUAL(L"", historyContext.CurrentCommandline()); + } + } void ControlCoreTests::TestSelectOutputScrolling() { From b85eb30e4d1ccad08dfa7df892e13ae89e8a0801 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 15:58:58 -0500 Subject: [PATCH 2/6] okay this trims out the empties, but what about --- src/cascadia/TerminalControl/ControlCore.cpp | 22 ++++++++++++++----- .../UnitTests_Control/ControlCoreTests.cpp | 3 ++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 575864ede1a..073be049190 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -2235,19 +2235,29 @@ namespace winrt::Microsoft::Terminal::Control::implementation std::vector commands; const auto bufferCommands{ textBuffer.Commands() }; - for (const auto& commandInBuffer : bufferCommands) - { - const auto strEnd = commandInBuffer.find_last_not_of(UNICODE_SPACE); + + auto trimToHstring = [](const auto& s) -> winrt::hstring { + const auto strEnd = s.find_last_not_of(UNICODE_SPACE); if (strEnd != std::string::npos) { - const auto trimmed = commandInBuffer.substr(0, strEnd + 1); + const auto trimmed = s.substr(0, strEnd + 1); + return winrt::hstring{ trimmed }; + } + return winrt::hstring{ L"" }; + }; - commands.push_back(winrt::hstring{ trimmed }); + for (const auto& commandInBuffer : bufferCommands) + { + if (const auto hstr {trimToHstring(commandInBuffer)} ; !hstr.empty() ) + { + commands.push_back(hstr); } } auto context = winrt::make_self(std::move(commands)); - context->CurrentCommandline(winrt::hstring{ _terminal->CurrentCommand() }); + + const auto currentCommand = _terminal->CurrentCommand(); + context->CurrentCommandline(trimToHstring(currentCommand)); return *context; } diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index d33d6362a04..42b76cf4f67 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -21,7 +21,7 @@ namespace ControlUnitTests class ControlCoreTests { BEGIN_TEST_CLASS(ControlCoreTests) - TEST_CLASS_PROPERTY(L"TestTimeout", L"0:0:10") // 10s timeout + // TEST_CLASS_PROPERTY(L"TestTimeout", L"0:0:10") // 10s timeout END_TEST_CLASS() TEST_METHOD(ComPtrSettings); @@ -543,6 +543,7 @@ namespace ControlUnitTests Log::Comment(L"Write 'Bar' to the command..."); conn->WriteInput(L"Bar"); { + DebugBreak(); auto historyContext{ core->CommandHistory() }; VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); VERIFY_ARE_EQUAL(L"Bar", historyContext.CurrentCommandline()); From 0907c5071dafe5cf8da5851744b29be96ae42d80 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 16:11:22 -0500 Subject: [PATCH 3/6] ... this takes care of the current command also appearing in the history --- src/cascadia/TerminalControl/ControlCore.cpp | 19 ++++++++++++++----- .../UnitTests_Control/ControlCoreTests.cpp | 3 ++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 073be049190..2e1c5860af1 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -2246,19 +2246,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation return winrt::hstring{ L"" }; }; + const auto currentCommand = _terminal->CurrentCommand(); + const auto trimmedCurrentCommand = trimToHstring(currentCommand); + for (const auto& commandInBuffer : bufferCommands) { - if (const auto hstr {trimToHstring(commandInBuffer)} ; !hstr.empty() ) + if (const auto hstr{ trimToHstring(commandInBuffer) }; + (!hstr.empty() && hstr != trimmedCurrentCommand)) { commands.push_back(hstr); } } - auto context = winrt::make_self(std::move(commands)); - - const auto currentCommand = _terminal->CurrentCommand(); - context->CurrentCommandline(trimToHstring(currentCommand)); + // If the very last thing in the list of recent commands, is exacly the + // same as the current command, then let's not include it in the + // history. It's literally the thing the user has typed, RIGHT now. + if (commands.back() == trimmedCurrentCommand) + { + commands.pop_back(); + } + auto context = winrt::make_self(std::move(commands)); + context->CurrentCommandline(trimmedCurrentCommand); return *context; } diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index 42b76cf4f67..290b796177c 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -543,8 +543,8 @@ namespace ControlUnitTests Log::Comment(L"Write 'Bar' to the command..."); conn->WriteInput(L"Bar"); { - DebugBreak(); auto historyContext{ core->CommandHistory() }; + // Bar shouldn't be in the history, it should be the current command VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); VERIFY_ARE_EQUAL(L"Bar", historyContext.CurrentCommandline()); } @@ -556,6 +556,7 @@ namespace ControlUnitTests { auto historyContext{ core->CommandHistory() }; VERIFY_ARE_EQUAL(1u, historyContext.History().Size()); + // The current commandline is now empty VERIFY_ARE_EQUAL(L"", historyContext.CurrentCommandline()); } } From 7ac499b9d1c8152b288cff4089c166094cc8912f Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 16:16:20 -0500 Subject: [PATCH 4/6] fuck --- src/cascadia/UnitTests_Control/ControlCoreTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index 290b796177c..c9f2dbb2ae6 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -21,7 +21,7 @@ namespace ControlUnitTests class ControlCoreTests { BEGIN_TEST_CLASS(ControlCoreTests) - // TEST_CLASS_PROPERTY(L"TestTimeout", L"0:0:10") // 10s timeout + TEST_CLASS_PROPERTY(L"TestTimeout", L"0:0:10") // 10s timeout END_TEST_CLASS() TEST_METHOD(ComPtrSettings); From 320c8020f4f9c8d1970dbed8d5ded5a445844b94 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 16:37:39 -0500 Subject: [PATCH 5/6] derp --- src/cascadia/TerminalControl/ControlCore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 2e1c5860af1..dd7072d483a 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -2261,7 +2261,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // If the very last thing in the list of recent commands, is exacly the // same as the current command, then let's not include it in the // history. It's literally the thing the user has typed, RIGHT now. - if (commands.back() == trimmedCurrentCommand) + if (!commands.empty() && commands.back() == trimmedCurrentCommand) { commands.pop_back(); } From 831a1fe0816710974a289407a3d88c10c1449544 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 10 May 2024 16:49:20 -0500 Subject: [PATCH 6/6] exactly --- src/cascadia/TerminalControl/ControlCore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index dd7072d483a..c4ad4b0799d 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -2258,7 +2258,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - // If the very last thing in the list of recent commands, is exacly the + // If the very last thing in the list of recent commands, is exactly the // same as the current command, then let's not include it in the // history. It's literally the thing the user has typed, RIGHT now. if (!commands.empty() && commands.back() == trimmedCurrentCommand)