1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
37 #include "basetextdocumentlayout.h"
38 #include "syntaxhighlighter.h"
40 #include <QtCore/QString>
41 #include <QtCore/QVector>
42 #include <QtCore/QStack>
43 #include <QtCore/QSharedPointer>
44 #include <QtCore/QStringList>
46 #include <QtGui/QSyntaxHighlighter>
47 #include <QtGui/QTextCharFormat>
49 namespace TextEditor {
57 class HighlightDefinition;
60 class Highlighter : public TextEditor::SyntaxHighlighter
65 Highlighter(QTextDocument *parent = 0);
66 virtual ~Highlighter();
86 void configureFormat(TextFormatId id, const QTextCharFormat &format);
87 void setTabSettings(const TabSettings &ts);
88 void setDefaultContext(const QSharedPointer<Context> &defaultContext);
91 virtual void highlightBlock(const QString &text);
95 void setupDataForBlock(const QString &text);
97 void setupFromWillContinue();
98 void setupFromContinued();
99 void setupFromPersistent();
101 void iterateThroughRules(const QString &text,
103 ProgressData *progress,
104 const bool childRule,
105 const QList<QSharedPointer<Rule> > &rules);
107 void assignCurrentContext();
108 bool contextChangeRequired(const QString &contextName) const;
109 void handleContextChange(const QString &contextName,
110 const QSharedPointer<HighlightDefinition> &definition,
111 const bool setCurrent = true);
112 void changeContext(const QString &contextName,
113 const QSharedPointer<HighlightDefinition> &definition,
114 const bool assignCurrent = true);
116 QString currentContextSequence() const;
117 void mapPersistentSequence(const QString &contextSequence);
118 void mapLeadingSequence(const QString &contextSequence);
119 void pushContextSequence(int state);
121 void pushDynamicContext(const QSharedPointer<Context> &baseContext);
123 void createWillContinueBlock();
124 void analyseConsistencyOfWillContinueBlock(const QString &text);
126 void applyFormat(int offset,
128 const QString &itemDataName,
129 const QSharedPointer<HighlightDefinition> &definition);
131 void applyRegionBasedFolding() const;
132 void applyIndentationBasedFolding(const QString &text) const;
133 int neighbouringNonEmptyBlockIndent(QTextBlock block, const bool previous) const;
135 // Mapping from Kate format strings to format ids.
139 QHash<QString, TextFormatId> m_ids;
141 static const KateFormatMap m_kateFormats;
142 QHash<TextFormatId, QTextCharFormat> m_creatorFormats;
144 struct BlockData : TextBlockUserData
147 virtual ~BlockData();
149 int m_foldingIndentDelta;
150 int m_originalObservableState;
151 QStack<QString> m_foldingRegions;
152 QSharedPointer<Context> m_contextToContinue;
154 BlockData *initializeBlockData();
155 static BlockData *blockData(QTextBlockUserData *userData);
157 // Block states are composed by the region depth (used for code folding) and what I call
158 // observable states. Observable states occupy the 12 least significant bits. They might have
159 // the following values:
160 // - Default [0]: Nothing special.
161 // - WillContinue [1]: When there is match of the LineContinue rule (backslash as the last
163 // - Continued [2]: Blocks that happen after a WillContinue block and continue from their
164 // context until the next line end.
165 // - Persistent(s) [Anything >= 3]: Correspond to persistent contexts which last until a pop
166 // occurs due to a matching rule. Every sequence of persistent contexts seen so far is
167 // associated with a number (incremented by a unit each time).
168 // Region depths occupy the remaining bits.
169 enum ObservableBlockState {
175 int computeState(const int observableState) const;
177 static int extractRegionDepth(const int state);
178 static int extractObservableState(const int state);
181 bool m_indentationBasedFolding;
182 const TabSettings *m_tabSettings;
184 int m_persistentObservableStatesCounter;
185 int m_dynamicContextsCounter;
189 QSharedPointer<Context> m_defaultContext;
190 QSharedPointer<Context> m_currentContext;
191 QVector<QSharedPointer<Context> > m_contexts;
193 // Mapping from context sequences to the observable persistent state they represent.
194 QHash<QString, int> m_persistentObservableStates;
195 // Mapping from context sequences to the non-persistent observable state that led to them.
196 QHash<QString, int> m_leadingObservableStates;
197 // Mapping from observable persistent states to context sequences (the actual "stack").
198 QHash<int, QVector<QSharedPointer<Context> > > m_persistentContexts;
200 // Captures used in dynamic rules.
201 QStringList m_currentCaptures;
204 } // namespace Internal
205 } // namespace TextEditor
207 #endif // HIGHLIGHTER_H