diff --git a/util/tests/test_texteditorhelpers.cpp b/util/tests/test_texteditorhelpers.cpp --- a/util/tests/test_texteditorhelpers.cpp +++ b/util/tests/test_texteditorhelpers.cpp @@ -60,9 +60,33 @@ << QStringLiteral("widget.cpp:12:5") << KTextEditor::Cursor(11, 4) << QStringLiteral("widget.cpp"); + QTest::newRow("file:line") + << QStringLiteral("widget.cpp#12") + << KTextEditor::Cursor(11, 0) + << QStringLiteral("widget.cpp"); + QTest::newRow("file:line") + << QStringLiteral("widget.cpp#L12") + << KTextEditor::Cursor(11, 0) + << QStringLiteral("widget.cpp"); + QTest::newRow("file:line") + << QStringLiteral("widget.cpp#n12") + << KTextEditor::Cursor(11, 0) + << QStringLiteral("widget.cpp"); // partially invalid input QTest::newRow("file:") << QStringLiteral("widget.cpp:") << KTextEditor::Cursor::invalid() << QStringLiteral("widget.cpp:"); + QTest::newRow("file:") + << QStringLiteral("widget.cpp#") + << KTextEditor::Cursor::invalid() + << QStringLiteral("widget.cpp#"); + QTest::newRow("file:") + << QStringLiteral("widget.cpp#L") + << KTextEditor::Cursor::invalid() + << QStringLiteral("widget.cpp#L"); + QTest::newRow("file:") + << QStringLiteral("widget.cpp#n") + << KTextEditor::Cursor::invalid() + << QStringLiteral("widget.cpp#n"); } diff --git a/util/texteditorhelpers.cpp b/util/texteditorhelpers.cpp --- a/util/texteditorhelpers.cpp +++ b/util/texteditorhelpers.cpp @@ -53,15 +53,25 @@ KTextEditor::Cursor KTextEditorHelpers::extractCursor(const QString& input, int* pathLength) { + // ":ll:cc", ":ll" static const QRegularExpression pattern(QStringLiteral(":(\\d+)(?::(\\d+))?$")); - const auto match = pattern.match(input); + // "#Lll", "#nll", "#ll" as e.g. seen with repo web links + static const QRegularExpression pattern2(QStringLiteral("#(?:n|L|)(\\d+)$")); + + auto match = pattern.match(input); + + if (!match.hasMatch()) { + match = pattern2.match(input); + } + if (!match.hasMatch()) { if (pathLength) *pathLength = input.length(); return KTextEditor::Cursor::invalid(); } int line = match.capturedRef(1).toInt() - 1; + // captured(2) for pattern2 will yield null QString, toInt() thus 0, so no need for if-else // don't use an invalid column when the line is valid int column = qMax(0, match.captured(2).toInt() - 1);