diff --git a/src/plugins/bazaar/bazaareditor.cpp b/src/plugins/bazaar/bazaareditor.cpp index 4087bd987c7..671f3964100 100644 --- a/src/plugins/bazaar/bazaareditor.cpp +++ b/src/plugins/bazaar/bazaareditor.cpp @@ -48,28 +48,7 @@ BazaarEditorWidget::BazaarEditorWidget() : // === 'mainwindow.cpp' setDiffFilePattern(QRegExp(QLatin1String("^=== [a-z]+ [a-z]+ '(.+)'\\s*"))); setLogEntryPattern(QRegExp(QLatin1String("^revno: (\\d+)"))); -} - -QSet BazaarEditorWidget::annotationChanges() const -{ - QSet changes; - const QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - - QRegExp changeNumRx(QLatin1String("^(" BZR_CHANGE_PATTERN ") ")); - QTC_ASSERT(changeNumRx.isValid(), return changes); - if (changeNumRx.indexIn(txt) != -1) { - changes.insert(changeNumRx.cap(1)); - changeNumRx.setPattern(QLatin1String("\n(" BZR_CHANGE_PATTERN ") ")); - QTC_ASSERT(changeNumRx.isValid(), return changes); - int pos = 0; - while ((pos = changeNumRx.indexIn(txt, pos)) != -1) { - pos += changeNumRx.matchedLength(); - changes.insert(changeNumRx.cap(1)); - } - } - return changes; + setAnnotationEntryPattern("^(" BZR_CHANGE_PATTERN ") "); } QString BazaarEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const diff --git a/src/plugins/bazaar/bazaareditor.h b/src/plugins/bazaar/bazaareditor.h index 09584462a15..96a9f1610f9 100644 --- a/src/plugins/bazaar/bazaareditor.h +++ b/src/plugins/bazaar/bazaareditor.h @@ -40,7 +40,6 @@ public: BazaarEditorWidget(); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &cursor) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; diff --git a/src/plugins/clearcase/clearcaseeditor.cpp b/src/plugins/clearcase/clearcaseeditor.cpp index bcac505c484..341cc92ad84 100644 --- a/src/plugins/clearcase/clearcaseeditor.cpp +++ b/src/plugins/clearcase/clearcaseeditor.cpp @@ -52,24 +52,8 @@ ClearCaseEditorWidget::ClearCaseEditorWidget() : setDiffFilePattern(diffFilePattern); setLogEntryPattern(QRegExp(QLatin1String("version \"([^\"]+)\""))); setAnnotateRevisionTextFormat(tr("Annotate version \"%1\"")); -} - -QSet ClearCaseEditorWidget::annotationChanges() const -{ - QSet changes; - QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - // search until header - int separator = txt.indexOf(QRegExp(QLatin1String("\n-{30}"))); - QRegExp r(QLatin1String("([^|]*)\\|[^\n]*\n")); - QTC_ASSERT(r.isValid(), return changes); - int pos = r.indexIn(txt, 0); - while (pos != -1 && pos < separator) { - changes.insert(r.cap(1)); - pos = r.indexIn(txt, pos + r.matchedLength()); - } - return changes; + setAnnotationEntryPattern("([^|]*)\\|[^\\n]*\\n"); + setAnnotationSeparatorPattern("\\n-{30}"); } QString ClearCaseEditorWidget::changeUnderCursor(const QTextCursor &c) const diff --git a/src/plugins/clearcase/clearcaseeditor.h b/src/plugins/clearcase/clearcaseeditor.h index 3c9d95fa095..e97a6ecb22e 100644 --- a/src/plugins/clearcase/clearcaseeditor.h +++ b/src/plugins/clearcase/clearcaseeditor.h @@ -41,7 +41,6 @@ public: ClearCaseEditorWidget(); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; diff --git a/src/plugins/cvs/cvseditor.cpp b/src/plugins/cvs/cvseditor.cpp index 8e0b0bbb2ca..638945e4e31 100644 --- a/src/plugins/cvs/cvseditor.cpp +++ b/src/plugins/cvs/cvseditor.cpp @@ -59,28 +59,7 @@ CvsEditorWidget::CvsEditorWidget() : setDiffFilePattern(QRegExp(QLatin1String("^[-+]{3} ([^\\t]+)"))); setLogEntryPattern(QRegExp(QLatin1String("^revision (.+)$"))); setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\"")); -} - -QSet CvsEditorWidget::annotationChanges() const -{ - QSet changes; - const QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - // Hunt for first change number in annotation: "1.1 (author)" - QRegExp r(QLatin1String(CVS_REVISION_AT_START_PATTERN)); - QTC_ASSERT(r.isValid(), return changes); - if (r.indexIn(txt) != -1) { - changes.insert(r.cap(1)); - r.setPattern(QLatin1String("\n(" CVS_REVISION_PATTERN ") ")); - QTC_ASSERT(r.isValid(), return changes); - int pos = 0; - while ((pos = r.indexIn(txt, pos)) != -1) { - pos += r.matchedLength(); - changes.insert(r.cap(1)); - } - } - return changes; + setAnnotationEntryPattern("^(" CVS_REVISION_PATTERN ") "); } QString CvsEditorWidget::changeUnderCursor(const QTextCursor &c) const diff --git a/src/plugins/cvs/cvseditor.h b/src/plugins/cvs/cvseditor.h index f7ce08fd0b0..83990d9bc35 100644 --- a/src/plugins/cvs/cvseditor.h +++ b/src/plugins/cvs/cvseditor.h @@ -40,7 +40,6 @@ public: CvsEditorWidget(); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index d9c29afebf4..26842a6b1ac 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -75,28 +75,7 @@ GitEditorWidget::GitEditorWidget() : setLogEntryPattern(QRegExp("^commit ([0-9a-f]{8})[0-9a-f]{32}")); setAnnotateRevisionTextFormat(tr("&Blame %1")); setAnnotatePreviousRevisionTextFormat(tr("Blame &Parent Revision %1")); -} - -QSet GitEditorWidget::annotationChanges() const -{ - QSet changes; - const QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - // Hunt for first change number in annotation: ":" - QRegExp r("^(" CHANGE_PATTERN ") "); - QTC_ASSERT(r.isValid(), return changes); - if (r.indexIn(txt) != -1) { - changes.insert(r.cap(1)); - r.setPattern("\n(" CHANGE_PATTERN ") "); - QTC_ASSERT(r.isValid(), return changes); - int pos = 0; - while ((pos = r.indexIn(txt, pos)) != -1) { - pos += r.matchedLength(); - changes.insert(r.cap(1)); - } - } - return changes; + setAnnotationEntryPattern("^(" CHANGE_PATTERN ") "); } QString GitEditorWidget::changeUnderCursor(const QTextCursor &c) const diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index bc7df7fe9e6..246ca9788f8 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -54,7 +54,6 @@ private: void resetChange(const QByteArray &resetType); void addDiffActions(QMenu *menu, const VcsBase::DiffChunk &chunk) override; void aboutToOpen(const QString &fileName, const QString &realFileName) override; - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet &changes) const override; QString decorateVersion(const QString &revision) const override; diff --git a/src/plugins/mercurial/constants.h b/src/plugins/mercurial/constants.h index 1813d16723b..7f8982d49ee 100644 --- a/src/plugins/mercurial/constants.h +++ b/src/plugins/mercurial/constants.h @@ -37,10 +37,10 @@ const char MERCURIALDEFAULT[] = "hg"; const char MERCURIAL_CONTEXT[] = "Mercurial Context"; // Changeset identifiers -const char CHANGESETID12[] = " ([a-f0-9]{12,12}) "; //match 12 hex chars and capture -const char CHANGESETID40[] = " ([a-f0-9]{40,40}) "; -const char CHANGEIDEXACT12[] = "[a-f0-9]{12,12}"; //match 12 hex chars a -const char CHANGEIDEXACT40[] = "[a-f0-9]{40,40}"; +const char CHANGESETID12[] = " ([a-f0-9]{12}) "; //match 12 hex chars and capture +const char CHANGESETID40[] = " ([a-f0-9]{40}) "; +const char CHANGEIDEXACT12[] = "[a-f0-9]{12}"; //match 12 hex chars +const char CHANGEIDEXACT40[] = "[a-f0-9]{40}"; // match diff header. e.g. +++ b/filename const char DIFFIDENTIFIER[] = "^(?:diff --git a/|[+-]{3} (?:/dev/null|[ab]/(.+$)))"; diff --git a/src/plugins/mercurial/mercurialeditor.cpp b/src/plugins/mercurial/mercurialeditor.cpp index e4c313e11ab..676f26ea8ff 100644 --- a/src/plugins/mercurial/mercurialeditor.cpp +++ b/src/plugins/mercurial/mercurialeditor.cpp @@ -45,7 +45,6 @@ namespace Internal { MercurialEditorWidget::MercurialEditorWidget(MercurialClient *client) : exactIdentifier12(QLatin1String(Constants::CHANGEIDEXACT12)), exactIdentifier40(QLatin1String(Constants::CHANGEIDEXACT40)), - changesetIdentifier12(QLatin1String(Constants::CHANGESETID12)), changesetIdentifier40(QLatin1String(Constants::CHANGESETID40)), m_client(client) { @@ -53,22 +52,7 @@ MercurialEditorWidget::MercurialEditorWidget(MercurialClient *client) : setLogEntryPattern(QRegExp(QLatin1String("^changeset:\\s+(\\S+)$"))); setAnnotateRevisionTextFormat(tr("&Annotate %1")); setAnnotatePreviousRevisionTextFormat(tr("Annotate &parent revision %1")); -} - -QSet MercurialEditorWidget::annotationChanges() const -{ - QSet changes; - const QString data = toPlainText(); - if (data.isEmpty()) - return changes; - - int position = 0; - while ((position = changesetIdentifier12.indexIn(data, position)) != -1) { - changes.insert(changesetIdentifier12.cap(1)); - position += changesetIdentifier12.matchedLength(); - } - - return changes; + setAnnotationEntryPattern(Constants::CHANGESETID12); } QString MercurialEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const diff --git a/src/plugins/mercurial/mercurialeditor.h b/src/plugins/mercurial/mercurialeditor.h index 12976a3d779..868f84f535c 100644 --- a/src/plugins/mercurial/mercurialeditor.h +++ b/src/plugins/mercurial/mercurialeditor.h @@ -41,7 +41,6 @@ public: explicit MercurialEditorWidget(MercurialClient *client); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &cursor) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; @@ -50,7 +49,6 @@ private: mutable QRegExp exactIdentifier12; mutable QRegExp exactIdentifier40; - mutable QRegExp changesetIdentifier12; const QRegExp changesetIdentifier40; MercurialClient *m_client; diff --git a/src/plugins/perforce/perforceeditor.cpp b/src/plugins/perforce/perforceeditor.cpp index e686d4e427b..82e7d166f27 100644 --- a/src/plugins/perforce/perforceeditor.cpp +++ b/src/plugins/perforce/perforceeditor.cpp @@ -63,28 +63,7 @@ PerforceEditorWidget::PerforceEditorWidget() : setDiffFilePattern(QRegExp(QLatin1String("^(?:={4}|\\+{3}) (.+)(?:\\t|#\\d)"))); setLogEntryPattern(QRegExp(QLatin1String("^... #\\d change (\\d+) "))); setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\"")); -} - -QSet PerforceEditorWidget::annotationChanges() const -{ - QSet changes; - const QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - // Hunt for first change number in annotation: ":" - QRegExp r(QLatin1String("^(\\d+):")); - QTC_ASSERT(r.isValid(), return changes); - if (r.indexIn(txt) != -1) { - changes.insert(r.cap(1)); - r.setPattern(QLatin1String("\n(\\d+):")); - QTC_ASSERT(r.isValid(), return changes); - int pos = 0; - while ((pos = r.indexIn(txt, pos)) != -1) { - pos += r.matchedLength(); - changes.insert(r.cap(1)); - } - } - return changes; + setAnnotationEntryPattern("^(\\d+):"); } QString PerforceEditorWidget::changeUnderCursor(const QTextCursor &c) const diff --git a/src/plugins/perforce/perforceeditor.h b/src/plugins/perforce/perforceeditor.h index 2a91373aacd..92a9d234869 100644 --- a/src/plugins/perforce/perforceeditor.h +++ b/src/plugins/perforce/perforceeditor.h @@ -40,7 +40,6 @@ public: PerforceEditorWidget(); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; diff --git a/src/plugins/subversion/subversioneditor.cpp b/src/plugins/subversion/subversioneditor.cpp index cb48da5daaf..7ef6e08443b 100644 --- a/src/plugins/subversion/subversioneditor.cpp +++ b/src/plugins/subversion/subversioneditor.cpp @@ -59,30 +59,7 @@ SubversionEditorWidget::SubversionEditorWidget() : setDiffFilePattern(QRegExp(QLatin1String("^[-+]{3} ([^\\t]+)|^Index: .*|^=+$"))); setLogEntryPattern(QRegExp(QLatin1String("^(r\\d+) \\|"))); setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\"")); -} - -QSet SubversionEditorWidget::annotationChanges() const -{ - QSet changes; - const QString txt = toPlainText(); - if (txt.isEmpty()) - return changes; - // Hunt for first change number in annotation: ":" - QRegExp r(QLatin1String("^(\\d+):")); - QTC_ASSERT(r.isValid(), return changes); - if (r.indexIn(txt) != -1) { - changes.insert(r.cap(1)); - r.setPattern(QLatin1String("\n(\\d+):")); - QTC_ASSERT(r.isValid(), return changes); - int pos = 0; - while ((pos = r.indexIn(txt, pos)) != -1) { - pos += r.matchedLength(); - changes.insert(r.cap(1)); - } - } - if (Subversion::Constants::debug) - qDebug() << "SubversionEditor::annotationChanges() returns #" << changes.size(); - return changes; + setAnnotationEntryPattern("^(\\d+):"); } QString SubversionEditorWidget::changeUnderCursor(const QTextCursor &c) const diff --git a/src/plugins/subversion/subversioneditor.h b/src/plugins/subversion/subversioneditor.h index 6b2446ffdea..a7b44f66b9a 100644 --- a/src/plugins/subversion/subversioneditor.h +++ b/src/plugins/subversion/subversioneditor.h @@ -40,7 +40,6 @@ public: SubversionEditorWidget(); private: - QSet annotationChanges() const override; QString changeUnderCursor(const QTextCursor &) const override; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( const QSet &changes) const override; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 0471968dcfd..aae366dcb47 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -556,6 +557,8 @@ public: QRegExp m_diffFilePattern; QRegExp m_logEntryPattern; + QRegularExpression m_annotationEntryPattern; + QRegularExpression m_annotationSeparatorPattern; QList m_entrySections; // line number where this section starts int m_cursorLine = -1; int m_firstLineNumber = -1; @@ -661,6 +664,20 @@ void VcsBaseEditorWidget::setLogEntryPattern(const QRegExp &pattern) d->m_logEntryPattern = pattern; } +void VcsBaseEditorWidget::setAnnotationEntryPattern(const QString &pattern) +{ + const QRegularExpression re(pattern, QRegularExpression::MultilineOption); + QTC_ASSERT(re.isValid() && re.captureCount() >= 1, return); + d->m_annotationEntryPattern = re; +} + +void VcsBaseEditorWidget::setAnnotationSeparatorPattern(const QString &pattern) +{ + const QRegularExpression re(pattern); + QTC_ASSERT(re.isValid() && re.captureCount() >= 1, return); + d->m_annotationSeparatorPattern = re; +} + bool VcsBaseEditorWidget::supportChangeLinks() const { switch (d->m_parameters->type) { @@ -1537,6 +1554,26 @@ void VcsBaseEditorWidget::addChangeActions(QMenu *, const QString &) { } +QSet VcsBaseEditorWidget::annotationChanges() const +{ + QSet changes; + QString text = toPlainText(); + QStringRef txt(&text); + if (txt.isEmpty()) + return changes; + if (d->m_annotationSeparatorPattern.isValid()) { + const QRegularExpressionMatch match = d->m_annotationSeparatorPattern.match(txt); + if (match.hasMatch()) + txt.truncate(match.capturedStart()); + } + QRegularExpressionMatchIterator i = d->m_annotationEntryPattern.globalMatch(txt); + while (i.hasNext()) { + const QRegularExpressionMatch match = i.next(); + changes.insert(match.captured(1)); + } + return changes; +} + QString VcsBaseEditorWidget::decorateVersion(const QString &revision) const { return revision; diff --git a/src/plugins/vcsbase/vcsbaseeditor.h b/src/plugins/vcsbase/vcsbaseeditor.h index 863d300d62f..caf2d4575db 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.h +++ b/src/plugins/vcsbase/vcsbaseeditor.h @@ -148,6 +148,10 @@ protected: void setDiffFilePattern(const QRegExp &pattern); // Pattern for log entry. hash/revision number must be in the first capture group void setLogEntryPattern(const QRegExp &pattern); + // Pattern for annotation entry. hash/revision number must be in the first capture group + void setAnnotationEntryPattern(const QString &pattern); + // Pattern for annotation separator. Lookup will stop on match. + void setAnnotationSeparatorPattern(const QString &pattern); virtual bool supportChangeLinks() const; virtual QString fileNameForLine(int line) const; @@ -246,7 +250,7 @@ protected: // Implement to return a set of change identifiers in // annotation mode - virtual QSet annotationChanges() const = 0; + QSet annotationChanges() const; // Implement to identify a change number at the cursor position virtual QString changeUnderCursor(const QTextCursor &) const = 0; // Factory functions for highlighters