diff --git a/util/tests/test_texteditorhelpers.cpp b/util/tests/test_texteditorhelpers.cpp index 64a3d15bb9..87e8dc4a25 100644 --- a/util/tests/test_texteditorhelpers.cpp +++ b/util/tests/test_texteditorhelpers.cpp @@ -1,68 +1,92 @@ /* * Copyright 2016 Kevin Funk * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "test_texteditorhelpers.h" #include "texteditorhelpers.h" #include QTEST_MAIN(TestKTextEditorHelpers); using namespace KDevelop; void TestKTextEditorHelpers::testExtractCursor() { QFETCH(QString, input); QFETCH(KTextEditor::Cursor, expectedCursor); QFETCH(QString, expectedPath); int pathLen; const auto cursor = KTextEditorHelpers::extractCursor(input, &pathLen); QCOMPARE(cursor, expectedCursor); QCOMPARE(input.mid(0, pathLen), expectedPath); } void TestKTextEditorHelpers::testExtractCursor_data() { QTest::addColumn("input"); QTest::addColumn("expectedCursor"); QTest::addColumn("expectedPath"); // valid input QTest::newRow("file") << QStringLiteral("widget.cpp") << KTextEditor::Cursor::invalid() << QStringLiteral("widget.cpp"); QTest::newRow("file:line") << QStringLiteral("widget.cpp:12") << KTextEditor::Cursor(11, 0) << QStringLiteral("widget.cpp"); QTest::newRow("file:line:column") << 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 index 0c80b86fc9..914b9f4f64 100644 --- a/util/texteditorhelpers.cpp +++ b/util/texteditorhelpers.cpp @@ -1,73 +1,83 @@ /* This file is part of the KDE project Copyright 2015 Maciej Cencora This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "texteditorhelpers.h" #include #include namespace KDevelop { namespace { // TODO: this is a hack, but Kate does not provide interface for this int getLineHeight(const KTextEditor::View* view, int curLine) { KTextEditor::Cursor c(curLine, 0); int currentHeight = view->cursorToCoordinate(c).y(); c.setLine(curLine + 1); if (view->cursorToCoordinate(c).y() < 0) { c.setLine(curLine - 1); } return std::abs(view->cursorToCoordinate(c).y() - currentHeight); } } QRect KTextEditorHelpers::getItemBoundingRect(const KTextEditor::View* view, const KTextEditor::Range& itemRange) { QPoint startPoint = view->mapToGlobal(view->cursorToCoordinate(itemRange.start())); QPoint endPoint = view->mapToGlobal(view->cursorToCoordinate(itemRange.end())); endPoint.ry() += getLineHeight(view, itemRange.start().line()); return QRect(startPoint, endPoint); } 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); if (pathLength) *pathLength = match.capturedStart(0); return {line, column}; } }