50
50
static const QLatin1Char kHash('#');
53
class HighlighterCodeFormatterData : public CodeFormatterData
56
HighlighterCodeFormatterData() : m_foldingIndentDelta(0), m_originalObservableState(-1) {}
57
~HighlighterCodeFormatterData() {}
58
int m_foldingIndentDelta;
59
int m_originalObservableState;
60
QStack<QString> m_foldingRegions;
61
QSharedPointer<Internal::Context> m_contextToContinue;
64
HighlighterCodeFormatterData *formatterData(const QTextBlock &block)
66
HighlighterCodeFormatterData *data = 0;
67
if (TextBlockUserData *userData = BaseTextDocumentLayout::userData(block)) {
68
data = static_cast<HighlighterCodeFormatterData *>(userData->codeFormatterData());
70
data = new HighlighterCodeFormatterData;
71
userData->setCodeFormatterData(data);
53
77
Highlighter::Highlighter(QTextDocument *parent) :
54
78
TextEditor::SyntaxHighlighter(parent),
71
95
<< TextEditor::C_NUMBER
72
96
<< TextEditor::C_STRING
73
97
<< TextEditor::C_STRING
78
<< TextEditor::C_TEXT;
98
<< TextEditor::C_TEXT // TODO : add style for alert (eg. yellow background)
99
<< TextEditor::C_TEXT // TODO : add style for error (eg. red underline)
100
<< TextEditor::C_FUNCTION
101
<< TextEditor::C_TEXT
102
<< TextEditor::C_TEXT
103
<< TextEditor::C_LOCAL;
81
106
setTextFormatCategories(categories);
84
109
Highlighter::~Highlighter()
87
Highlighter::BlockData::BlockData() : m_foldingIndentDelta(0), m_originalObservableState(-1)
90
Highlighter::BlockData::~BlockData()
93
112
// Mapping from Kate format strings to format ids.
94
113
struct KateFormatMap
113
132
m_ids.insert(QLatin1String("dsFunction"), Highlighter::Function);
114
133
m_ids.insert(QLatin1String("dsRegionMarker"), Highlighter::RegionMarker);
115
134
m_ids.insert(QLatin1String("dsOthers"), Highlighter::Others);
135
m_ids.insert(QLatin1String("dsIdentifier"), Highlighter::Identifier);
118
138
Q_GLOBAL_STATIC(KateFormatMap, kateFormatMap)
187
205
setupFromPersistent();
189
blockData(currentBlockUserData())->m_foldingRegions =
190
blockData(currentBlock().previous().userData())->m_foldingRegions;
207
formatterData(currentBlock())->m_foldingRegions =
208
formatterData(currentBlock().previous())->m_foldingRegions;
193
211
assignCurrentContext();
203
221
void Highlighter::setupFromWillContinue()
205
BlockData *previousData = blockData(currentBlock().previous().userData());
223
HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous());
206
224
if (previousData->m_originalObservableState == Default ||
207
225
previousData->m_originalObservableState == -1) {
208
226
m_contexts.push_back(previousData->m_contextToContinue);
210
228
pushContextSequence(previousData->m_originalObservableState);
213
BlockData *data = blockData(currentBlock().userData());
231
HighlighterCodeFormatterData *data = formatterData(currentBlock());
214
232
data->m_originalObservableState = previousData->m_originalObservableState;
216
234
if (currentBlockState() == -1 || extractObservableState(currentBlockState()) == Default)
220
238
void Highlighter::setupFromContinued()
222
BlockData *previousData = blockData(currentBlock().previous().userData());
240
HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous());
224
242
Q_ASSERT(previousData->m_originalObservableState != WillContinue &&
225
243
previousData->m_originalObservableState != Continued);
263
281
if (!m_indentationBasedFolding) {
264
282
if (!rule->beginRegion().isEmpty()) {
265
blockData(currentBlockUserData())->m_foldingRegions.push(rule->beginRegion());
283
formatterData(currentBlock())->m_foldingRegions.push(rule->beginRegion());
267
285
if (progress->isOpeningBraceMatchAtFirstNonSpace())
268
++blockData(currentBlockUserData())->m_foldingIndentDelta;
286
++formatterData(currentBlock())->m_foldingIndentDelta;
270
288
if (!rule->endRegion().isEmpty()) {
271
289
QStack<QString> *currentRegions =
272
&blockData(currentBlockUserData())->m_foldingRegions;
290
&formatterData(currentBlock())->m_foldingRegions;
273
291
if (!currentRegions->isEmpty() && rule->endRegion() == currentRegions->top()) {
274
292
currentRegions->pop();
276
294
if (progress->isClosingBraceMatchAtNonEnd())
277
--blockData(currentBlockUserData())->m_foldingIndentDelta;
295
--formatterData(currentBlock())->m_foldingIndentDelta;
280
298
progress->clearBracesMatches();
441
459
void Highlighter::createWillContinueBlock()
443
BlockData *data = blockData(currentBlockUserData());
461
HighlighterCodeFormatterData *data = formatterData(currentBlock());
444
462
const int currentObservableState = extractObservableState(currentBlockState());
445
463
if (currentObservableState == Continued) {
446
BlockData *previousData = blockData(currentBlock().previous().userData());
464
HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous());
447
465
data->m_originalObservableState = previousData->m_originalObservableState;
448
466
} else if (currentObservableState != WillContinue) {
449
467
data->m_originalObservableState = currentObservableState;
464
482
if (text.length() == 0 || text.at(text.length() - 1) != kBackSlash) {
465
BlockData *data = blockData(currentBlockUserData());
483
HighlighterCodeFormatterData *data = formatterData(currentBlock());
466
484
data->m_contextToContinue.clear();
467
485
setCurrentBlockState(computeState(data->m_originalObservableState));
504
Highlighter::BlockData *Highlighter::initializeBlockData()
506
BlockData *data = new BlockData;
507
setCurrentBlockUserData(data);
511
Highlighter::BlockData *Highlighter::blockData(QTextBlockUserData *userData)
513
return static_cast<BlockData *>(userData);
516
522
void Highlighter::pushDynamicContext(const QSharedPointer<Context> &baseContext)
518
524
// A dynamic context is created from another context which serves as its basis. Then,
554
560
void Highlighter::applyRegionBasedFolding() const
557
BlockData *data = blockData(currentBlockUserData());
558
BlockData *previousData = blockData(currentBlock().previous().userData());
563
TextBlockUserData *currentBlockUserData = BaseTextDocumentLayout::userData(currentBlock());
564
HighlighterCodeFormatterData *data = formatterData(currentBlock());
565
HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous());
559
566
if (previousData) {
560
567
folding = extractRegionDepth(previousBlockState());
561
568
if (data->m_foldingIndentDelta != 0) {
562
569
folding += data->m_foldingIndentDelta;
563
570
if (data->m_foldingIndentDelta > 0)
564
data->setFoldingStartIncluded(true);
571
currentBlockUserData->setFoldingStartIncluded(true);
566
previousData->setFoldingEndIncluded(false);
573
BaseTextDocumentLayout::userData(currentBlock().previous())->setFoldingEndIncluded(false);
567
574
data->m_foldingIndentDelta = 0;
570
data->setFoldingEndIncluded(true);
571
data->setFoldingIndent(folding);
577
currentBlockUserData->setFoldingEndIncluded(true);
578
currentBlockUserData->setFoldingIndent(folding);
574
581
void Highlighter::applyIndentationBasedFolding(const QString &text) const
576
BlockData *data = blockData(currentBlockUserData());
583
TextBlockUserData *data = BaseTextDocumentLayout::userData(currentBlock());
577
584
data->setFoldingEndIncluded(true);
579
586
// If this line is empty, check its neighbours. They all might be part of the same block.