File indexing completed on 2024-05-05 04:38:47

0001 /*
0002     SPDX-FileCopyrightText: 2015 Maciej Cencora
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "texteditorhelpers.h"
0008 
0009 #include <KTextEditor/View>
0010 
0011 #include <QRegularExpression>
0012 
0013 #include <cstdlib>
0014 
0015 namespace KDevelop {
0016 
0017 namespace {
0018 
0019 // TODO: this is a hack, but Kate does not provide interface for this
0020 int lineHeight(const KTextEditor::View* view, int curLine)
0021 {
0022     KTextEditor::Cursor c(curLine, 0);
0023     int currentHeight = view->cursorToCoordinate(c).y();
0024     c.setLine(curLine + 1);
0025     if (view->cursorToCoordinate(c).y() < 0) {
0026         c.setLine(curLine - 1);
0027     }
0028     return std::abs(view->cursorToCoordinate(c).y() - currentHeight);
0029 }
0030 
0031 }
0032 
0033 QRect KTextEditorHelpers::itemBoundingRect(const KTextEditor::View* view, const KTextEditor::Range& itemRange)
0034 {
0035     QPoint startPoint = view->mapToGlobal(view->cursorToCoordinate(itemRange.start()));
0036     QPoint endPoint = view->mapToGlobal(view->cursorToCoordinate(itemRange.end()));
0037     endPoint.ry() += lineHeight(view, itemRange.start().line());
0038     return QRect(startPoint, endPoint);
0039 }
0040 
0041 KTextEditor::Cursor KTextEditorHelpers::extractCursor(const QString& input, int* pathLength)
0042 {
0043     // ":ll:cc", ":ll"
0044     static const QRegularExpression pattern(QStringLiteral(":(\\d+)(?::(\\d+))?$"));
0045     // "#Lll", "#nll", "#ll" as e.g. seen with repo web links
0046     static const QRegularExpression pattern2(QStringLiteral("#(?:n|L|)(\\d+)$"));
0047 
0048     auto match = pattern.match(input);
0049 
0050     if (!match.hasMatch()) {
0051         match = pattern2.match(input);
0052     }
0053 
0054     if (!match.hasMatch()) {
0055         if (pathLength)
0056             *pathLength = input.length();
0057         return KTextEditor::Cursor::invalid();
0058     }
0059 
0060     int line = match.capturedRef(1).toInt() - 1;
0061     // captured(2) for pattern2 will yield null QString, toInt() thus 0, so no need for if-else
0062     // don't use an invalid column when the line is valid
0063     int column = qMax(0, match.capturedRef(2).toInt() - 1);
0064 
0065     if (pathLength)
0066         *pathLength = match.capturedStart(0);
0067     return {
0068                line, column
0069     };
0070 }
0071 
0072 }