00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "katehighlight.h"
00025
#include "katehighlight.moc"
00026
00027
#include "katetextline.h"
00028
#include "katedocument.h"
00029
#include "katesyntaxdocument.h"
00030
#include "katerenderer.h"
00031
#include "katefactory.h"
00032
#include "kateschema.h"
00033
#include "kateconfig.h"
00034
00035
#include <kconfig.h>
00036
#include <kglobal.h>
00037
#include <kinstance.h>
00038
#include <kmimetype.h>
00039
#include <klocale.h>
00040
#include <kregexp.h>
00041
#include <kpopupmenu.h>
00042
#include <kglobalsettings.h>
00043
#include <kdebug.h>
00044
#include <kstandarddirs.h>
00045
#include <kmessagebox.h>
00046
#include <kstaticdeleter.h>
00047
#include <kapplication.h>
00048
00049
#include <qstringlist.h>
00050
#include <qtextstream.h>
00051
00052
00053
00054
00055
#define KATE_HL_HOWMANY 1024
00056
00057
00058
static const int KATE_DYNAMIC_CONTEXTS_RESET_DELAY = 30 * 1000;
00059
00060
00061
#define IS_TRUE(x) x.lower() == QString("true") || x.toInt() == 1
00062
00063
00064
00065
00066
inline bool kateInsideString (
const QString &str,
QChar ch)
00067 {
00068
for (uint i=0; i < str.length(); i++)
00069
if (*(str.unicode()+i) == ch)
00070
return true;
00071
00072
return false;
00073 }
00074
00075
class KateHlItem
00076 {
00077
public:
00078 KateHlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00079
virtual ~KateHlItem();
00080
00081
public:
00082
00083
00084
00085
virtual int checkHgl(
const QString& text,
int offset,
int len) = 0;
00086
00087
virtual bool lineContinue(){
return false;}
00088
00089
virtual QStringList *capturedTexts() {
return 0;}
00090
virtual KateHlItem *clone(
const QStringList *) {
return this;}
00091
00092
static void dynamicSubstitute(
QString& str,
const QStringList *args);
00093
00094
QMemArray<KateHlItem*> subItems;
00095
int attr;
00096
int ctx;
00097
signed char region;
00098
signed char region2;
00099
00100
bool lookAhead;
00101
00102
bool dynamic;
00103
bool dynamicChild;
00104
bool firstNonSpace;
00105
bool onlyConsume;
00106
int column;
00107
00108
00109
00110
bool alwaysStartEnable;
00111
bool customStartEnable;
00112 };
00113
00114
class KateHlContext
00115 {
00116
public:
00117 KateHlContext(
const QString &_hlId,
int attribute,
int lineEndContext,
int _lineBeginContext,
00118
bool _fallthrough,
int _fallthroughContext,
bool _dynamic);
00119
virtual ~KateHlContext();
00120 KateHlContext *clone(
const QStringList *args);
00121
00122
QValueVector<KateHlItem*> items;
00123
QString hlId;
00124
int attr;
00125
int ctx;
00126
int lineBeginContext;
00132
bool fallthrough;
00133
int ftctx;
00134
00135
bool dynamic;
00136
bool dynamicChild;
00137 };
00138
00139
class KateEmbeddedHlInfo
00140 {
00141
public:
00142 KateEmbeddedHlInfo() {loaded=
false;context0=-1;}
00143 KateEmbeddedHlInfo(
bool l,
int ctx0) {loaded=l;context0=ctx0;}
00144
00145
public:
00146
bool loaded;
00147
int context0;
00148 };
00149
00150
class KateHlIncludeRule
00151 {
00152
public:
00153 KateHlIncludeRule(
int ctx_=0, uint pos_=0,
const QString &incCtxN_=
"",
bool incAttrib=
false)
00154 : ctx(ctx_)
00155 , pos( pos_)
00156 , incCtxN( incCtxN_ )
00157 , includeAttrib( incAttrib )
00158 {
00159 incCtx=-1;
00160 }
00161
00162
00163
public:
00164
int ctx;
00165 uint pos;
00166
int incCtx;
00167
QString incCtxN;
00168
bool includeAttrib;
00169 };
00170
00171
class KateHlCharDetect :
public KateHlItem
00172 {
00173
public:
00174 KateHlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar);
00175
00176
virtual int checkHgl(
const QString& text,
int offset,
int len);
00177
virtual KateHlItem *clone(
const QStringList *args);
00178
00179
private:
00180
QChar sChar;
00181 };
00182
00183
class KateHl2CharDetect :
public KateHlItem
00184 {
00185
public:
00186 KateHl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00187 KateHl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *ch);
00188
00189
virtual int checkHgl(
const QString& text,
int offset,
int len);
00190
virtual KateHlItem *clone(
const QStringList *args);
00191
00192
private:
00193
QChar sChar1;
00194
QChar sChar2;
00195 };
00196
00197
class KateHlStringDetect :
public KateHlItem
00198 {
00199
public:
00200 KateHlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &,
bool inSensitive=
false);
00201
00202
virtual int checkHgl(
const QString& text,
int offset,
int len);
00203
virtual KateHlItem *clone(
const QStringList *args);
00204
00205
private:
00206
const QString str;
00207
const int strLen;
00208
const bool _inSensitive;
00209 };
00210
00211
class KateHlRangeDetect :
public KateHlItem
00212 {
00213
public:
00214 KateHlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00215
00216
virtual int checkHgl(
const QString& text,
int offset,
int len);
00217
00218
private:
00219
QChar sChar1;
00220
QChar sChar2;
00221 };
00222
00223
class KateHlKeyword :
public KateHlItem
00224 {
00225
public:
00226 KateHlKeyword(
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims);
00227
virtual ~KateHlKeyword ();
00228
00229
void addList(
const QStringList &);
00230
virtual int checkHgl(
const QString& text,
int offset,
int len);
00231
00232
private:
00233
QMemArray< QDict<bool>* > dict;
00234
bool _caseSensitive;
00235
const QString& deliminators;
00236
int minLen;
00237
int maxLen;
00238 };
00239
00240
class KateHlInt :
public KateHlItem
00241 {
00242
public:
00243 KateHlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00244
00245
virtual int checkHgl(
const QString& text,
int offset,
int len);
00246 };
00247
00248
class KateHlFloat :
public KateHlItem
00249 {
00250
public:
00251 KateHlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00252
virtual ~KateHlFloat () {}
00253
00254
virtual int checkHgl(
const QString& text,
int offset,
int len);
00255 };
00256
00257
class KateHlCFloat :
public KateHlFloat
00258 {
00259
public:
00260 KateHlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00261
00262
virtual int checkHgl(
const QString& text,
int offset,
int len);
00263
int checkIntHgl(
const QString& text,
int offset,
int len);
00264 };
00265
00266
class KateHlCOct :
public KateHlItem
00267 {
00268
public:
00269 KateHlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00270
00271
virtual int checkHgl(
const QString& text,
int offset,
int len);
00272 };
00273
00274
class KateHlCHex :
public KateHlItem
00275 {
00276
public:
00277 KateHlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00278
00279
virtual int checkHgl(
const QString& text,
int offset,
int len);
00280 };
00281
00282
class KateHlLineContinue :
public KateHlItem
00283 {
00284
public:
00285 KateHlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00286
00287
virtual bool endEnable(
QChar c) {
return c ==
'\0';}
00288
virtual int checkHgl(
const QString& text,
int offset,
int len);
00289
virtual bool lineContinue(){
return true;}
00290 };
00291
00292
class KateHlCStringChar :
public KateHlItem
00293 {
00294
public:
00295 KateHlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00296
00297
virtual int checkHgl(
const QString& text,
int offset,
int len);
00298 };
00299
00300
class KateHlCChar :
public KateHlItem
00301 {
00302
public:
00303 KateHlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00304
00305
virtual int checkHgl(
const QString& text,
int offset,
int len);
00306 };
00307
00308
class KateHlAnyChar :
public KateHlItem
00309 {
00310
public:
00311 KateHlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList);
00312
00313
virtual int checkHgl(
const QString& text,
int offset,
int len);
00314
00315
private:
00316
const QString _charList;
00317 };
00318
00319
class KateHlRegExpr :
public KateHlItem
00320 {
00321
public:
00322 KateHlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2 ,
QString expr,
bool insensitive,
bool minimal);
00323 ~KateHlRegExpr() {
delete Expr; };
00324
00325
virtual int checkHgl(
const QString& text,
int offset,
int len);
00326
virtual QStringList *capturedTexts();
00327
virtual KateHlItem *clone(
const QStringList *args);
00328
00329
private:
00330
QRegExp *Expr;
00331
bool handlesLinestart;
00332
QString _regexp;
00333
bool _insensitive;
00334
bool _minimal;
00335 };
00336
00337
class KateHlDetectSpaces :
public KateHlItem
00338 {
00339
public:
00340 KateHlDetectSpaces (
int attribute,
int context,
signed char regionId,
signed char regionId2)
00341 : KateHlItem(attribute,context,regionId,regionId2) {}
00342
00343
virtual int checkHgl(
const QString& text,
int offset,
int len)
00344 {
00345
int len2 = offset + len;
00346
while ((offset < len2) && text[offset].isSpace()) offset++;
00347
return offset;
00348 }
00349 };
00350
00351
class KateHlDetectIdentifier :
public KateHlItem
00352 {
00353
public:
00354 KateHlDetectIdentifier (
int attribute,
int context,
signed char regionId,
signed char regionId2)
00355 : KateHlItem(attribute,context,regionId,regionId2) { alwaysStartEnable =
false; }
00356
00357
virtual int checkHgl(
const QString& text,
int offset,
int len)
00358 {
00359
00360
if ( text[offset].isLetter() || text[offset] ==
QChar (
'_') )
00361 {
00362
00363
int len2 = offset+len;
00364
00365
00366 offset++;
00367
00368
00369
while (
00370 (offset < len2)
00371 && (text[offset].isLetterOrNumber() || (text[offset] == QChar (
'_')))
00372 )
00373 offset++;
00374
00375
return offset;
00376 }
00377
00378
return 0;
00379 }
00380 };
00381
00382
00383
00384
00385 KateHlManager *KateHlManager::s_self = 0;
00386
00387
static const bool trueBool =
true;
00388
static const QString stdDeliminator =
QString (
" \t.():!+,-<=>%&*/;?[]^{|}~\\");
00389
00390
00391
00392
static KateHlItemData::ItemStyles getDefStyleNum(QString name)
00393 {
00394
if (
name==
"dsNormal")
return KateHlItemData::dsNormal;
00395
else if (
name==
"dsKeyword")
return KateHlItemData::dsKeyword;
00396
else if (
name==
"dsDataType")
return KateHlItemData::dsDataType;
00397
else if (
name==
"dsDecVal")
return KateHlItemData::dsDecVal;
00398
else if (
name==
"dsBaseN")
return KateHlItemData::dsBaseN;
00399
else if (
name==
"dsFloat")
return KateHlItemData::dsFloat;
00400
else if (
name==
"dsChar")
return KateHlItemData::dsChar;
00401
else if (
name==
"dsString")
return KateHlItemData::dsString;
00402
else if (
name==
"dsComment")
return KateHlItemData::dsComment;
00403
else if (
name==
"dsOthers")
return KateHlItemData::dsOthers;
00404
else if (
name==
"dsAlert")
return KateHlItemData::dsAlert;
00405
else if (
name==
"dsFunction")
return KateHlItemData::dsFunction;
00406
else if (
name==
"dsRegionMarker")
return KateHlItemData::dsRegionMarker;
00407
else if (
name==
"dsError")
return KateHlItemData::dsError;
00408
00409
return KateHlItemData::dsNormal;
00410 }
00411
00412
00413
00414 KateHlItem::KateHlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00415 : attr(attribute),
00416 ctx(context),
00417 region(regionId),
00418 region2(regionId2),
00419 lookAhead(false),
00420 dynamic(false),
00421 dynamicChild(false),
00422 firstNonSpace(false),
00423 onlyConsume(false),
00424 column (-1),
00425 alwaysStartEnable (true),
00426 customStartEnable (false)
00427 {
00428 }
00429
00430 KateHlItem::~KateHlItem()
00431 {
00432
00433
for (uint i=0; i < subItems.size(); i++)
00434
delete subItems[i];
00435 }
00436
00437
void KateHlItem::dynamicSubstitute(QString &str,
const QStringList *args)
00438 {
00439
for (uint i = 0; i < str.length() - 1; ++i)
00440 {
00441
if (str[i] ==
'%')
00442 {
00443
char c = str[i + 1].latin1();
00444
if (c ==
'%')
00445 str.replace(i, 1,
"");
00446
else if (c >=
'0' && c <=
'9')
00447 {
00448
if ((uint)(c -
'0') < args->size())
00449 {
00450 str.replace(i, 2, (*args)[c -
'0']);
00451 i += ((*args)[c -
'0']).length() - 1;
00452 }
00453
else
00454 {
00455 str.replace(i, 2,
"");
00456 --i;
00457 }
00458 }
00459 }
00460 }
00461 }
00462
00463
00464
00465 KateHlCharDetect::KateHlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar c)
00466 : KateHlItem(attribute,context,regionId,regionId2)
00467 , sChar(c)
00468 {
00469 }
00470
00471
int KateHlCharDetect::checkHgl(
const QString& text,
int offset,
int )
00472 {
00473
if (text[offset] == sChar)
00474
return offset + 1;
00475
00476
return 0;
00477 }
00478
00479 KateHlItem *KateHlCharDetect::clone(
const QStringList *args)
00480 {
00481
char c = sChar.latin1();
00482
00483
if (c < '0' || c >
'9' || (
unsigned)(c -
'0') >= args->size())
00484
return this;
00485
00486 KateHlCharDetect *ret =
new KateHlCharDetect(attr, ctx, region, region2, (*args)[c -
'0'][0]);
00487 ret->dynamicChild =
true;
00488
return ret;
00489 }
00490
00491
00492
00493 KateHl2CharDetect::KateHl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00494 : KateHlItem(attribute,context,regionId,regionId2)
00495 , sChar1 (ch1)
00496 , sChar2 (ch2)
00497 {
00498 }
00499
00500
int KateHl2CharDetect::checkHgl(
const QString& text,
int offset,
int len)
00501 {
00502
if ((len >= 2) && text[offset++] == sChar1 && text[offset++] == sChar2)
00503
return offset;
00504
00505
return 0;
00506 }
00507
00508 KateHlItem *KateHl2CharDetect::clone(
const QStringList *args)
00509 {
00510
char c1 = sChar1.latin1();
00511
char c2 = sChar2.latin1();
00512
00513
if (c1 < '0' || c1 >
'9' || (
unsigned)(c1 -
'0') >= args->size())
00514
return this;
00515
00516
if (c2 < '0' || c2 >
'9' || (
unsigned)(c2 -
'0') >= args->size())
00517
return this;
00518
00519 KateHl2CharDetect *ret =
new KateHl2CharDetect(attr, ctx, region, region2, (*args)[c1 -
'0'][0], (*args)[c2 -
'0'][0]);
00520 ret->dynamicChild =
true;
00521
return ret;
00522 }
00523
00524
00525
00526 KateHlStringDetect::KateHlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &s,
bool inSensitive)
00527 : KateHlItem(attribute, context,regionId,regionId2)
00528 , str(inSensitive ? s.upper() : s)
00529 , strLen (str.length())
00530 , _inSensitive(inSensitive)
00531 {
00532 }
00533
00534
int KateHlStringDetect::checkHgl(
const QString& text,
int offset,
int len)
00535 {
00536
if (len < strLen)
00537
return 0;
00538
00539
if (_inSensitive)
00540 {
00541
for (
int i=0; i < strLen; i++)
00542
if (text[offset++].upper() != str[i])
00543
return 0;
00544
00545
return offset;
00546 }
00547
else
00548 {
00549
for (
int i=0; i < strLen; i++)
00550
if (text[offset++] != str[i])
00551
return 0;
00552
00553
return offset;
00554 }
00555
00556
return 0;
00557 }
00558
00559 KateHlItem *KateHlStringDetect::clone(
const QStringList *args)
00560 {
00561 QString newstr = str;
00562
00563 dynamicSubstitute(newstr, args);
00564
00565
if (newstr == str)
00566
return this;
00567
00568 KateHlStringDetect *ret =
new KateHlStringDetect(attr, ctx, region, region2, newstr, _inSensitive);
00569 ret->dynamicChild =
true;
00570
return ret;
00571 }
00572
00573
00574
00575 KateHlRangeDetect::KateHlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00576 : KateHlItem(attribute,context,regionId,regionId2)
00577 , sChar1 (ch1)
00578 , sChar2 (ch2)
00579 {
00580 }
00581
00582
int KateHlRangeDetect::checkHgl(
const QString& text,
int offset,
int len)
00583 {
00584
if (text[offset] == sChar1)
00585 {
00586
do
00587 {
00588 offset++;
00589 len--;
00590
if (len < 1)
return 0;
00591 }
00592
while (text[offset] != sChar2);
00593
00594
return offset + 1;
00595 }
00596
return 0;
00597 }
00598
00599
00600
00601 KateHlKeyword::KateHlKeyword (
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims)
00602 : KateHlItem(attribute,context,regionId,regionId2)
00603 , _caseSensitive(casesensitive)
00604 , deliminators(delims)
00605 , minLen (0xFFFFFF)
00606 , maxLen (0)
00607 {
00608 alwaysStartEnable =
false;
00609 customStartEnable =
true;
00610 }
00611
00612 KateHlKeyword::~KateHlKeyword ()
00613 {
00614
for (uint i=0; i < dict.size(); ++i)
00615
delete dict[i];
00616 }
00617
00618
void KateHlKeyword::addList(
const QStringList& list)
00619 {
00620
for(uint i=0; i < list.count(); ++i)
00621 {
00622
int len = list[i].length();
00623
00624
if (minLen > len)
00625 minLen = len;
00626
00627
if (maxLen < len)
00628 maxLen = len;
00629
00630
if ((uint)len >= dict.size())
00631 {
00632 uint oldSize = dict.size();
00633 dict.resize (len+1);
00634
00635
for (uint m=oldSize; m < dict.size(); ++m)
00636 dict[m] = 0;
00637 }
00638
00639
if (!dict[len])
00640 dict[len] =
new QDict<bool> (17, _caseSensitive);
00641
00642 dict[len]->insert(list[i], &trueBool);
00643 }
00644 }
00645
00646
int KateHlKeyword::checkHgl(
const QString& text,
int offset,
int len)
00647 {
00648
int offset2 = offset;
00649
int wordLen = 0;
00650
00651
while ((len > wordLen) && !kateInsideString (deliminators, text[offset2]))
00652 {
00653 offset2++;
00654 wordLen++;
00655
00656
if (wordLen > maxLen)
return 0;
00657 }
00658
00659
if (wordLen < minLen)
return 0;
00660
00661
if ( dict[wordLen] && dict[wordLen]->find(
QConstString(text.unicode() + offset, wordLen).string()) )
00662
return offset2;
00663
00664
return 0;
00665 }
00666
00667
00668
00669 KateHlInt::KateHlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00670 : KateHlItem(attribute,context,regionId,regionId2)
00671 {
00672 alwaysStartEnable =
false;
00673 }
00674
00675
int KateHlInt::checkHgl(
const QString& text,
int offset,
int len)
00676 {
00677
int offset2 = offset;
00678
00679
while ((len > 0) && text[offset2].isDigit())
00680 {
00681 offset2++;
00682 len--;
00683 }
00684
00685
if (offset2 > offset)
00686 {
00687
if (len > 0)
00688 {
00689
for (uint i=0; i < subItems.size(); i++)
00690 {
00691
if ( (offset = subItems[i]->checkHgl(text, offset2, len)) )
00692
return offset;
00693 }
00694 }
00695
00696
return offset2;
00697 }
00698
00699
return 0;
00700 }
00701
00702
00703
00704 KateHlFloat::KateHlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00705 : KateHlItem(attribute,context, regionId,regionId2)
00706 {
00707 alwaysStartEnable =
false;
00708 }
00709
00710
int KateHlFloat::checkHgl(
const QString& text,
int offset,
int len)
00711 {
00712
bool b =
false;
00713
bool p =
false;
00714
00715
while ((len > 0) && text[offset].isDigit())
00716 {
00717 offset++;
00718 len--;
00719 b =
true;
00720 }
00721
00722
if ((len > 0) && (p = (text[offset] ==
'.')))
00723 {
00724 offset++;
00725 len--;
00726
00727
while ((len > 0) && text[offset].isDigit())
00728 {
00729 offset++;
00730 len--;
00731 b =
true;
00732 }
00733 }
00734
00735
if (!b)
00736
return 0;
00737
00738
if ((len > 0) && ((text[offset] & 0xdf) ==
'E'))
00739 {
00740 offset++;
00741 len--;
00742 }
00743
else
00744 {
00745
if (!p)
00746
return 0;
00747
else
00748 {
00749
if (len > 0)
00750 {
00751
for (uint i=0; i < subItems.size(); i++)
00752 {
00753
int offset2 = subItems[i]->checkHgl(text, offset, len);
00754
00755
if (offset2)
00756
return offset2;
00757 }
00758 }
00759
00760
return offset;
00761 }
00762 }
00763
00764
if ((len > 0) && (text[offset] ==
'-' || text[offset] ==
'+'))
00765 {
00766 offset++;
00767 len--;
00768 }
00769
00770 b =
false;
00771
00772
while ((len > 0) && text[offset].isDigit())
00773 {
00774 offset++;
00775 len--;
00776 b =
true;
00777 }
00778
00779
if (b)
00780 {
00781
if (len > 0)
00782 {
00783
for (uint i=0; i < subItems.size(); i++)
00784 {
00785
int offset2 = subItems[i]->checkHgl(text, offset, len);
00786
00787
if (offset2)
00788
return offset2;
00789 }
00790 }
00791
00792
return offset;
00793 }
00794
00795
return 0;
00796 }
00797
00798
00799
00800 KateHlCOct::KateHlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00801 : KateHlItem(attribute,context,regionId,regionId2)
00802 {
00803 alwaysStartEnable =
false;
00804 }
00805
00806
int KateHlCOct::checkHgl(
const QString& text,
int offset,
int len)
00807 {
00808
if (text[offset] ==
'0')
00809 {
00810 offset++;
00811 len--;
00812
00813
int offset2 = offset;
00814
00815
while ((len > 0) && (text[offset2] >=
'0' && text[offset2] <=
'7'))
00816 {
00817 offset2++;
00818 len--;
00819 }
00820
00821
if (offset2 > offset)
00822 {
00823
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset] & 0xdf) ==
'U' ))
00824 offset2++;
00825
00826
return offset2;
00827 }
00828 }
00829
00830
return 0;
00831 }
00832
00833
00834
00835 KateHlCHex::KateHlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00836 : KateHlItem(attribute,context,regionId,regionId2)
00837 {
00838 alwaysStartEnable =
false;
00839 }
00840
00841
int KateHlCHex::checkHgl(
const QString& text,
int offset,
int len)
00842 {
00843
if ((len > 1) && (text[offset++] ==
'0') && ((text[offset++] & 0xdf) ==
'X' ))
00844 {
00845 len -= 2;
00846
00847
int offset2 = offset;
00848
00849
while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >=
'A' && (text[offset2] & 0xdf) <=
'F')))
00850 {
00851 offset2++;
00852 len--;
00853 }
00854
00855
if (offset2 > offset)
00856 {
00857
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset2] & 0xdf) ==
'U' ))
00858 offset2++;
00859
00860
return offset2;
00861 }
00862 }
00863
00864
return 0;
00865 }
00866
00867
00868
00869 KateHlCFloat::KateHlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00870 : KateHlFloat(attribute,context,regionId,regionId2)
00871 {
00872 alwaysStartEnable =
false;
00873 }
00874
00875
int KateHlCFloat::checkIntHgl(
const QString& text,
int offset,
int len)
00876 {
00877
int offset2 = offset;
00878
00879
while ((len > 0) && text[offset].isDigit()) {
00880 offset2++;
00881 len--;
00882 }
00883
00884
if (offset2 > offset)
00885
return offset2;
00886
00887
return 0;
00888 }
00889
00890
int KateHlCFloat::checkHgl(
const QString& text,
int offset,
int len)
00891 {
00892
int offset2 = KateHlFloat::checkHgl(text, offset, len);
00893
00894
if (offset2)
00895 {
00896
if ((text[offset2] & 0xdf) ==
'F' )
00897 offset2++;
00898
00899
return offset2;
00900 }
00901
else
00902 {
00903 offset2 = checkIntHgl(text, offset, len);
00904
00905
if (offset2 && ((text[offset2] & 0xdf) ==
'F' ))
00906
return ++offset2;
00907
else
00908
return 0;
00909 }
00910 }
00911
00912
00913
00914 KateHlAnyChar::KateHlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList)
00915 : KateHlItem(attribute, context,regionId,regionId2)
00916 , _charList(charList)
00917 {
00918 }
00919
00920
int KateHlAnyChar::checkHgl(
const QString& text,
int offset,
int)
00921 {
00922
if (kateInsideString (_charList, text[offset]))
00923
return ++offset;
00924
00925
return 0;
00926 }
00927
00928
00929
00930 KateHlRegExpr::KateHlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2, QString regexp,
bool insensitive,
bool minimal)
00931 : KateHlItem(attribute, context, regionId,regionId2)
00932 , handlesLinestart (regexp.startsWith("^"))
00933 , _regexp(regexp)
00934 , _insensitive(insensitive)
00935 , _minimal(minimal)
00936 {
00937
if (!handlesLinestart)
00938 regexp.prepend(
"^");
00939
00940 Expr =
new QRegExp(regexp, !_insensitive);
00941 Expr->setMinimal(_minimal);
00942 }
00943
00944
int KateHlRegExpr::checkHgl(
const QString& text,
int offset,
int )
00945 {
00946
if (offset && handlesLinestart)
00947
return 0;
00948
00949
int offset2 = Expr->search( text, offset, QRegExp::CaretAtOffset );
00950
00951
if (offset2 == -1)
return 0;
00952
00953
return (offset + Expr->matchedLength());
00954 }
00955
00956
QStringList *KateHlRegExpr::capturedTexts()
00957 {
00958
return new QStringList(Expr->capturedTexts());
00959 }
00960
00961 KateHlItem *KateHlRegExpr::clone(
const QStringList *args)
00962 {
00963 QString regexp = _regexp;
00964
QStringList escArgs = *args;
00965
00966
for (QStringList::Iterator it = escArgs.begin(); it != escArgs.end(); ++it)
00967 {
00968 (*it).replace(
QRegExp(
"(\\W)"),
"\\\\1");
00969 }
00970
00971 dynamicSubstitute(regexp, &escArgs);
00972
00973
if (regexp == _regexp)
00974
return this;
00975
00976
00977
00978 KateHlRegExpr *ret =
new KateHlRegExpr(attr, ctx, region, region2, regexp, _insensitive, _minimal);
00979 ret->dynamicChild =
true;
00980
return ret;
00981 }
00982
00983
00984
00985 KateHlLineContinue::KateHlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00986 : KateHlItem(attribute,context,regionId,regionId2) {
00987 }
00988
00989
int KateHlLineContinue::checkHgl(
const QString& text,
int offset,
int len)
00990 {
00991
if ((len == 1) && (text[offset] ==
'\\'))
00992
return ++offset;
00993
00994
return 0;
00995 }
00996
00997
00998
00999 KateHlCStringChar::KateHlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
01000 : KateHlItem(attribute,context,regionId,regionId2) {
01001 }
01002
01003
01004
static int checkEscapedChar(
const QString& text,
int offset,
int& len)
01005 {
01006
int i;
01007
if (text[offset] ==
'\\' && len > 1)
01008 {
01009 offset++;
01010 len--;
01011
01012
switch(text[offset])
01013 {
01014
case 'a':
01015
case 'b':
01016
case 'e':
01017
case 'f':
01018
01019
case 'n':
01020
case 'r':
01021
case 't':
01022
case 'v':
01023
case '\'':
01024
case '\"':
01025
case '?' :
01026
case '\\':
01027 offset++;
01028 len--;
01029
break;
01030
01031
case 'x':
01032 offset++;
01033 len--;
01034
01035
01036
01037
01038
for (i = 0; (len > 0) && (i < 2) && (text[offset] >=
'0' && text[offset] <=
'9' || (text[offset] & 0xdf) >=
'A' && (text[offset] & 0xdf) <=
'F'); i++)
01039 {
01040 offset++;
01041 len--;
01042 }
01043
01044
if (i == 0)
01045
return 0;
01046
01047
break;
01048
01049
case '0':
case '1':
case '2':
case '3' :
01050
case '4':
case '5':
case '6':
case '7' :
01051
for (i = 0; (len > 0) && (i < 3) && (text[offset] >=
'0'&& text[offset] <=
'7'); i++)
01052 {
01053 offset++;
01054 len--;
01055 }
01056
break;
01057
01058
default:
01059
return 0;
01060 }
01061
01062
return offset;
01063 }
01064
01065
return 0;
01066 }
01067
01068
int KateHlCStringChar::checkHgl(
const QString& text,
int offset,
int len)
01069 {
01070
return checkEscapedChar(text, offset, len);
01071 }
01072
01073
01074
01075 KateHlCChar::KateHlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
01076 : KateHlItem(attribute,context,regionId,regionId2) {
01077 }
01078
01079
int KateHlCChar::checkHgl(
const QString& text,
int offset,
int len)
01080 {
01081
if ((len > 1) && (text[offset] ==
'\'') && (text[offset+1] !=
'\''))
01082 {
01083
int oldl;
01084 oldl = len;
01085
01086 len--;
01087
01088
int offset2 = checkEscapedChar(text, offset + 1, len);
01089
01090
if (!offset2)
01091 {
01092
if (oldl > 2)
01093 {
01094 offset2 = offset + 2;
01095 len = oldl - 2;
01096 }
01097
else
01098 {
01099
return 0;
01100 }
01101 }
01102
01103
if ((len > 0) && (text[offset2] ==
'\''))
01104
return ++offset2;
01105 }
01106
01107
return 0;
01108 }
01109
01110
01111
01112 KateHl2CharDetect::KateHl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *s)
01113 : KateHlItem(attribute,context,regionId,regionId2) {
01114 sChar1 = s[0];
01115 sChar2 = s[1];
01116 }
01117
01118
01119 KateHlItemData::KateHlItemData(
const QString name,
int defStyleNum)
01120 :
name(
name), defStyleNum(defStyleNum) {
01121 }
01122
01123 KateHlData::KateHlData(
const QString &wildcards,
const QString &mimetypes,
const QString &identifier,
int priority)
01124 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
01125 {
01126 }
01127
01128
01129 KateHlContext::KateHlContext (
const QString &_hlId,
int attribute,
int lineEndContext,
int _lineBeginContext,
bool _fallthrough,
int _fallthroughContext,
bool _dynamic)
01130 {
01131 hlId = _hlId;
01132 attr = attribute;
01133 ctx = lineEndContext;
01134 lineBeginContext = _lineBeginContext;
01135 fallthrough = _fallthrough;
01136 ftctx = _fallthroughContext;
01137 dynamic = _dynamic;
01138 dynamicChild =
false;
01139 }
01140
01141 KateHlContext *KateHlContext::clone(
const QStringList *args)
01142 {
01143 KateHlContext *ret =
new KateHlContext(hlId, attr, ctx, lineBeginContext, fallthrough, ftctx,
false);
01144
01145
for (uint n=0; n < items.size(); ++n)
01146 {
01147 KateHlItem *item = items[n];
01148 KateHlItem *i = (item->dynamic ? item->clone(args) : item);
01149 ret->items.append(i);
01150 }
01151
01152 ret->dynamicChild =
true;
01153
01154
return ret;
01155 }
01156
01157 KateHlContext::~KateHlContext()
01158 {
01159
if (dynamicChild)
01160 {
01161
for (uint n=0; n < items.size(); ++n)
01162 {
01163
if (items[n]->dynamicChild)
01164
delete items[n];
01165 }
01166 }
01167 }
01168
01169
01170
01171 KateHighlighting::KateHighlighting(
const KateSyntaxModeListItem *def) : refCount(0)
01172 {
01173 m_attributeArrays.setAutoDelete (
true);
01174
01175 errorsAndWarnings =
"";
01176 building=
false;
01177 noHl =
false;
01178 m_foldingIndentationSensitive =
false;
01179 folding=
false;
01180 internalIDList.setAutoDelete(
true);
01181
01182
if (def == 0)
01183 {
01184 noHl =
true;
01185 iName =
"None";
01186 iNameTranslated = i18n(
"None");
01187 iSection =
"";
01188 m_priority = 0;
01189 iHidden =
false;
01190 m_additionalData.insert(
"none",
new HighlightPropertyBag );
01191 m_additionalData[
"none"]->deliminator = stdDeliminator;
01192 m_additionalData[
"none"]->wordWrapDeliminator = stdDeliminator;
01193 m_hlIndex[0] =
"none";
01194 }
01195
else
01196 {
01197 iName = def->
name;
01198 iNameTranslated = def->
nameTranslated;
01199 iSection = def->
section;
01200 iHidden = def->
hidden;
01201 iWildcards = def->
extension;
01202 iMimetypes = def->
mimetype;
01203 identifier = def->
identifier;
01204 iVersion=def->
version;
01205 iAuthor=def->
author;
01206 iLicense=def->
license;
01207 m_priority=def->
priority.toInt();
01208 }
01209
01210 deliminator = stdDeliminator;
01211 }
01212
01213 KateHighlighting::~KateHighlighting()
01214 {
01215
for (uint i=0; i < m_contexts.size(); ++i)
01216
delete m_contexts[i];
01217 }
01218
01219
void KateHighlighting::generateContextStack(
int *ctxNum,
int ctx,
QMemArray<short>* ctxs,
int *prevLine)
01220 {
01221
01222
while (
true)
01223 {
01224
if (ctx >= 0)
01225 {
01226 (*ctxNum) = ctx;
01227
01228 ctxs->resize (ctxs->size()+1, QGArray::SpeedOptim);
01229 (*ctxs)[ctxs->size()-1]=(*ctxNum);
01230
01231
return;
01232 }
01233
else
01234 {
01235
if (ctx == -1)
01236 {
01237 (*ctxNum)=( (ctxs->isEmpty() ) ? 0 : (*ctxs)[ctxs->size()-1]);
01238 }
01239
else
01240 {
01241
int size = ctxs->size() + ctx + 1;
01242
01243
if (size > 0)
01244 {
01245 ctxs->resize (size, QGArray::SpeedOptim);
01246 (*ctxNum)=(*ctxs)[size-1];
01247 }
01248
else
01249 {
01250 ctxs->resize (0, QGArray::SpeedOptim);
01251 (*ctxNum)=0;
01252 }
01253
01254 ctx = 0;
01255
01256
if ((*prevLine) >= (
int)(ctxs->size()-1))
01257 {
01258 *prevLine=ctxs->size()-1;
01259
01260
if ( ctxs->isEmpty() )
01261
return;
01262
01263 KateHlContext *c = contextNum((*ctxs)[ctxs->size()-1]);
01264
if (c && (c->ctx != -1))
01265 {
01266
01267 ctx = c->ctx;
01268
01269
continue;
01270 }
01271 }
01272 }
01273
01274
return;
01275 }
01276 }
01277 }
01278
01282
int KateHighlighting::makeDynamicContext(KateHlContext *model,
const QStringList *args)
01283 {
01284
QPair<KateHlContext *, QString> key(model, args->front());
01285
short value;
01286
01287
if (dynamicCtxs.contains(key))
01288 value = dynamicCtxs[
key];
01289
else
01290 {
01291
kdDebug(13010) <<
"new stuff: " << startctx <<
endl;
01292
01293 KateHlContext *newctx = model->clone(args);
01294
01295 m_contexts.push_back (newctx);
01296
01297 value = startctx++;
01298 dynamicCtxs[
key] = value;
01299 KateHlManager::self()->incDynamicCtxs();
01300 }
01301
01302
01303
01304
return value;
01305 }
01306
01311
void KateHighlighting::dropDynamicContexts()
01312 {
01313
for (uint i=base_startctx; i < m_contexts.size(); ++i)
01314
delete m_contexts[i];
01315
01316 m_contexts.resize (base_startctx);
01317
01318 dynamicCtxs.clear();
01319 startctx = base_startctx;
01320 }
01321
01330
void KateHighlighting::doHighlight (
KateTextLine *prevLine,
01331
KateTextLine *textLine,
01332
QMemArray<uint>* foldingList,
01333
bool *ctxChanged )
01334 {
01335
if (!textLine)
01336
return;
01337
01338
if (noHl)
01339 {
01340
if (textLine->
length() > 0)
01341 memset (textLine->
attributes(), 0, textLine->
length());
01342
01343
return;
01344 }
01345
01346
01347
QMemArray<short> ctx;
01348 ctx.duplicate (prevLine->
ctxArray());
01349
01350
int ctxNum = 0;
01351
int previousLine = -1;
01352 KateHlContext *context;
01353
01354
if (ctx.isEmpty())
01355 {
01356
01357 context = contextNum(ctxNum);
01358 }
01359
else
01360 {
01361
01362 ctxNum = ctx[ctx.size()-1];
01363
01364
01365
01366
01367
01368
if (!(context = contextNum(ctxNum)))
01369 context = contextNum(0);
01370
01371
01372
01373 previousLine=ctx.size()-1;
01374
01375
01376
if (prevLine->
hlLineContinue())
01377 {
01378 prevLine--;
01379 }
01380
else
01381 {
01382 generateContextStack(&ctxNum, context->ctx, &ctx, &previousLine);
01383
01384
if (!(context = contextNum(ctxNum)))
01385 context = contextNum(0);
01386 }
01387
01388
01389
01390
01391 }
01392
01393
01394
QChar lastChar =
' ';
01395
const QString& text = textLine->
string();
01396
const int len = textLine->
length();
01397
01398
01399
const int firstChar = textLine->
firstChar();
01400
const int startNonSpace = (firstChar == -1) ? len : firstChar;
01401
01402
01403 KateHlItem *item = 0;
01404
01405
01406
int offset = 0;
01407
while (offset < len)
01408 {
01409
bool anItemMatched =
false;
01410
bool standardStartEnableDetermined =
false;
01411
bool customStartEnableDetermined =
false;
01412
01413 uint index = 0;
01414
for (item = context->items.empty() ? 0 : context->items[0]; item; item = (++index < context->items.size()) ? context->items[index] : 0 )
01415 {
01416
01417
if (item->firstNonSpace && (offset > startNonSpace))
01418
continue;
01419
01420
01421
if ((item->column != -1) && (item->column != offset))
01422
continue;
01423
01424
if (!item->alwaysStartEnable)
01425 {
01426
if (item->customStartEnable)
01427 {
01428
if (customStartEnableDetermined || kateInsideString (m_additionalData[context->hlId]->deliminator, lastChar))
01429 customStartEnableDetermined =
true;
01430
else
01431
continue;
01432 }
01433
else
01434 {
01435
if (standardStartEnableDetermined || kateInsideString (stdDeliminator, lastChar))
01436 standardStartEnableDetermined =
true;
01437
else
01438
continue;
01439 }
01440 }
01441
01442
int offset2 = item->checkHgl(text, offset, len-offset);
01443
01444
if (offset2 <= offset)
01445
continue;
01446
01447
if (item->region2)
01448 {
01449
01450
if ( !foldingList->isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->size()-2] == -item->region2 ) )
01451 {
01452 foldingList->resize (foldingList->size()-2, QGArray::SpeedOptim);
01453 }
01454
else
01455 {
01456 foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
01457 (*foldingList)[foldingList->size()-2] = (uint)item->region2;
01458
if (item->region2<0)
01459 (*foldingList)[foldingList->size()-1] = offset2;
01460
else
01461 (*foldingList)[foldingList->size()-1] = offset;
01462 }
01463
01464 }
01465
01466
if (item->region)
01467 {
01468
01469
01470
01471
01472
01473
01474
01475 {
01476 foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
01477 (*foldingList)[foldingList->size()-2] = item->region;
01478
if (item->region<0)
01479 (*foldingList)[foldingList->size()-1] = offset2;
01480
else
01481 (*foldingList)[foldingList->size()-1] = offset;
01482 }
01483
01484 }
01485
01486
01487
if (item->ctx != -1)
01488 {
01489 generateContextStack (&ctxNum, item->ctx, &ctx, &previousLine);
01490 context = contextNum(ctxNum);
01491 }
01492
01493
01494
if (context->dynamic)
01495 {
01496
QStringList *lst = item->capturedTexts();
01497
if (lst != 0)
01498 {
01499
01500
int newctx = makeDynamicContext(context, lst);
01501
if (ctx.size() > 0)
01502 ctx[ctx.size() - 1] = newctx;
01503 ctxNum = newctx;
01504 context = contextNum(ctxNum);
01505 }
01506
delete lst;
01507 }
01508
01509
01510
if (!item->lookAhead)
01511 {
01512
if (offset2 > len)
01513 offset2 = len;
01514
01515
01516 memset ( textLine->
attributes()+offset
01517 , item->onlyConsume ? context->attr : item->attr
01518 , len-offset);
01519
01520 offset = offset2;
01521 lastChar = text[offset-1];
01522 }
01523
01524 anItemMatched =
true;
01525
break;
01526 }
01527
01528
01529
if (anItemMatched)
01530
continue;
01531
01532
01533
01534
if ( context->fallthrough )
01535 {
01536
01537 generateContextStack(&ctxNum, context->ftctx, &ctx, &previousLine);
01538 context=contextNum(ctxNum);
01539
01540
01541
01542
01543
01544
01545
01546
01547
continue;
01548 }
01549
else
01550 {
01551 *(textLine->
attributes() + offset) = context->attr;
01552 lastChar = text[offset];
01553 offset++;
01554 }
01555 }
01556
01557
01558
if (ctx == textLine->
ctxArray())
01559 {
01560
if (ctxChanged)
01561 (*ctxChanged) =
false;
01562 }
01563
else
01564 {
01565
if (ctxChanged)
01566 (*ctxChanged) =
true;
01567
01568
01569 textLine->
setContext(ctx);
01570 }
01571
01572
01573 textLine->
setHlLineContinue (item && item->lineContinue());
01574 }
01575
01576
void KateHighlighting::loadWildcards()
01577 {
01578
KConfig *config = KateHlManager::self()->getKConfig();
01579 config->
setGroup(
"Highlighting " + iName);
01580
01581 QString extensionString = config->
readEntry(
"Wildcards", iWildcards);
01582
01583
if (extensionSource != extensionString) {
01584 regexpExtensions.clear();
01585 plainExtensions.clear();
01586
01587 extensionSource = extensionString;
01588
01589
static QRegExp sep(
"\\s*;\\s*");
01590
01591
QStringList l = QStringList::split( sep, extensionSource );
01592
01593
static QRegExp boringExpression(
"\\*\\.[\\d\\w]+");
01594
01595
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
01596
if (boringExpression.exactMatch(*it))
01597 plainExtensions.append((*it).mid(1));
01598
else
01599 regexpExtensions.append(
QRegExp((*it),
true,
true));
01600 }
01601 }
01602
01603
QValueList<QRegExp>& KateHighlighting::getRegexpExtensions()
01604 {
01605
return regexpExtensions;
01606 }
01607
01608
QStringList& KateHighlighting::getPlainExtensions()
01609 {
01610
return plainExtensions;
01611 }
01612
01613 QString KateHighlighting::getMimetypes()
01614 {
01615
KConfig *config = KateHlManager::self()->getKConfig();
01616 config->
setGroup(
"Highlighting " + iName);
01617
01618
return config->
readEntry(
"Mimetypes", iMimetypes);
01619 }
01620
01621
int KateHighlighting::priority()
01622 {
01623
KConfig *config = KateHlManager::self()->getKConfig();
01624 config->
setGroup(
"Highlighting " + iName);
01625
01626
return config->
readNumEntry(
"Priority", m_priority);
01627 }
01628
01629 KateHlData *KateHighlighting::getData()
01630 {
01631
KConfig *config = KateHlManager::self()->getKConfig();
01632 config->
setGroup(
"Highlighting " + iName);
01633
01634 KateHlData *hlData =
new KateHlData(
01635 config->
readEntry(
"Wildcards", iWildcards),
01636 config->
readEntry(
"Mimetypes", iMimetypes),
01637 config->
readEntry(
"Identifier", identifier),
01638 config->
readNumEntry(
"Priority", m_priority));
01639
01640
return hlData;
01641 }
01642
01643
void KateHighlighting::setData(KateHlData *hlData)
01644 {
01645
KConfig *config = KateHlManager::self()->getKConfig();
01646 config->
setGroup(
"Highlighting " + iName);
01647
01648 config->
writeEntry(
"Wildcards",hlData->wildcards);
01649 config->
writeEntry(
"Mimetypes",hlData->mimetypes);
01650 config->
writeEntry(
"Priority",hlData->priority);
01651 }
01652
01653
void KateHighlighting::getKateHlItemDataList (uint schema,
KateHlItemDataList &list)
01654 {
01655
KConfig *config = KateHlManager::self()->getKConfig();
01656 config->
setGroup(
"Highlighting " + iName +
" - Schema " + KateFactory::self()->schemaManager()->
name(schema));
01657
01658 list.clear();
01659 createKateHlItemData(list);
01660
01661
for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
01662 {
01663
QStringList s = config->
readListEntry(p->name);
01664
01665
01666
if (s.count()>0)
01667 {
01668
01669
while(s.count()<9) s<<
"";
01670 p->clear();
01671
01672 QString tmp=s[0];
if (!tmp.isEmpty()) p->defStyleNum=tmp.toInt();
01673
01674 QRgb col;
01675
01676 tmp=s[1];
if (!tmp.isEmpty()) {
01677 col=tmp.toUInt(0,16); p->setTextColor(col); }
01678
01679 tmp=s[2];
if (!tmp.isEmpty()) {
01680 col=tmp.toUInt(0,16); p->setSelectedTextColor(col); }
01681
01682 tmp=s[3];
if (!tmp.isEmpty()) p->setBold(tmp!=
"0");
01683
01684 tmp=s[4];
if (!tmp.isEmpty()) p->setItalic(tmp!=
"0");
01685
01686 tmp=s[5];
if (!tmp.isEmpty()) p->setStrikeOut(tmp!=
"0");
01687
01688 tmp=s[6];
if (!tmp.isEmpty()) p->setUnderline(tmp!=
"0");
01689
01690 tmp=s[7];
if (!tmp.isEmpty()) {
01691 col=tmp.toUInt(0,16); p->setBGColor(col); }
01692
01693 tmp=s[8];
if (!tmp.isEmpty()) {
01694 col=tmp.toUInt(0,16); p->setSelectedBGColor(col); }
01695
01696 }
01697 }
01698 }
01699
01706
void KateHighlighting::setKateHlItemDataList(uint schema,
KateHlItemDataList &list)
01707 {
01708
KConfig *config = KateHlManager::self()->getKConfig();
01709 config->
setGroup(
"Highlighting " + iName +
" - Schema "
01710 + KateFactory::self()->schemaManager()->
name(schema));
01711
01712
QStringList settings;
01713
01714
for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
01715 {
01716 settings.clear();
01717 settings<<QString::number(p->defStyleNum,10);
01718 settings<<(p->itemSet(KateAttribute::TextColor)?QString::number(p->textColor().rgb(),16):
"");
01719 settings<<(p->itemSet(KateAttribute::SelectedTextColor)?QString::number(p->selectedTextColor().rgb(),16):
"");
01720 settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?
"1":
"0"):
"");
01721 settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?
"1":
"0"):
"");
01722 settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?
"1":
"0"):
"");
01723 settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?
"1":
"0"):
"");
01724 settings<<(p->itemSet(KateAttribute::BGColor)?QString::number(p->bgColor().rgb(),16):
"");
01725 settings<<(p->itemSet(KateAttribute::SelectedBGColor)?QString::number(p->selectedBGColor().rgb(),16):
"");
01726 settings<<
"---";
01727 config->
writeEntry(p->name,settings);
01728 }
01729 }
01730
01734
void KateHighlighting::use()
01735 {
01736
if (refCount == 0)
01737 init();
01738
01739 refCount++;
01740 }
01741
01745
void KateHighlighting::release()
01746 {
01747 refCount--;
01748
01749
if (refCount == 0)
01750 done();
01751 }
01752
01757
void KateHighlighting::init()
01758 {
01759
if (noHl)
01760
return;
01761
01762 m_contexts.clear ();
01763 makeContextList();
01764 }
01765
01766
01771
void KateHighlighting::done()
01772 {
01773
if (noHl)
01774
return;
01775
01776 m_contexts.clear ();
01777 internalIDList.clear();
01778 }
01779
01787
void KateHighlighting::createKateHlItemData(
KateHlItemDataList &list)
01788 {
01789
01790
if (noHl)
01791 {
01792 list.append(
new KateHlItemData(i18n(
"Normal Text"), KateHlItemData::dsNormal));
01793
return;
01794 }
01795
01796
01797
if (internalIDList.isEmpty())
01798 makeContextList();
01799
01800 list=internalIDList;
01801 }
01802
01806
void KateHighlighting::addToKateHlItemDataList()
01807 {
01808
01809 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
01810
KateSyntaxContextData *data = KateHlManager::self()->syntax->getGroupInfo(
"highlighting",
"itemData");
01811
01812
01813
while (KateHlManager::self()->syntax->nextGroup(data))
01814 {
01815
01816 QString color = KateHlManager::self()->syntax->groupData(data,QString(
"color"));
01817 QString selColor = KateHlManager::self()->syntax->groupData(data,QString(
"selColor"));
01818 QString bold = KateHlManager::self()->syntax->groupData(data,QString(
"bold"));
01819 QString italic = KateHlManager::self()->syntax->groupData(data,QString(
"italic"));
01820 QString underline = KateHlManager::self()->syntax->groupData(data,QString(
"underline"));
01821 QString strikeOut = KateHlManager::self()->syntax->groupData(data,QString(
"strikeOut"));
01822 QString bgColor = KateHlManager::self()->syntax->groupData(data,QString(
"backgroundColor"));
01823 QString selBgColor = KateHlManager::self()->syntax->groupData(data,QString(
"selBackgroundColor"));
01824
01825 KateHlItemData* newData =
new KateHlItemData(
01826 buildPrefix+KateHlManager::self()->syntax->groupData(data,QString(
"name")).simplifyWhiteSpace(),
01827 getDefStyleNum(KateHlManager::self()->syntax->groupData(data,QString(
"defStyleNum"))));
01828
01829
01830
if (!color.isEmpty()) newData->setTextColor(
QColor(color));
01831
if (!selColor.isEmpty()) newData->setSelectedTextColor(
QColor(selColor));
01832
if (!bold.isEmpty()) newData->setBold( IS_TRUE(bold) );
01833
if (!italic.isEmpty()) newData->setItalic( IS_TRUE(italic) );
01834
01835
if (!underline.isEmpty()) newData->setUnderline( IS_TRUE(underline) );
01836
if (!strikeOut.isEmpty()) newData->setStrikeOut( IS_TRUE(strikeOut) );
01837
if (!bgColor.isEmpty()) newData->setBGColor(
QColor(bgColor));
01838
if (!selBgColor.isEmpty()) newData->setSelectedBGColor(
QColor(selBgColor));
01839
01840 internalIDList.append(newData);
01841 }
01842
01843
01844
if (data)
01845 KateHlManager::self()->syntax->freeGroupInfo(data);
01846 }
01847
01858
int KateHighlighting::lookupAttrName(
const QString& name,
KateHlItemDataList &iDl)
01859 {
01860
for (uint i = 0; i < iDl.count(); i++)
01861
if (iDl.at(i)->name == buildPrefix+
name)
01862
return i;
01863
01864
kdDebug(13010)<<
"Couldn't resolve itemDataName:"<<
name<<
endl;
01865
return 0;
01866 }
01867
01881 KateHlItem *KateHighlighting::createKateHlItem(
KateSyntaxContextData *data,
01882
KateHlItemDataList &iDl,
01883
QStringList *RegionList,
01884
QStringList *ContextNameList)
01885 {
01886
01887
if (noHl)
01888
return 0;
01889
01890
01891 QString dataname=KateHlManager::self()->syntax->groupItemData(data,QString(
""));
01892
01893
01894 QString beginRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString(
"beginRegion"));
01895 QString endRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString(
"endRegion"));
01896
01897
signed char regionId=0;
01898
signed char regionId2=0;
01899
01900
if (!beginRegionStr.isEmpty())
01901 {
01902 regionId = RegionList->findIndex(beginRegionStr);
01903
01904
if (regionId==-1)
01905 {
01906 (*RegionList)<<beginRegionStr;
01907 regionId = RegionList->findIndex(beginRegionStr);
01908 }
01909
01910 regionId++;
01911
01912
kdDebug(13010) <<
"########### BEG REG: " << beginRegionStr <<
" NUM: " << regionId <<
endl;
01913 }
01914
01915
if (!endRegionStr.isEmpty())
01916 {
01917 regionId2 = RegionList->findIndex(endRegionStr);
01918
01919
if (regionId2==-1)
01920 {
01921 (*RegionList)<<endRegionStr;
01922 regionId2 = RegionList->findIndex(endRegionStr);
01923 }
01924
01925 regionId2 = -regionId2 - 1;
01926
01927
kdDebug(13010) <<
"########### END REG: " << endRegionStr <<
" NUM: " << regionId2 <<
endl;
01928 }
01929
01930
int attr = 0;
01931 QString tmpAttr=KateHlManager::self()->syntax->groupItemData(data,QString(
"attribute")).simplifyWhiteSpace();
01932
bool onlyConsume = tmpAttr.isEmpty();
01933
01934
01935
if (!onlyConsume)
01936 {
01937
if (QString(
"%1").arg(tmpAttr.toInt())==tmpAttr)
01938 {
01939 errorsAndWarnings+=i18n(
01940
"<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
01941 arg(buildIdentifier).arg(tmpAttr);
01942 attr=tmpAttr.toInt();
01943 }
01944
else
01945 attr=lookupAttrName(tmpAttr,iDl);
01946 }
01947
01948
01949
int context = -1;
01950 QString unresolvedContext;
01951 QString tmpcontext=KateHlManager::self()->syntax->groupItemData(data,QString(
"context"));
01952
if (!tmpcontext.isEmpty())
01953 context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
01954
01955
01956
char chr;
01957
if (! KateHlManager::self()->syntax->groupItemData(data,QString(
"char")).isEmpty())
01958 chr= (KateHlManager::self()->syntax->groupItemData(data,QString(
"char")).latin1())[0];
01959
else
01960 chr=0;
01961
01962
01963 QString stringdata=KateHlManager::self()->syntax->groupItemData(data,QString(
"String"));
01964
01965
01966
char chr1;
01967
if (! KateHlManager::self()->syntax->groupItemData(data,QString(
"char1")).isEmpty())
01968 chr1= (KateHlManager::self()->syntax->groupItemData(data,QString(
"char1")).latin1())[0];
01969
else
01970 chr1=0;
01971
01972
01973
bool insensitive = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString(
"insensitive")) );
01974
01975
01976
bool minimal = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString(
"minimal")) );
01977
01978
01979
bool lookAhead = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString(
"lookAhead")) );
01980
01981
bool dynamic= IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString(
"dynamic")) );
01982
01983
bool firstNonSpace = IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString(
"firstNonSpace")) );
01984
01985
int column = -1;
01986 QString colStr = KateHlManager::self()->syntax->groupItemData(data,QString(
"column"));
01987
if (!colStr.isEmpty())
01988 column = colStr.toInt();
01989
01990
01991 KateHlItem *tmpItem;
01992
01993
if (dataname==
"keyword")
01994 {
01995 KateHlKeyword *keyword=
new KateHlKeyword(attr,context,regionId,regionId2,casesensitive,
01996 m_additionalData[ buildIdentifier ]->deliminator);
01997
01998
01999 keyword->addList(KateHlManager::self()->syntax->finddata(
"highlighting",stringdata));
02000 tmpItem=keyword;
02001 }
02002
else if (dataname==
"Float") tmpItem= (
new KateHlFloat(attr,context,regionId,regionId2));
02003
else if (dataname==
"Int") tmpItem=(
new KateHlInt(attr,context,regionId,regionId2));
02004
else if (dataname==
"DetectChar") tmpItem=(
new KateHlCharDetect(attr,context,regionId,regionId2,chr));
02005
else if (dataname==
"Detect2Chars") tmpItem=(
new KateHl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
02006
else if (dataname==
"RangeDetect") tmpItem=(
new KateHlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
02007
else if (dataname==
"LineContinue") tmpItem=(
new KateHlLineContinue(attr,context,regionId,regionId2));
02008
else if (dataname==
"StringDetect") tmpItem=(
new KateHlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
02009
else if (dataname==
"AnyChar") tmpItem=(
new KateHlAnyChar(attr,context,regionId,regionId2,stringdata));
02010
else if (dataname==
"RegExpr") tmpItem=(
new KateHlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
02011
else if (dataname==
"HlCChar") tmpItem= (
new KateHlCChar(attr,context,regionId,regionId2));
02012
else if (dataname==
"HlCHex") tmpItem= (
new KateHlCHex(attr,context,regionId,regionId2));
02013
else if (dataname==
"HlCOct") tmpItem= (
new KateHlCOct(attr,context,regionId,regionId2));
02014
else if (dataname==
"HlCFloat") tmpItem= (
new KateHlCFloat(attr,context,regionId,regionId2));
02015
else if (dataname==
"HlCStringChar") tmpItem= (
new KateHlCStringChar(attr,context,regionId,regionId2));
02016
else if (dataname==
"DetectSpaces") tmpItem= (
new KateHlDetectSpaces(attr,context,regionId,regionId2));
02017
else if (dataname==
"DetectIdentifier") tmpItem= (
new KateHlDetectIdentifier(attr,context,regionId,regionId2));
02018
else
02019 {
02020
02021
return 0;
02022 }
02023
02024
02025 tmpItem->lookAhead = lookAhead;
02026 tmpItem->dynamic = dynamic;
02027 tmpItem->firstNonSpace = firstNonSpace;
02028 tmpItem->column = column;
02029 tmpItem->onlyConsume = onlyConsume;
02030
02031
if (!unresolvedContext.isEmpty())
02032 {
02033 unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
02034 }
02035
02036
return tmpItem;
02037 }
02038
02039 QString KateHighlighting::hlKeyForAttrib(
int i )
const
02040
{
02041
int k = 0;
02042
QMap<int,QString>::const_iterator it = m_hlIndex.constEnd();
02043
while ( it != m_hlIndex.constBegin() )
02044 {
02045 --it;
02046 k = it.key();
02047
if ( i >= k )
02048
break;
02049 }
02050
return it.data();
02051 }
02052
02053
bool KateHighlighting::isInWord(
QChar c,
int attrib )
const
02054
{
02055
static const QString& sq =
KGlobal::staticQString(
" \"'");
02056
return m_additionalData[ hlKeyForAttrib( attrib ) ]->deliminator.find(c) < 0 && sq.find(c) < 0;
02057 }
02058
02059
bool KateHighlighting::canBreakAt(
QChar c,
int attrib )
const
02060
{
02061
static const QString& sq =
KGlobal::staticQString(
"\"'");
02062
return (m_additionalData[ hlKeyForAttrib( attrib ) ]->wordWrapDeliminator.find(c) != -1) && (sq.find(c) == -1);
02063 }
02064
02065
signed char KateHighlighting::commentRegion(
int attr)
const {
02066 QString commentRegion=m_additionalData[ hlKeyForAttrib( attr ) ]->multiLineRegion;
02067
return (commentRegion.isEmpty()?0:(commentRegion.toShort()));
02068 }
02069
02070
bool KateHighlighting::canComment(
int startAttrib,
int endAttrib )
const
02071
{
02072 QString k = hlKeyForAttrib( startAttrib );
02073
return ( k == hlKeyForAttrib( endAttrib ) &&
02074 ( ( !m_additionalData[k]->multiLineCommentStart.isEmpty() && !m_additionalData[k]->multiLineCommentEnd.isEmpty() ) ||
02075 ! m_additionalData[k]->singleLineCommentMarker.isEmpty() ) );
02076 }
02077
02078 QString KateHighlighting::getCommentStart(
int attrib )
const
02079
{
02080
return m_additionalData[ hlKeyForAttrib( attrib) ]->multiLineCommentStart;
02081 }
02082
02083 QString KateHighlighting::getCommentEnd(
int attrib )
const
02084
{
02085
return m_additionalData[ hlKeyForAttrib( attrib ) ]->multiLineCommentEnd;
02086 }
02087
02088 QString KateHighlighting::getCommentSingleLineStart(
int attrib )
const
02089
{
02090
return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentMarker;
02091 }
02092
02097
void KateHighlighting::readCommentConfig()
02098 {
02099 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02100
KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo(
"general",
"comment");
02101
02102 QString cmlStart, cmlEnd, cmlRegion, cslStart ;
02103
02104
if (data)
02105 {
02106
while (KateHlManager::self()->syntax->nextGroup(data))
02107 {
02108
if (KateHlManager::self()->syntax->groupData(data,
"name")==
"singleLine")
02109 cslStart=KateHlManager::self()->syntax->groupData(data,
"start");
02110
02111
if (KateHlManager::self()->syntax->groupData(data,
"name")==
"multiLine")
02112 {
02113 cmlStart=KateHlManager::self()->syntax->groupData(data,
"start");
02114 cmlEnd=KateHlManager::self()->syntax->groupData(data,
"end");
02115 cmlRegion=KateHlManager::self()->syntax->groupData(data,
"region");
02116 }
02117 }
02118
02119 KateHlManager::self()->syntax->freeGroupInfo(data);
02120 }
02121
else
02122 {
02123 cslStart =
"";
02124 cmlStart =
"";
02125 cmlEnd =
"";
02126 cmlRegion =
"";
02127 }
02128 m_additionalData[buildIdentifier]->singleLineCommentMarker = cslStart;
02129 m_additionalData[buildIdentifier]->multiLineCommentStart = cmlStart;
02130 m_additionalData[buildIdentifier]->multiLineCommentEnd = cmlEnd;
02131 m_additionalData[buildIdentifier]->multiLineRegion = cmlRegion;
02132 }
02133
02139
void KateHighlighting::readGlobalKeywordConfig()
02140 {
02141 deliminator = stdDeliminator;
02142
02143
kdDebug(13010)<<
"readGlobalKeywordConfig:BEGIN"<<
endl;
02144
02145 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02146
KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig(
"general",
"keywords");
02147
02148
if (data)
02149 {
02150
kdDebug(13010)<<
"Found global keyword config"<<
endl;
02151
02152
if (KateHlManager::self()->syntax->groupItemData(data,QString(
"casesensitive"))!=
"0")
02153 casesensitive=
true;
02154
else
02155 casesensitive=
false;
02156
02157
02158 weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,QString(
"weakDeliminator")));
02159
02160
kdDebug(13010)<<
"weak delimiters are: "<<weakDeliminator<<
endl;
02161
02162
02163
for (uint s=0; s < weakDeliminator.length(); s++)
02164 {
02165
int f = deliminator.find (weakDeliminator[s]);
02166
02167
if (f > -1)
02168 deliminator.remove (f, 1);
02169 }
02170
02171 QString addDelim = (KateHlManager::self()->syntax->groupItemData(data,QString(
"additionalDeliminator")));
02172
02173
if (!addDelim.isEmpty())
02174 deliminator=deliminator+addDelim;
02175
02176 KateHlManager::self()->syntax->freeGroupInfo(data);
02177 }
02178
else
02179 {
02180
02181 casesensitive=
true;
02182 weakDeliminator=QString(
"");
02183 }
02184
02185
kdDebug(13010)<<
"readGlobalKeywordConfig:END"<<
endl;
02186
02187
kdDebug(13010)<<
"delimiterCharacters are: "<<deliminator<<
endl;
02188
02189 m_additionalData[buildIdentifier]->deliminator = deliminator;
02190 }
02191
02202
void KateHighlighting::readWordWrapConfig()
02203 {
02204
02205
kdDebug(13010)<<
"readWordWrapConfig:BEGIN"<<
endl;
02206
02207 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02208
KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig(
"general",
"keywords");
02209
02210 QString wordWrapDeliminator = stdDeliminator;
02211
if (data)
02212 {
02213
kdDebug(13010)<<
"Found global keyword config"<<
endl;
02214
02215 wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,QString(
"wordWrapDeliminator")));
02216
02217
if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
02218
02219
kdDebug(13010) <<
"word wrap deliminators are " << wordWrapDeliminator <<
endl;
02220
02221 KateHlManager::self()->syntax->freeGroupInfo(data);
02222 }
02223
02224
kdDebug(13010)<<
"readWordWrapConfig:END"<<
endl;
02225
02226 m_additionalData[buildIdentifier]->wordWrapDeliminator = wordWrapDeliminator;
02227 }
02228
02229
void KateHighlighting::readIndentationConfig()
02230 {
02231 m_indentation =
"";
02232
02233 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02234
KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig(
"general",
"indentation");
02235
02236
if (data)
02237 {
02238 m_indentation = (KateHlManager::self()->syntax->groupItemData(data,QString(
"mode")));
02239
02240 KateHlManager::self()->syntax->freeGroupInfo(data);
02241 }
02242 }
02243
02244
void KateHighlighting::readFoldingConfig()
02245 {
02246
02247
kdDebug(13010)<<
"readfoldignConfig:BEGIN"<<
endl;
02248
02249 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02250
KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig(
"general",
"folding");
02251
02252
if (data)
02253 {
02254
kdDebug(13010)<<
"Found global keyword config"<<
endl;
02255
02256
if (KateHlManager::self()->syntax->groupItemData(data,QString(
"indentationsensitive"))!=
"1")
02257 m_foldingIndentationSensitive=
false;
02258
else
02259 m_foldingIndentationSensitive=
true;
02260
02261 KateHlManager::self()->syntax->freeGroupInfo(data);
02262 }
02263
else
02264 {
02265
02266 m_foldingIndentationSensitive =
false;
02267 }
02268
02269
kdDebug(13010)<<
"readfoldingConfig:END"<<
endl;
02270
02271
kdDebug(13010)<<
"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<
endl;
02272 }
02273
02274
void KateHighlighting::createContextNameList(
QStringList *ContextNameList,
int ctx0)
02275 {
02276
kdDebug(13010)<<
"creatingContextNameList:BEGIN"<<
endl;
02277
02278
if (ctx0 == 0)
02279 ContextNameList->clear();
02280
02281 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02282
02283
KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
02284
02285
int id=ctx0;
02286
02287
if (data)
02288 {
02289
while (KateHlManager::self()->syntax->nextGroup(data))
02290 {
02291 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString(
"name")).simplifyWhiteSpace();
02292
if (tmpAttr.isEmpty())
02293 {
02294 tmpAttr=QString(
"!KATE_INTERNAL_DUMMY! %1").arg(
id);
02295 errorsAndWarnings +=i18n(
"<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(
id-ctx0);
02296 }
02297
else tmpAttr=buildPrefix+tmpAttr;
02298 (*ContextNameList)<<tmpAttr;
02299
id++;
02300 }
02301 KateHlManager::self()->syntax->freeGroupInfo(data);
02302 }
02303
kdDebug(13010)<<
"creatingContextNameList:END"<<
endl;
02304
02305 }
02306
02307
int KateHighlighting::getIdFromString(
QStringList *ContextNameList, QString tmpLineEndContext, QString &unres)
02308 {
02309 unres=
"";
02310
int context;
02311
if ((tmpLineEndContext==
"#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
02312 context=-1;
02313
02314
else if (tmpLineEndContext.startsWith(
"#pop"))
02315 {
02316 context=-1;
02317
for(;tmpLineEndContext.startsWith(
"#pop");context--)
02318 {
02319 tmpLineEndContext.remove(0,4);
02320
kdDebug(13010)<<
"#pop found"<<
endl;
02321 }
02322 }
02323
02324
else if ( tmpLineEndContext.startsWith(
"##"))
02325 {
02326 QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
02327
if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,KateEmbeddedHlInfo());
02328 unres=tmp;
02329 context=0;
02330 }
02331
02332
else
02333 {
02334 context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
02335
if (context==-1)
02336 {
02337 context=tmpLineEndContext.toInt();
02338 errorsAndWarnings+=i18n(
02339
"<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
02340 ).arg(buildIdentifier).arg(tmpLineEndContext);
02341 }
02342
02343
02344 }
02345
return context;
02346 }
02347
02353
void KateHighlighting::makeContextList()
02354 {
02355
if (noHl)
02356
return;
02357
02358 embeddedHls.clear();
02359 unresolvedContextReferences.clear();
02360 RegionList.clear();
02361 ContextNameList.clear();
02362
02363
02364
02365 embeddedHls.insert(iName,KateEmbeddedHlInfo());
02366
02367
bool something_changed;
02368
02369 startctx=base_startctx=0;
02370
02371 building=
true;
02372
02373
do
02374 {
02375
kdDebug(13010)<<
"**************** Outter loop in make ContextList"<<
endl;
02376
kdDebug(13010)<<
"**************** Hl List count:"<<embeddedHls.count()<<
endl;
02377 something_changed=
false;
02378
for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
02379 {
02380
if (!it.data().loaded)
02381 {
02382
kdDebug(13010)<<
"**************** Inner loop in make ContextList"<<
endl;
02383 QString identifierToUse;
02384
kdDebug(13010)<<
"Trying to open highlighting definition file: "<< it.key()<<
endl;
02385
if (iName==it.key())
02386 identifierToUse=identifier;
02387
else
02388 identifierToUse=KateHlManager::self()->identifierForName(it.key());
02389
02390
kdDebug(13010)<<
"Location is:"<< identifierToUse<<
endl;
02391
02392 buildPrefix=it.key()+
':';
02393
02394
02395
if (identifierToUse.isEmpty() )
02396
kdDebug(13010)<<
"OHOH, unknown highlighting description referenced"<<
endl;
02397
02398
kdDebug(13010)<<
"setting ("<<it.key()<<
") to loaded"<<
endl;
02399
02400
02401 it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(
true,startctx));
02402
02403 buildContext0Offset=startctx;
02404
02405 startctx=addToContextList(identifierToUse,startctx);
02406
02407
if (noHl)
return;
02408
02409 base_startctx = startctx;
02410 something_changed=
true;
02411 }
02412 }
02413 }
while (something_changed);
02414
02415
02416
02417
02418
02419
kdDebug(13010)<<
"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<
endl;
02420
02421
02422
for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
02423 unresIt!=unresolvedContextReferences.end();++unresIt)
02424 {
02425
02426 KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
02427
if (hlIt!=embeddedHls.end())
02428 *(unresIt.key())=hlIt.data().context0;
02429 }
02430
02431
02432
02433
02434
02435 handleKateHlIncludeRules();
02436
02437 embeddedHls.clear();
02438 unresolvedContextReferences.clear();
02439 RegionList.clear();
02440 ContextNameList.clear();
02441
02442
02443
02444
if (!errorsAndWarnings.isEmpty())
02445
KMessageBox::detailedSorry(0L,i18n(
02446
"There were warning(s) and/or error(s) while parsing the syntax "
02447
"highlighting configuration."),
02448 errorsAndWarnings, i18n(
"Kate Syntax Highlighting Parser"));
02449
02450
02451 building=
false;
02452 }
02453
02454
void KateHighlighting::handleKateHlIncludeRules()
02455 {
02456
02457
kdDebug(13010)<<
"KateHlIncludeRules, which need attention: " <<includeRules.count()<<
endl;
02458
if (includeRules.isEmpty())
return;
02459
02460 buildPrefix=
"";
02461 QString dummy;
02462
02463
02464
02465
02466
02467
02468
02469
for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
02470 {
02471
if ((*it)->incCtx==-1)
02472 {
02473
02474
if ((*it)->incCtxN.isEmpty())
02475 {
02476
02477
02478 KateHlIncludeRules::iterator it1=it;
02479 ++it1;
02480
delete (*it);
02481 includeRules.remove(it);
02482 it=it1;
02483 }
02484
else
02485 {
02486
02487 (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
02488
kdDebug(13010)<<
"Resolved "<<(*it)->incCtxN<<
" to "<<(*it)->incCtx<<
" for include rule"<<
endl;
02489
02490 }
02491 }
02492
else ++it;
02493 }
02494
02495
02496
02497
02498
02499
02500
02501
while (!includeRules.isEmpty())
02502 handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
02503 }
02504
02505
void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it,
KateHlIncludeRules *list)
02506 {
02507
if (it==list->end())
return;
02508
02509 KateHlIncludeRules::iterator it1=it;
02510
int ctx=(*it1)->ctx;
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
while ((it!=list->end()) && ((*it)->ctx==ctx))
02521 {
02522 it1=it;
02523 ++it;
02524 }
02525
02526
02527
while ((it1!=list->end()) && ((*it1)->ctx==ctx))
02528 {
02529
int ctx1=(*it1)->incCtx;
02530
02531
02532
for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
02533 {
02534
if ((*it2)->ctx==ctx1)
02535 {
02536
02537
02538 handleKateHlIncludeRulesRecursive(it2,list);
02539
break;
02540 }
02541 }
02542
02543
02544 KateHlContext *dest=m_contexts[ctx];
02545 KateHlContext *src=m_contexts[ctx1];
02546
02547
02548
02549
02550
02551
if ( (*it1)->includeAttrib )
02552 dest->attr = src->attr;
02553
02554
02555
int p=(*it1)->pos;
02556
02557
02558
int oldLen = dest->items.size();
02559 uint itemsToInsert = src->items.size();
02560
02561
02562 dest->items.resize (oldLen + itemsToInsert);
02563
02564
02565
for (
int i=oldLen-1; i >= p; --i)
02566 dest->items[i+itemsToInsert] = dest->items[i];
02567
02568
02569
for (uint i=0; i < itemsToInsert; ++i )
02570 dest->items[p+i] = src->items[i];
02571
02572 it=it1;
02573 --it1;
02574
delete (*it);
02575 list->remove(it);
02576 }
02577 }
02578
02584
int KateHighlighting::addToContextList(
const QString &ident,
int ctx0)
02585 {
02586
kdDebug(13010)<<
"=== Adding hl with ident '"<<ident<<
"'"<<
endl;
02587
02588 buildIdentifier=ident;
02589
KateSyntaxContextData *data, *datasub;
02590 KateHlItem *c;
02591
02592 QString dummy;
02593
02594
02595
if (!KateHlManager::self()->syntax->setIdentifier(ident))
02596 {
02597 noHl=
true;
02598
KMessageBox::information(0L,i18n(
02599
"Since there has been an error parsing the highlighting description, "
02600
"this highlighting will be disabled"));
02601
return 0;
02602 }
02603
02604
02605
if (identifier == ident)
02606 {
02607 readIndentationConfig ();
02608 }
02609
02610 RegionList<<
"!KateInternal_TopLevel!";
02611
02612 m_hlIndex[internalIDList.count()] = ident;
02613 m_additionalData.insert( ident,
new HighlightPropertyBag );
02614
02615
02616 readCommentConfig();
02617 readGlobalKeywordConfig();
02618 readWordWrapConfig();
02619
02620 readFoldingConfig ();
02621
02622 QString ctxName;
02623
02624
02625
02626 addToKateHlItemDataList();
02627
KateHlItemDataList iDl = internalIDList;
02628
02629 createContextNameList(&ContextNameList,ctx0);
02630
02631
02632
kdDebug(13010)<<
"Parsing Context structure"<<
endl;
02633
02634 data=KateHlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
02635 uint i=buildContext0Offset;
02636
if (data)
02637 {
02638
while (KateHlManager::self()->syntax->nextGroup(data))
02639 {
02640
kdDebug(13010)<<
"Found a context in file, building structure now"<<
endl;
02641
02642 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString(
"attribute")).simplifyWhiteSpace();
02643
int attr;
02644
if (QString(
"%1").arg(tmpAttr.toInt())==tmpAttr)
02645 attr=tmpAttr.toInt();
02646
else
02647 attr=lookupAttrName(tmpAttr,iDl);
02648
02649
02650 ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,QString(
"lineEndContext")).simplifyWhiteSpace();
02651
02652 QString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,QString(
"lineEndContext")).simplifyWhiteSpace();
02653
int context;
02654
02655 context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
02656
02657
02658
bool ft =
false;
02659
int ftc = 0;
02660
if ( i > 0 )
02661 {
02662 QString tmpFt = KateHlManager::self()->syntax->groupData(data, QString(
"fallthrough") );
02663
if ( IS_TRUE(tmpFt) )
02664 ft =
true;
02665
if ( ft )
02666 {
02667 QString tmpFtc = KateHlManager::self()->syntax->groupData( data, QString(
"fallthroughContext") );
02668
02669 ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
02670
if (ftc == -1) ftc =0;
02671
02672
kdDebug(13010)<<
"Setting fall through context (context "<<i<<
"): "<<ftc<<
endl;
02673 }
02674 }
02675
02676
02677
bool dynamic =
false;
02678 QString tmpDynamic = KateHlManager::self()->syntax->groupData(data, QString(
"dynamic") );
02679
if ( tmpDynamic.lower() ==
"true" || tmpDynamic.toInt() == 1 )
02680 dynamic =
true;
02681
02682 KateHlContext *ctxNew =
new KateHlContext (
02683 ident,
02684 attr,
02685 context,
02686 (KateHlManager::self()->syntax->groupData(data,QString(
"lineBeginContext"))).isEmpty()?-1:
02687 (KateHlManager::self()->syntax->groupData(data,QString(
"lineBeginContext"))).toInt(),
02688 ft, ftc, dynamic);
02689
02690 m_contexts.push_back (ctxNew);
02691
02692
kdDebug(13010) <<
"INDEX: " << i <<
" LENGTH " << m_contexts.size()-1 <<
endl;
02693
02694
02695
while (KateHlManager::self()->syntax->nextItem(data))
02696 {
02697
02698
02699
02700
02701 QString tag = KateHlManager::self()->syntax->groupItemData(data,QString(
""));
02702
if ( tag ==
"IncludeRules" )
02703 {
02704 QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString(
"context"));
02705 QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString(
"includeAttrib"));
02706
bool includeAttrib = ( incAttrib.lower() ==
"true" || incAttrib.toInt() == 1 );
02707
02708
if (incCtx.startsWith(
"##") || (!incCtx.startsWith(
"#")))
02709 {
02710
02711
if (!incCtx.startsWith(
"#"))
02712 {
02713
02714 incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
02715 includeRules.append(
new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
02716 }
02717
else
02718 {
02719
02720
kdDebug(13010)<<
"Cross highlight reference <IncludeRules>"<<
endl;
02721 KateHlIncludeRule *ir=
new KateHlIncludeRule(i,m_contexts[i]->items.count(),
"",includeAttrib);
02722
02723
02724
if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
02725 embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
02726
02727 unresolvedContextReferences.insert(&(ir->incCtx),
02728 incCtx.right(incCtx.length()-2));
02729
02730 includeRules.append(ir);
02731 }
02732 }
02733
02734
continue;
02735 }
02736
02737
#if 0
02738
QString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,QString(
""));
02739
if ( tag ==
"IncludeRules" ) {
02740
02741
02742
02743
int ctxId = getIdFromString(&ContextNameList,
02744 KateHlManager::self()->syntax->groupKateHlItemData( data, QString(
"context")),dummy);
02745
if ( ctxId > -1) {
02746
kdDebug(13010)<<
"makeContextList["<<i<<
"]: including all items of context "<<ctxId<<
endl;
02747
if ( ctxId < (
int) i ) {
02748
for ( c = m_contexts[ctxId]->items.first(); c; c = m_contexts[ctxId]->items.next() )
02749 m_contexts[i]->items.append(c);
02750 }
02751
else
02752
kdDebug(13010)<<
"Context "<<ctxId<<
"not defined. You can not include the rules of an undefined context"<<
endl;
02753 }
02754
continue;
02755 }
02756
#endif
02757
c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
02758
if (c)
02759 {
02760 m_contexts[i]->items.append(c);
02761
02762
02763
02764 datasub=KateHlManager::self()->syntax->getSubItems(data);
02765
bool tmpbool;
02766
if (tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02767 {
02768
for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02769 {
02770 c->subItems.resize (c->subItems.size()+1);
02771 c->subItems[c->subItems.size()-1] = createKateHlItem(datasub,iDl,&RegionList,&ContextNameList);
02772 } }
02773 KateHlManager::self()->syntax->freeGroupInfo(datasub);
02774
02775 }
02776 }
02777 i++;
02778 }
02779 }
02780
02781 KateHlManager::self()->syntax->freeGroupInfo(data);
02782
02783
if (RegionList.count()!=1)
02784 folding=
true;
02785
02786 folding = folding || m_foldingIndentationSensitive;
02787
02788
02789
if (!m_additionalData[ ident ]->multiLineRegion.isEmpty()) {
02790
long commentregionid=RegionList.findIndex( m_additionalData[ ident ]->multiLineRegion );
02791
if (-1==commentregionid) {
02792 errorsAndWarnings+=i18n(
02793
"<B>%1</B>: Specified multiline comment region (%2) could not be resolved<BR>"
02794 ).arg(buildIdentifier).arg( m_additionalData[ ident ]->multiLineRegion );
02795 m_additionalData[ ident ]->multiLineRegion = QString();
02796
kdDebug(13010)<<
"ERROR comment region attribute could not be resolved"<<
endl;
02797
02798 }
else {
02799 m_additionalData[ ident ]->multiLineRegion=QString::number(commentregionid+1);
02800
kdDebug(13010)<<
"comment region resolved to:"<<m_additionalData[ ident ]->multiLineRegion<<
endl;
02801 }
02802 }
02803
02804
return i;
02805 }
02806
02807
void KateHighlighting::clearAttributeArrays ()
02808 {
02809
for (
QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
02810 {
02811
02812
KateAttributeList defaultStyleList;
02813 defaultStyleList.setAutoDelete(
true);
02814 KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
02815
02816
KateHlItemDataList itemDataList;
02817 getKateHlItemDataList(it.currentKey(), itemDataList);
02818
02819 uint nAttribs = itemDataList.count();
02820
QMemArray<KateAttribute> *array = it.current();
02821 array->resize (nAttribs);
02822
02823
for (uint z = 0; z < nAttribs; z++)
02824 {
02825 KateHlItemData *itemData = itemDataList.at(z);
02826
KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02827
02828
if (itemData && itemData->isSomethingSet())
02829 n += *itemData;
02830
02831 array->at(z) = n;
02832 }
02833 }
02834 }
02835
02836
QMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
02837 {
02838
QMemArray<KateAttribute> *array;
02839
02840
02841
if ((array = m_attributeArrays[schema]))
02842
return array;
02843
02844
02845
if (!KateFactory::self()->schemaManager()->validSchema(schema))
02846 {
02847
02848
return attributes (0);
02849 }
02850
02851
02852
KateAttributeList defaultStyleList;
02853 defaultStyleList.setAutoDelete(
true);
02854 KateHlManager::self()->getDefaults(schema, defaultStyleList);
02855
02856
KateHlItemDataList itemDataList;
02857 getKateHlItemDataList(schema, itemDataList);
02858
02859 uint nAttribs = itemDataList.count();
02860 array =
new QMemArray<KateAttribute> (nAttribs);
02861
02862
for (uint z = 0; z < nAttribs; z++)
02863 {
02864 KateHlItemData *itemData = itemDataList.at(z);
02865
KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02866
02867
if (itemData && itemData->isSomethingSet())
02868 n += *itemData;
02869
02870 array->at(z) = n;
02871 }
02872
02873 m_attributeArrays.insert(schema, array);
02874
02875
return array;
02876 }
02877
02878
void KateHighlighting::getKateHlItemDataListCopy (uint schema,
KateHlItemDataList &outlist)
02879 {
02880
KateHlItemDataList itemDataList;
02881 getKateHlItemDataList(schema, itemDataList);
02882
02883 outlist.clear ();
02884 outlist.setAutoDelete (
true);
02885
for (uint z=0; z < itemDataList.count(); z++)
02886 outlist.append (
new KateHlItemData (*itemDataList.at(z)));
02887 }
02888
02889
02890
02891
02892 KateHlManager::KateHlManager()
02893 :
QObject()
02894 , m_config ("katesyntaxhighlightingrc", false, false)
02895 , commonSuffixes (
QStringList::split(";
", ".orig;.new;~;.bak;.BAK
"))
02896
, syntax (new KateSyntaxDocument())
02897
, dynamicCtxsCount(0)
02898
, forceNoDCReset(false)
02899
{
02900
hlList.setAutoDelete(true);
02901
hlDict.setAutoDelete(false);
02902
02903
KateSyntaxModeList modeList = syntax->modeList();
02904
for (uint i=0; i < modeList.count(); i++)
02905
{
02906
KateHighlighting *hl = new KateHighlighting(modeList[i]);
02907
02908
uint insert = 0;
02909
for (; insert <= hlList.count(); insert++)
02910
{
02911
if (insert == hlList.count())
02912
break;
02913
02914
if ( QString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
02915
> QString(hl->section() + hl->nameTranslated()).lower() )
02916
break;
02917
}
02918
02919
hlList.insert (insert, hl);
02920
hlDict.insert (hl->name(), hl);
02921
}
02922
02923
// Normal HL
02924
KateHighlighting *hl = new KateHighlighting(0);
02925
hlList.prepend (hl);
02926
hlDict.insert (hl->name(), hl);
02927
02928
lastCtxsReset.start();
02929
}
02930
02931
KateHlManager::~KateHlManager()
02932
{
02933
delete syntax;
02934
}
02935
02936
static KStaticDeleter<KateHlManager> sdHlMan;
02937
02938
KateHlManager *KateHlManager::self()
02939
{
02940
if ( !s_self )
02941
sdHlMan.setObject(s_self, new KateHlManager ());
02942
02943
return s_self;
02944
}
02945
02946
KateHighlighting *KateHlManager::getHl(int n)
02947
{
02948
if (n < 0 || n >= (int) hlList.count())
02949
n = 0;
02950
02951
return hlList.at(n);
02952
}
02953
02954
int KateHlManager::nameFind(const QString &name)
02955
{
02956
int z (hlList.count() - 1);
02957
for (; z > 0; z--)
02958
if (hlList.at(z)->name() == name)
02959
return z;
02960
02961
return z;
02962
}
02963
02964
int KateHlManager::detectHighlighting (KateDocument *doc)
02965
{
02966
int hl = wildcardFind( doc->url().filename() );
02967
if ( hl < 0 )
02968
hl = mimeFind ( doc );
02969
02970
return hl;
02971
}
02972
02973
int KateHlManager::wildcardFind(const QString &fileName)
02974
{
02975
int result = -1;
02976
if ((result = realWildcardFind(fileName)) != -1)
02977
return result;
02978
02979
int length = fileName.length();
02980
QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
02981
if (fileName.endsWith(backupSuffix)) {
02982
if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
02983
return result;
02984
}
02985
02986
for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
02987
if (*it != backupSuffix && fileName.endsWith(*it)) {
02988
if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
02989
return result;
02990
}
02991
}
02992
02993
return -1;
02994
}
02995
02996
int KateHlManager::realWildcardFind(const QString &fileName)
02997
{
02998
static QRegExp sep("\\s*;\\s*
");
02999
03000
QPtrList<KateHighlighting> highlights;
03001
03002
for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
03003
highlight->loadWildcards();
03004
03005
for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
03006
if (fileName.endsWith((*it)))
03007
highlights.append(highlight);
03008
03009
for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
03010
QRegExp re = highlight->getRegexpExtensions()[i];
03011
if (re.exactMatch(fileName))
03012
highlights.append(highlight);
03013
}
03014
}
03015
03016
if ( !highlights.isEmpty() )
03017
{
03018
int pri = -1;
03019
int hl = -1;
03020
03021
for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
03022
{
03023
if (highlight->priority() > pri)
03024
{
03025
pri = highlight->priority();
03026
hl = hlList.findRef (highlight);
03027
}
03028
}
03029
return hl;
03030
}
03031
03032
return -1;
03033
}
03034
03035
int KateHlManager::mimeFind( KateDocument *doc )
03036
{
03037
static QRegExp sep("\\s*;\\s*
");
03038
03039
KMimeType::Ptr mt = doc->mimeTypeForContent();
03040
03041
QPtrList<KateHighlighting> highlights;
03042
03043
for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
03044
{
03045
QStringList l = QStringList::split( sep, highlight->getMimetypes() );
03046
03047
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
03048
{
03049
if ( *it == mt->name() ) // faster than a regexp i guess?
03050
highlights.append (highlight);
03051
}
03052
}
03053
03054
if ( !highlights.isEmpty() )
03055
{
03056
int pri = -1;
03057
int hl = -1;
03058
03059
for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
03060
{
03061
if (highlight->priority() > pri)
03062
{
03063
pri = highlight->priority();
03064
hl = hlList.findRef (highlight);
03065
}
03066
}
03067
03068
return hl;
03069
}
03070
03071
return -1;
03072
}
03073
03074
uint KateHlManager::defaultStyles()
03075
{
03076
return 14;
03077
}
03078
03079
QString KateHlManager::defaultStyleName(int n, bool translateNames)
03080
{
03081
static QStringList names;
03082
static QStringList translatedNames;
03083
03084
if (names.isEmpty())
03085
{
03086
names << "Normal
";
03087
names << "Keyword
";
03088
names << "Data Type
";
03089
names << "Decimal/Value
";
03090
names << "Base-N Integer
";
03091
names << "Floating Point
";
03092
names << "Character
";
03093
names << "String
";
03094
names << "Comment
";
03095
names << "Others
";
03096
names << "Alert
";
03097
names << "Function
";
03098
// this next one is for denoting the beginning/end of a user defined folding region
03099
names << "Region Marker
";
03100
// this one is for marking invalid input
03101
names << "Error";
03102
03103
translatedNames << i18n("Normal
");
03104
translatedNames << i18n("Keyword
");
03105
translatedNames << i18n("Data Type
");
03106
translatedNames << i18n("Decimal/Value
");
03107
translatedNames << i18n("Base-N Integer
");
03108
translatedNames << i18n("Floating Point
");
03109
translatedNames << i18n("Character
");
03110
translatedNames << i18n("String
");
03111
translatedNames << i18n("Comment
");
03112
translatedNames << i18n("Others
");
03113
translatedNames << i18n("Alert
");
03114
translatedNames << i18n("Function
");
03115
// this next one is for denoting the beginning/end of a user defined folding region
03116
translatedNames << i18n("Region Marker
");
03117
// this one is for marking invalid input
03118
translatedNames << i18n("Error");
03119
}
03120
03121
return translateNames ? translatedNames[n] : names[n];
03122
}
03123
03124
void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
03125
{
03126
list.setAutoDelete(true);
03127
03128
KateAttribute* normal = new KateAttribute();
03129
normal->setTextColor(Qt::black);
03130
normal->setSelectedTextColor(Qt::white);
03131
list.append(normal);
03132
03133
KateAttribute* keyword = new KateAttribute();
03134
keyword->setTextColor(Qt::black);
03135
keyword->setSelectedTextColor(Qt::white);
03136
keyword->setBold(true);
03137
list.append(keyword);
03138
03139
KateAttribute* dataType = new KateAttribute();
03140
dataType->setTextColor(Qt::darkRed);
03141
dataType->setSelectedTextColor(Qt::white);
03142
list.append(dataType);
03143
03144
KateAttribute* decimal = new KateAttribute();
03145
decimal->setTextColor(Qt::blue);
03146
decimal->setSelectedTextColor(Qt::cyan);
03147
list.append(decimal);
03148
03149
KateAttribute* basen = new KateAttribute();
03150
basen->setTextColor(Qt::darkCyan);
03151
basen->setSelectedTextColor(Qt::cyan);
03152
list.append(basen);
03153
03154
KateAttribute* floatAttribute = new KateAttribute();
03155
floatAttribute->setTextColor(Qt::darkMagenta);
03156
floatAttribute->setSelectedTextColor(Qt::cyan);
03157
list.append(floatAttribute);
03158
03159
KateAttribute* charAttribute = new KateAttribute();
03160
charAttribute->setTextColor(Qt::magenta);
03161
charAttribute->setSelectedTextColor(Qt::magenta);
03162
list.append(charAttribute);
03163
03164
KateAttribute* string = new KateAttribute();
03165
string->setTextColor(QColor::QColor("#D00
"));
03166
string->setSelectedTextColor(Qt::red);
03167
list.append(string);
03168
03169
KateAttribute* comment = new KateAttribute();
03170
comment->setTextColor(Qt::darkGray);
03171
comment->setSelectedTextColor(Qt::gray);
03172
comment->setItalic(true);
03173
list.append(comment);
03174
03175
KateAttribute* others = new KateAttribute();
03176
others->setTextColor(Qt::darkGreen);
03177
others->setSelectedTextColor(Qt::green);
03178
list.append(others);
03179
03180
KateAttribute* alert = new KateAttribute();
03181
alert->setTextColor(Qt::white);
03182
alert->setSelectedTextColor( QColor::QColor("#FCC
") );
03183
alert->setBold(true);
03184
alert->setBGColor( QColor::QColor("#FCC
") );
03185
list.append(alert);
03186
03187
KateAttribute* functionAttribute = new KateAttribute();
03188
functionAttribute->setTextColor(Qt::darkBlue);
03189
functionAttribute->setSelectedTextColor(Qt::white);
03190
list.append(functionAttribute);
03191
03192
KateAttribute* regionmarker = new KateAttribute();
03193
regionmarker->setTextColor(Qt::white);
03194
regionmarker->setBGColor(Qt::gray);
03195
regionmarker->setSelectedTextColor(Qt::gray);
03196
list.append(regionmarker);
03197
03198
KateAttribute* error = new KateAttribute();
03199
error->setTextColor(Qt::red);
03200
error->setUnderline(true);
03201
error->setSelectedTextColor(Qt::red);
03202
list.append(error);
03203
03204
KConfig *config = KateHlManager::self()->self()->getKConfig();
03205
config->setGroup("Default Item Styles - Schema
" + KateFactory::self()->schemaManager()->name(schema));
03206
03207
for (uint z = 0; z < defaultStyles(); z++)
03208
{
03209
KateAttribute *i = list.at(z);
03210
QStringList s = config->readListEntry(defaultStyleName(z));
03211
if (!s.isEmpty())
03212
{
03213
while( s.count()<8)
03214
s << "";
03215
03216
QString tmp;
03217
QRgb col;
03218
03219
tmp=s[0]; if (!tmp.isEmpty()) {
03220
col=tmp.toUInt(0,16); i->setTextColor(col); }
03221
03222
tmp=s[1]; if (!tmp.isEmpty()) {
03223
col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
03224
03225
tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0
");
03226
03227
tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0
");
03228
03229
tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0
");
03230
03231
tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0
");
03232
03233
tmp=s[6]; if (!tmp.isEmpty()) {
03234
if ( tmp != "-
" )
03235
{
03236
col=tmp.toUInt(0,16);
03237
i->setBGColor(col);
03238
}
03239
else
03240
i->clearAttribute(KateAttribute::BGColor);
03241
}
03242
tmp=s[7]; if (!tmp.isEmpty()) {
03243
if ( tmp != "-
" )
03244
{
03245
col=tmp.toUInt(0,16);
03246
i->setSelectedBGColor(col);
03247
}
03248
else
03249
i->clearAttribute(KateAttribute::SelectedBGColor);
03250
}
03251
}
03252
}
03253
}
03254
03255
void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
03256
{
03257
KConfig *config = KateHlManager::self()->self()->getKConfig();
03258
config->setGroup("Default Item Styles - Schema
" + KateFactory::self()->schemaManager()->name(schema));
03259
03260
for (uint z = 0; z < defaultStyles(); z++)
03261
{
03262
QStringList settings;
03263
KateAttribute *i = list.at(z);
03264
03265
settings<<(i->itemSet(KateAttribute::TextColor)?QString::number(i->textColor().rgb(),16):"");
03266
settings<<(i->itemSet(KateAttribute::SelectedTextColor)?QString::number(i->selectedTextColor().rgb(),16):"");
03267
settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1
":"0
"):"");
03268
settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1
":"0
"):"");
03269
settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1
":"0
"):"");
03270
settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1
":"0
"):"");
03271
settings<<(i->itemSet(KateAttribute::BGColor)?QString::number(i->bgColor().rgb(),16):"-
");
03272
settings<<(i->itemSet(KateAttribute::SelectedBGColor)?QString::number(i->selectedBGColor().rgb(),16):"-
");
03273
settings<<"---
";
03274
03275
config->writeEntry(defaultStyleName(z),settings);
03276
}
03277
03278
emit changed();
03279
}
03280
03281
int KateHlManager::highlights()
03282
{
03283
return (int) hlList.count();
03284
}
03285
03286
QString KateHlManager::hlName(int n)
03287
{
03288
return hlList.at(n)->name();
03289
}
03290
03291
QString KateHlManager::hlNameTranslated(int n)
03292
{
03293
return hlList.at(n)->nameTranslated();
03294
}
03295
03296
QString KateHlManager::hlSection(int n)
03297
{
03298
return hlList.at(n)->section();
03299
}
03300
03301
bool KateHlManager::hlHidden(int n)
03302
{
03303
return hlList.at(n)->hidden();
03304
}
03305
03306
QString KateHlManager::identifierForName(const QString& name)
03307
{
03308
KateHighlighting *hl = 0;
03309
03310
if ((hl = hlDict[name]))
03311
return hl->getIdentifier ();
03312
03313
return QString();
03314
}
03315
03316
bool KateHlManager::resetDynamicCtxs()
03317
{
03318
if (forceNoDCReset)
03319
return false;
03320
03321
if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
03322
return false;
03323
03324
KateHighlighting *hl;
03325
for (hl = hlList.first(); hl; hl = hlList.next())
03326
hl->dropDynamicContexts();
03327
03328
dynamicCtxsCount = 0;
03329
lastCtxsReset.start();
03330
03331
return true;
03332
}
03333
//END
03334
03335
//BEGIN KateHighlightAction
03336
void KateViewHighlightAction::init()
03337
{
03338
m_doc = 0;
03339
subMenus.setAutoDelete( true );
03340
03341
connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
03342
}
03343
03344
void KateViewHighlightAction::updateMenu (Kate::Document *doc)
03345
{
03346
m_doc = doc;
03347
}
03348
03349
void KateViewHighlightAction::slotAboutToShow()
03350
{
03351
Kate::Document *doc=m_doc;
03352
int count = KateHlManager::self()->highlights();
03353
03354
for (int z=0; z<count; z++)
03355
{
03356
QString hlName = KateHlManager::self()->hlNameTranslated (z);
03357
QString hlSection = KateHlManager::self()->hlSection (z);
03358
03359
if (!KateHlManager::self()->hlHidden(z))
03360
{
03361
if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
03362
{
03363
if (subMenusName.contains(hlSection) < 1)
03364
{
03365
subMenusName << hlSection;
03366
QPopupMenu *menu = new QPopupMenu ();
03367
subMenus.append(menu);
03368
popupMenu()->insertItem ( '&' + hlSection, menu);
03369
}
03370
03371
int m = subMenusName.findIndex (hlSection);
03372
names << hlName;
03373
subMenus.at(m)->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0, z);
03374
}
03375
else if (names.contains(hlName) < 1)
03376
{
03377
names << hlName;
03378
popupMenu()->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0, z);
03379
}
03380
}
03381
}
03382
03383
if (!doc) return;
03384
03385
for (uint i=0;i<subMenus.count();i++)
03386
{
03387
for (uint i2=0;i2<subMenus.at(i)->count();i2++)
03388
{
03389
subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
03390
}
03391
}
03392
popupMenu()->setItemChecked (0, false);
03393
03394
int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
03395
if (i >= 0 && subMenus.at(i))
03396
subMenus.at(i)->setItemChecked (doc->hlMode(), true);
03397
else
03398
popupMenu()->setItemChecked (0, true);
03399
}
03400
03401
void KateViewHighlightAction::setHl (int mode)
03402
{
03403
Kate::Document *doc=m_doc;
03404
03405
if (doc)
03406
doc->setHlMode((uint)mode);
03407
}
03408
//END KateViewHighlightAction
03409
03410
// kate: space-indent on; indent-width 2; replace-tabs on;