From c60dfbd8a4327ca53aebfe05753fa18ffff16700 Mon Sep 17 00:00:00 2001 From: Chester Liu Date: Fri, 29 Jan 2021 13:26:19 +0800 Subject: [PATCH 1/2] Improve OSC 9;9 parsing logic & add tests --- .../TerminalCore/TerminalDispatch.cpp | 14 ++++- .../TerminalApiTest.cpp | 57 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 533c62120b0..ed5437f301b 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -474,7 +474,19 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept { if (parts.size() >= 2) { - return _terminalApi.SetWorkingDirectory(til::at(parts, 1)); + const auto path = til::at(parts, 1); + // The path should be surrounded with '"' according to the documentation of ConEmu. + // An example: 9;"D:/" + if (path.at(0) == L'"' && path.at(path.size() - 1) == L'"' && path.size() >= 3) + { + return _terminalApi.SetWorkingDirectory(path.substr(1, path.size() - 2)); + } + else + { + // If we fail to find the surrouding quotation marks, we'll give the path a try anyway. + // ConEmu also does this. + return _terminalApi.SetWorkingDirectory(path); + } } } diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index 2060e444c2e..935a468fefc 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -40,6 +40,7 @@ namespace TerminalCoreUnitTests TEST_METHOD(AddHyperlinkCustomIdDifferentUri); TEST_METHOD(SetTaskbarProgress); + TEST_METHOD(SetWorkingDirectory); }; }; @@ -388,3 +389,59 @@ void TerminalCoreUnitTests::TerminalApiTest::SetTaskbarProgress() VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(1)); VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(80)); } + +void TerminalCoreUnitTests::TerminalApiTest::SetWorkingDirectory() +{ + Terminal term; + DummyRenderTarget emptyRT; + term.Create({ 100, 100 }, 0, emptyRT); + + auto& stateMachine = *(term._stateMachine); + + // Test setting working directory using OSC 9;9 + // Initial CWD should be empty + VERIFY_IS_TRUE(term.GetWorkingDirectory().empty()); + + // Invalid sequences should not change CWD + stateMachine.ProcessString(L"\x1b]9;9\x9c"); + VERIFY_IS_TRUE(term.GetWorkingDirectory().empty()); + + stateMachine.ProcessString(L"\x1b]9;9\"\x9c"); + VERIFY_IS_TRUE(term.GetWorkingDirectory().empty()); + + stateMachine.ProcessString(L"\x1b]9;9\"C:\\\"\x9c"); + VERIFY_IS_TRUE(term.GetWorkingDirectory().empty()); + + // Valid sequences should change CWD + stateMachine.ProcessString(L"\x1b]9;9;\"C:\\\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\"); + + stateMachine.ProcessString(L"\x1b]9;9;\"C:\\Program Files\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\Program Files"); + + stateMachine.ProcessString(L"\x1b]9;9;\"D:\\中文\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"D:\\中文"); + + // Test OSC 9;9 sequences without quotation marks + stateMachine.ProcessString(L"\x1b]9;9;C:\\\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\"); + + stateMachine.ProcessString(L"\x1b]9;9;C:\\Program Files\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\Program Files"); + + stateMachine.ProcessString(L"\x1b]9;9;D:\\中文\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"D:\\中文"); + + // These OSC 9;9 sequences will result in invalid CWD. We shouldn't crash on these. + stateMachine.ProcessString(L"\x1b]9;9;\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\""); + + stateMachine.ProcessString(L"\x1b]9;9;\"\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"\""); + + stateMachine.ProcessString(L"\x1b]9;9;\"\"\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\""); + + stateMachine.ProcessString(L"\x1b]9;9;\"\"\"\"\x9c"); + VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"\""); +} From 66ce9e2917aa2fb81cf3bbf6613f3a15e643b87e Mon Sep 17 00:00:00 2001 From: Chester Liu Date: Tue, 2 Feb 2021 09:51:26 +0800 Subject: [PATCH 2/2] typo --- src/cascadia/TerminalCore/TerminalDispatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index ed5437f301b..a8a73979519 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -483,7 +483,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept } else { - // If we fail to find the surrouding quotation marks, we'll give the path a try anyway. + // If we fail to find the surrounding quotation marks, we'll give the path a try anyway. // ConEmu also does this. return _terminalApi.SetWorkingDirectory(path); }