2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
#include "diffandloghighlighter.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/textdocumentlayout.h>
|
2010-11-21 10:15:12 +01:00
|
|
|
|
2008-12-09 15:25:01 +01:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QRegExp>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-03-28 14:19:17 +02:00
|
|
|
/*!
|
2015-03-25 10:31:55 +02:00
|
|
|
\class VcsBase::DiffAndLogHighlighter
|
2011-03-28 14:19:17 +02:00
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
\brief The DiffAndLogHighlighter class provides a highlighter for diffs and log editors.
|
2011-03-28 14:19:17 +02:00
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
Diff is parametrizable by the file indicator, which is for example '^====' in case of p4:
|
2011-03-28 14:19:17 +02:00
|
|
|
\code
|
|
|
|
|
==== //depot/research/main/qdynamicmainwindow3/qdynamicdockwidgetlayout_p.h#34 (text) ====
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
Or '--- a/|'+++ b/' in case of git:
|
|
|
|
|
\code
|
|
|
|
|
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
|
|
|
|
|
index 9401ee7..ef35c3b 100644
|
|
|
|
|
--- a/src/plugins/plugins.pro
|
|
|
|
|
+++ b/src/plugins/plugins.pro
|
|
|
|
|
@@ -10,6 +10,7 @@ SUBDIRS = plugin_coreplugin
|
|
|
|
|
\endcode
|
|
|
|
|
|
2015-03-25 10:30:24 +02:00
|
|
|
Log is parametrizable by change indicator. For example '^commit ([0-9a-f]{8})[0-9a-f]{32}'
|
|
|
|
|
in Git:
|
|
|
|
|
\code
|
|
|
|
|
commit a3398841a24b24c73b47759c4bffdc8b78a34936 (HEAD, master)
|
|
|
|
|
\code
|
|
|
|
|
|
2011-03-28 14:19:17 +02:00
|
|
|
Also highlights trailing blanks.
|
|
|
|
|
*/
|
|
|
|
|
|
2010-11-21 10:15:12 +01:00
|
|
|
static const int BASE_LEVEL = 0;
|
|
|
|
|
static const int FILE_LEVEL = 1;
|
|
|
|
|
static const int LOCATION_LEVEL = 2;
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
namespace VcsBase {
|
2010-11-21 10:15:12 +01:00
|
|
|
namespace Internal {
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
// Formats used by DiffAndLogHighlighter
|
2008-12-02 12:01:29 +01:00
|
|
|
enum DiffFormats {
|
|
|
|
|
DiffTextFormat,
|
|
|
|
|
DiffInFormat,
|
|
|
|
|
DiffOutFormat,
|
|
|
|
|
DiffFileFormat,
|
2015-03-25 10:30:24 +02:00
|
|
|
DiffLocationFormat,
|
|
|
|
|
ChangeTextFormat
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
2010-11-21 10:15:12 +01:00
|
|
|
enum FoldingState {
|
|
|
|
|
StartOfFile,
|
|
|
|
|
Header,
|
|
|
|
|
File,
|
|
|
|
|
Location
|
|
|
|
|
};
|
|
|
|
|
|
2014-06-16 21:34:13 +04:00
|
|
|
} // namespace Internal;
|
2013-08-13 12:57:31 +02:00
|
|
|
|
|
|
|
|
static inline QTextCharFormat invertedColorFormat(const QTextCharFormat &in)
|
|
|
|
|
{
|
|
|
|
|
QTextCharFormat rc = in;
|
|
|
|
|
rc.setForeground(in.background());
|
|
|
|
|
rc.setBackground(in.foreground());
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
// --- DiffAndLogHighlighterPrivate
|
|
|
|
|
class DiffAndLogHighlighterPrivate
|
2012-01-07 03:35:54 +01:00
|
|
|
{
|
2015-03-25 10:31:55 +02:00
|
|
|
DiffAndLogHighlighter *q_ptr;
|
|
|
|
|
Q_DECLARE_PUBLIC(DiffAndLogHighlighter)
|
2010-11-21 10:15:12 +01:00
|
|
|
public:
|
2015-03-25 10:30:24 +02:00
|
|
|
DiffAndLogHighlighterPrivate(const QRegExp &filePattern, const QRegExp &changePattern);
|
2012-01-07 03:35:54 +01:00
|
|
|
|
2013-08-13 12:57:31 +02:00
|
|
|
Internal::DiffFormats analyzeLine(const QString &block) const;
|
|
|
|
|
void updateOtherFormats();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-04-30 12:01:15 +02:00
|
|
|
mutable QRegExp m_filePattern;
|
2015-03-25 10:30:24 +02:00
|
|
|
mutable QRegExp m_changePattern;
|
2008-12-02 12:01:29 +01:00
|
|
|
const QString m_locationIndicator;
|
|
|
|
|
const QChar m_diffInIndicator;
|
|
|
|
|
const QChar m_diffOutIndicator;
|
2009-12-04 14:23:34 +01:00
|
|
|
QTextCharFormat m_addedTrailingWhiteSpaceFormat;
|
2010-11-21 10:15:12 +01:00
|
|
|
|
2013-08-13 12:57:31 +02:00
|
|
|
Internal::FoldingState m_foldingState;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
2015-03-25 10:30:24 +02:00
|
|
|
DiffAndLogHighlighterPrivate::DiffAndLogHighlighterPrivate(const QRegExp &filePattern, const QRegExp &changePattern) :
|
2013-08-13 12:57:31 +02:00
|
|
|
q_ptr(0),
|
2008-12-02 12:01:29 +01:00
|
|
|
m_filePattern(filePattern),
|
2015-03-25 10:30:24 +02:00
|
|
|
m_changePattern(changePattern),
|
2008-12-02 12:01:29 +01:00
|
|
|
m_locationIndicator(QLatin1String("@@")),
|
|
|
|
|
m_diffInIndicator(QLatin1Char('+')),
|
2010-11-21 10:15:12 +01:00
|
|
|
m_diffOutIndicator(QLatin1Char('-')),
|
2013-08-13 12:57:31 +02:00
|
|
|
m_foldingState(Internal::StartOfFile)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(filePattern.isValid());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
Internal::DiffFormats DiffAndLogHighlighterPrivate::analyzeLine(const QString &text) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
// Do not match on git "--- a/" as a deleted line, check
|
|
|
|
|
// file first
|
2013-01-19 23:19:38 +02:00
|
|
|
if (m_filePattern.indexIn(text) == 0)
|
2013-08-13 12:57:31 +02:00
|
|
|
return Internal::DiffFileFormat;
|
2015-03-25 10:30:24 +02:00
|
|
|
if (m_changePattern.indexIn(text) == 0)
|
|
|
|
|
return Internal::ChangeTextFormat;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (text.startsWith(m_diffInIndicator))
|
2013-08-13 12:57:31 +02:00
|
|
|
return Internal::DiffInFormat;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (text.startsWith(m_diffOutIndicator))
|
2013-08-13 12:57:31 +02:00
|
|
|
return Internal::DiffOutFormat;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (text.startsWith(m_locationIndicator))
|
2013-08-13 12:57:31 +02:00
|
|
|
return Internal::DiffLocationFormat;
|
|
|
|
|
return Internal::DiffTextFormat;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
void DiffAndLogHighlighterPrivate::updateOtherFormats()
|
2013-08-13 12:57:31 +02:00
|
|
|
{
|
2015-03-25 10:31:55 +02:00
|
|
|
Q_Q(DiffAndLogHighlighter);
|
2013-08-13 12:57:31 +02:00
|
|
|
m_addedTrailingWhiteSpaceFormat =
|
|
|
|
|
invertedColorFormat(q->formatForCategory(Internal::DiffInFormat));
|
|
|
|
|
|
|
|
|
|
}
|
2010-11-21 10:15:12 +01:00
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
// --- DiffAndLogHighlighter
|
2015-03-25 10:30:24 +02:00
|
|
|
DiffAndLogHighlighter::DiffAndLogHighlighter(const QRegExp &filePattern, const QRegExp &changePattern) :
|
2013-01-17 22:08:29 +02:00
|
|
|
TextEditor::SyntaxHighlighter(static_cast<QTextDocument *>(0)),
|
2015-03-25 10:30:24 +02:00
|
|
|
d_ptr(new DiffAndLogHighlighterPrivate(filePattern, changePattern))
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-08-13 12:57:31 +02:00
|
|
|
d_ptr->q_ptr = this;
|
2015-03-25 10:31:55 +02:00
|
|
|
Q_D(DiffAndLogHighlighter);
|
2013-08-13 12:57:31 +02:00
|
|
|
|
|
|
|
|
static QVector<TextEditor::TextStyle> categories;
|
|
|
|
|
if (categories.isEmpty()) {
|
|
|
|
|
categories << TextEditor::C_TEXT
|
|
|
|
|
<< TextEditor::C_ADDED_LINE
|
|
|
|
|
<< TextEditor::C_REMOVED_LINE
|
|
|
|
|
<< TextEditor::C_DIFF_FILE
|
2015-03-25 10:30:24 +02:00
|
|
|
<< TextEditor::C_DIFF_LOCATION
|
|
|
|
|
<< TextEditor::C_LOG_CHANGE_LINE;
|
2013-08-13 12:57:31 +02:00
|
|
|
}
|
|
|
|
|
setTextFormatCategories(categories);
|
|
|
|
|
d->updateOtherFormats();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
DiffAndLogHighlighter::~DiffAndLogHighlighter()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-04 14:23:34 +01:00
|
|
|
// Check trailing spaces
|
|
|
|
|
static inline int trimmedLength(const QString &in)
|
|
|
|
|
{
|
|
|
|
|
for (int pos = in.length() - 1; pos >= 0; pos--)
|
|
|
|
|
if (!in.at(pos).isSpace())
|
|
|
|
|
return pos + 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-08 10:56:09 +02:00
|
|
|
/*
|
|
|
|
|
* This sets the folding indent:
|
|
|
|
|
* 0 for the first line of the diff header.
|
|
|
|
|
* 1 for all the following lines of the diff header and all @@ lines.
|
|
|
|
|
* 2 for everything else
|
|
|
|
|
*/
|
2015-03-25 10:31:55 +02:00
|
|
|
void DiffAndLogHighlighter::highlightBlock(const QString &text)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-03-25 10:31:55 +02:00
|
|
|
Q_D(DiffAndLogHighlighter);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (text.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
2009-12-04 14:23:34 +01:00
|
|
|
const int length = text.length();
|
2011-09-15 13:42:38 +02:00
|
|
|
const Internal::DiffFormats format = d->analyzeLine(text);
|
2009-12-04 14:23:34 +01:00
|
|
|
switch (format) {
|
2010-11-21 10:15:12 +01:00
|
|
|
case Internal::DiffTextFormat:
|
2009-12-04 14:23:34 +01:00
|
|
|
break;
|
2010-11-21 10:15:12 +01:00
|
|
|
case Internal::DiffInFormat: {
|
2009-12-04 14:23:34 +01:00
|
|
|
// Mark trailing whitespace.
|
|
|
|
|
const int trimmedLen = trimmedLength(text);
|
2013-08-13 12:57:31 +02:00
|
|
|
setFormat(0, trimmedLen, formatForCategory(format));
|
2009-12-04 14:23:34 +01:00
|
|
|
if (trimmedLen != length)
|
2011-09-15 13:42:38 +02:00
|
|
|
setFormat(trimmedLen, length - trimmedLen, d->m_addedTrailingWhiteSpaceFormat);
|
2009-12-04 14:23:34 +01:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2013-08-13 12:57:31 +02:00
|
|
|
setFormat(0, length, formatForCategory(format));
|
2009-12-04 14:23:34 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2010-11-21 10:15:12 +01:00
|
|
|
|
|
|
|
|
// codefolding:
|
|
|
|
|
TextEditor::TextBlockUserData *data =
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::userData(currentBlock());
|
2011-07-21 09:12:10 +02:00
|
|
|
QTC_ASSERT(data, return; );
|
2014-09-26 09:14:03 +02:00
|
|
|
if (!TextEditor::TextDocumentLayout::testUserData(currentBlock().previous()))
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::StartOfFile;
|
2010-11-21 10:15:12 +01:00
|
|
|
|
2011-09-15 13:42:38 +02:00
|
|
|
switch (d->m_foldingState) {
|
2010-11-21 10:15:12 +01:00
|
|
|
case Internal::StartOfFile:
|
|
|
|
|
case Internal::Header:
|
|
|
|
|
switch (format) {
|
|
|
|
|
case Internal::DiffFileFormat:
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::File;
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
case Internal::DiffLocationFormat:
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::Location;
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::Header;
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Internal::File:
|
|
|
|
|
switch (format) {
|
|
|
|
|
case Internal::DiffFileFormat:
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
case Internal::DiffLocationFormat:
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::Location;
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Internal::Location:
|
|
|
|
|
switch (format) {
|
|
|
|
|
case Internal::DiffFileFormat:
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_foldingState = Internal::File;
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
case Internal::DiffLocationFormat:
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
2014-09-26 09:14:03 +02:00
|
|
|
TextEditor::TextDocumentLayout::setFoldingIndent(currentBlock(), LOCATION_LEVEL);
|
2010-11-21 10:15:12 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-12-04 14:23:34 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-25 10:31:55 +02:00
|
|
|
void DiffAndLogHighlighter::setFontSettings(const TextEditor::FontSettings &fontSettings)
|
2009-12-04 14:23:34 +01:00
|
|
|
{
|
2015-03-25 10:31:55 +02:00
|
|
|
Q_D(DiffAndLogHighlighter);
|
2013-08-13 12:57:31 +02:00
|
|
|
SyntaxHighlighter::setFontSettings(fontSettings);
|
|
|
|
|
d->updateOtherFormats();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
} // namespace VcsBase
|