Skip to content

Commit 212f43e

Browse files
authored
Fix hyperlinks using an extra character at the end (microsoft#17326)
Closes: microsoft#17323 ## Validation Steps Performed - Run `echo Hello ^(https://github.com/microsoft/terminal^)` in cmd. - Ctrl+click on the URL opens `https://github.com/microsoft/terminal` in the browser. - Hovering over the url in the terminal shows `https://github.com/microsoft/terminal` in the hover UI.
1 parent 5d1cf1a commit 212f43e

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/cascadia/TerminalCore/Terminal.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,10 @@ std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
522522
// Case 2 - Step 2: get the auto-detected hyperlink
523523
if (result.has_value() && result->value == _hyperlinkPatternId)
524524
{
525+
// GetPlainText works with inclusive coordinates, but interval's stop
526+
// point is (horizontally) exclusive, so let's just update it.
527+
result->stop.x--;
528+
525529
return _activeBuffer().GetPlainText(result->start, result->stop);
526530
}
527531
return {};

src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class TerminalCoreUnitTests::TerminalBufferTests final
5151

5252
TEST_METHOD(TestGetReverseTab);
5353

54+
TEST_METHOD(TestURLPatternDetection);
55+
5456
TEST_METHOD_SETUP(MethodSetup)
5557
{
5658
// STEP 1: Set up the Terminal
@@ -594,3 +596,34 @@ void TerminalBufferTests::TestGetReverseTab()
594596
L"Cursor adjusted to last item in the sample list from position beyond end.");
595597
}
596598
}
599+
600+
void TerminalBufferTests::TestURLPatternDetection()
601+
{
602+
using namespace std::string_view_literals;
603+
604+
constexpr auto BeforeStr = L"<Before>"sv;
605+
constexpr auto UrlStr = L"https://www.contoso.com"sv;
606+
constexpr auto AfterStr = L"<After>"sv;
607+
constexpr auto urlStartX = BeforeStr.size();
608+
constexpr auto urlEndX = BeforeStr.size() + UrlStr.size() - 1;
609+
610+
auto& termSm = *term->_stateMachine;
611+
termSm.ProcessString(fmt::format(FMT_COMPILE(L"{}{}{}"), BeforeStr, UrlStr, AfterStr));
612+
term->UpdatePatternsUnderLock();
613+
614+
std::wstring result;
615+
616+
result = term->GetHyperlinkAtBufferPosition(til::point{ urlStartX - 1, 0 });
617+
VERIFY_IS_TRUE(result.empty(), L"URL is not detected before the actual URL.");
618+
619+
result = term->GetHyperlinkAtBufferPosition(til::point{ urlStartX, 0 });
620+
VERIFY_IS_TRUE(!result.empty(), L"A URL is detected at the start position.");
621+
VERIFY_ARE_EQUAL(result, UrlStr, L"Detected URL matches the given URL.");
622+
623+
result = term->GetHyperlinkAtBufferPosition(til::point{ urlEndX, 0 });
624+
VERIFY_IS_TRUE(!result.empty(), L"A URL is detected at the end position.");
625+
VERIFY_ARE_EQUAL(result, UrlStr, L"Detected URL matches the given URL.");
626+
627+
result = term->GetHyperlinkAtBufferPosition(til::point{ urlEndX + 1, 0 });
628+
VERIFY_IS_TRUE(result.empty(), L"URL is not detected after the actual URL.");
629+
}

0 commit comments

Comments
 (0)