00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "katehighlight.h"
00024
#include "katehighlight.moc"
00025
00026
#include "katetextline.h"
00027
#include "katedocument.h"
00028
#include "katesyntaxdocument.h"
00029
#include "katerenderer.h"
00030
#include "katefactory.h"
00031
#include "kateschema.h"
00032
#include "kateconfig.h"
00033
00034
#include <kconfig.h>
00035
#include <kglobal.h>
00036
#include <kinstance.h>
00037
#include <kmimetype.h>
00038
#include <klocale.h>
00039
#include <kregexp.h>
00040
#include <kpopupmenu.h>
00041
#include <kglobalsettings.h>
00042
#include <kdebug.h>
00043
#include <kstandarddirs.h>
00044
#include <kmessagebox.h>
00045
#include <kstaticdeleter.h>
00046
#include <kapplication.h>
00047
00048
#include <qstringlist.h>
00049
#include <qtextstream.h>
00050
00051
00052
00053
#define KATE_HL_HOWMANY 1024
00054
00055
00056
00057
class HlItem
00058 {
00059
public:
00060 HlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00061
virtual ~HlItem();
00062
00063
public:
00064
virtual bool alwaysStartEnable()
const {
return true; };
00065
virtual bool hasCustomStartEnable()
const {
return false; };
00066
virtual bool startEnable(
const QChar&);
00067
00068
00069
00070
00071
00072
virtual int checkHgl(
const QString& text,
int offset,
int len) = 0;
00073
00074
virtual bool lineContinue(){
return false;}
00075
00076
QPtrList<HlItem> *subItems;
00077
int attr;
00078
int ctx;
00079
signed char region;
00080
signed char region2;
00081 };
00082
00083
class HlContext
00084 {
00085
public:
00086 HlContext (
int attribute,
int lineEndContext,
int _lineBeginContext,
00087
bool _fallthrough,
int _fallthroughContext);
00088
00089
QPtrList<HlItem> items;
00090
int attr;
00091
int ctx;
00092
int lineBeginContext;
00098
bool fallthrough;
00099
int ftctx;
00100 };
00101
00102
class EmbeddedHlInfo
00103 {
00104
public:
00105 EmbeddedHlInfo() {loaded=
false;context0=-1;}
00106 EmbeddedHlInfo(
bool l,
int ctx0) {loaded=l;context0=ctx0;}
00107
00108
public:
00109
bool loaded;
00110
int context0;
00111 };
00112
00113
class IncludeRule
00114 {
00115
public:
00116 IncludeRule(
int ctx_, uint pos_,
const QString &incCtxN_) {ctx=ctx_;pos=pos_;incCtxN=incCtxN_;incCtx=-1;}
00117 IncludeRule(
int ctx_, uint pos_) {ctx=ctx_;pos=pos_;incCtx=-1;incCtxN=
"";}
00118
00119
public:
00120 uint pos;
00121
int ctx;
00122
int incCtx;
00123
QString incCtxN;
00124 };
00125
00126
class HlCharDetect :
public HlItem
00127 {
00128
public:
00129 HlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar);
00130
virtual int checkHgl(
const QString& text,
int offset,
int len);
00131
00132
private:
00133
QChar sChar;
00134 };
00135
00136
class Hl2CharDetect :
public HlItem
00137 {
00138
public:
00139 Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00140 Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *ch);
00141
00142
virtual int checkHgl(
const QString& text,
int offset,
int len);
00143
00144
private:
00145
QChar sChar1;
00146
QChar sChar2;
00147 };
00148
00149
class HlStringDetect :
public HlItem
00150 {
00151
public:
00152 HlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &,
bool inSensitive=
false);
00153
00154
virtual ~HlStringDetect();
00155
virtual int checkHgl(
const QString& text,
int offset,
int len);
00156
00157
private:
00158
const QString str;
00159
bool _inSensitive;
00160 };
00161
00162
class HlRangeDetect :
public HlItem
00163 {
00164
public:
00165 HlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00166
00167
virtual int checkHgl(
const QString& text,
int offset,
int len);
00168
00169
private:
00170
QChar sChar1;
00171
QChar sChar2;
00172 };
00173
00174
class HlKeyword :
public HlItem
00175 {
00176
public:
00177 HlKeyword(
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims);
00178
virtual ~HlKeyword();
00179
00180
virtual void addWord(
const QString &);
00181
virtual void addList(
const QStringList &);
00182
virtual int checkHgl(
const QString& text,
int offset,
int len);
00183
virtual bool startEnable(
const QChar& c);
00184
virtual bool alwaysStartEnable() const;
00185 virtual
bool hasCustomStartEnable() const;
00186
00187 private:
00188
QDict<
bool> dict;
00189
bool _caseSensitive;
00190 const
QString& deliminators;
00191 };
00192
00193 class HlInt : public HlItem
00194 {
00195
public:
00196 HlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00197
00198
virtual int checkHgl(
const QString& text,
int offset,
int len);
00199
virtual bool alwaysStartEnable() const;
00200 };
00201
00202 class HlFloat : public HlItem
00203 {
00204
public:
00205 HlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00206
00207
virtual int checkHgl(
const QString& text,
int offset,
int len);
00208
virtual bool alwaysStartEnable() const;
00209 };
00210
00211 class HlCOct : public HlItem
00212 {
00213
public:
00214 HlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00215
00216
virtual int checkHgl(
const QString& text,
int offset,
int len);
00217
virtual bool alwaysStartEnable() const;
00218 };
00219
00220 class HlCHex : public HlItem
00221 {
00222
public:
00223 HlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00224
00225
virtual int checkHgl(
const QString& text,
int offset,
int len);
00226
virtual bool alwaysStartEnable() const;
00227 };
00228
00229 class HlCFloat : public HlFloat
00230 {
00231
public:
00232 HlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00233
00234
virtual int checkHgl(
const QString& text,
int offset,
int len);
00235
int checkIntHgl(
const QString& text,
int offset,
int len);
00236
virtual bool alwaysStartEnable() const;
00237 };
00238
00239 class HlLineContinue : public HlItem
00240 {
00241
public:
00242 HlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00243
00244
virtual bool endEnable(
QChar c) {
return c ==
'\0';}
00245
virtual int checkHgl(
const QString& text,
int offset,
int len);
00246
virtual bool lineContinue(){
return true;}
00247 };
00248
00249
class HlCStringChar :
public HlItem
00250 {
00251
public:
00252 HlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00253
00254
virtual int checkHgl(
const QString& text,
int offset,
int len);
00255 };
00256
00257
class HlCChar :
public HlItem
00258 {
00259
public:
00260 HlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00261
00262
virtual int checkHgl(
const QString& text,
int offset,
int len);
00263 };
00264
00265
class HlAnyChar :
public HlItem
00266 {
00267
public:
00268 HlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList);
00269
00270
virtual int checkHgl(
const QString& text,
int offset,
int len);
00271
00272
private:
00273
const QString _charList;
00274 };
00275
00276
class HlRegExpr :
public HlItem
00277 {
00278
public:
00279 HlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2 ,
QString expr,
bool insensitive,
bool minimal);
00280 ~HlRegExpr(){
delete Expr;};
00281
00282
virtual int checkHgl(
const QString& text,
int offset,
int len);
00283
00284
private:
00285
QRegExp *Expr;
00286
bool handlesLinestart;
00287 };
00288
00289
00290
00291
00292 HlManager *HlManager::s_self = 0;
00293
00294
enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers};
00295
00296
static const bool trueBool =
true;
00297
static const QString stdDeliminator =
QString (
" \t.():!+,-<=>%&*/;?[]^{|}~\\");
00298
00299
00300
00301
static int getDefStyleNum(
QString name)
00302 {
00303
if (
name==
"dsNormal")
return dsNormal;
00304
else if (
name==
"dsKeyword")
return dsKeyword;
00305
else if (
name==
"dsDataType")
return dsDataType;
00306
else if (
name==
"dsDecVal")
return dsDecVal;
00307
else if (
name==
"dsBaseN")
return dsBaseN;
00308
else if (
name==
"dsFloat")
return dsFloat;
00309
else if (
name==
"dsChar")
return dsChar;
00310
else if (
name==
"dsString")
return dsString;
00311
else if (
name==
"dsComment")
return dsComment;
00312
else if (
name==
"dsOthers")
return dsOthers;
00313
00314
return dsNormal;
00315 }
00316
00317
00318
00319 HlItem::HlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00320 : attr(attribute), ctx(context),region(regionId),region2(regionId2) {subItems=0;
00321 }
00322
00323 HlItem::~HlItem()
00324 {
00325
00326
if (subItems!=0)
00327 {
00328 subItems->setAutoDelete(
true);
00329 subItems->clear();
00330
delete subItems;
00331 }
00332 }
00333
00334
bool HlItem::startEnable(
const QChar& c)
00335 {
00336
00337
00338 Q_ASSERT(
false);
00339
return stdDeliminator.
find(c) != -1;
00340 }
00341
00342
00343
00344 HlCharDetect::HlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar c)
00345 : HlItem(attribute,context,regionId,regionId2), sChar(c)
00346 {
00347 }
00348
00349
int HlCharDetect::checkHgl(
const QString& text,
int offset,
int len)
00350 {
00351
if (len && text[offset] == sChar)
00352
return offset + 1;
00353
00354
return 0;
00355 }
00356
00357
00358
00359 Hl2CharDetect::Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00360 : HlItem(attribute,context,regionId,regionId2)
00361 {
00362 sChar1 = ch1;
00363 sChar2 = ch2;
00364 }
00365
00366
int Hl2CharDetect::checkHgl(
const QString& text,
int offset,
int len)
00367 {
00368
if (len < 2)
00369
return offset;
00370
00371
if (text[offset++] == sChar1 && text[offset++] == sChar2)
00372
return offset;
00373
00374
return 0;
00375 }
00376
00377
00378
00379 HlStringDetect::HlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &s,
bool inSensitive)
00380 : HlItem(attribute, context,regionId,regionId2), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) {
00381 }
00382
00383 HlStringDetect::~HlStringDetect() {
00384 }
00385
00386
int HlStringDetect::checkHgl(
const QString& text,
int offset,
int len)
00387 {
00388
if (len < (
int)str.length())
00389
return 0;
00390
00391
if (
QConstString(text.
unicode() + offset, str.length()).string().find(str, 0, !_inSensitive) == 0)
00392
return offset + str.length();
00393
00394
return 0;
00395 }
00396
00397
00398
00399
00400 HlRangeDetect::HlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00401 : HlItem(attribute,context,regionId,regionId2) {
00402 sChar1 = ch1;
00403 sChar2 = ch2;
00404 }
00405
00406
int HlRangeDetect::checkHgl(
const QString& text,
int offset,
int len)
00407 {
00408
if ((len > 0) && (text[offset] == sChar1))
00409 {
00410
do
00411 {
00412 offset++;
00413 len--;
00414
if (len < 1)
return 0;
00415 }
00416
while (text[offset] != sChar2);
00417
00418
return offset + 1;
00419 }
00420
return 0;
00421 }
00422
00423
00424
00425 HlKeyword::HlKeyword (
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims)
00426 : HlItem(attribute,context,regionId,regionId2)
00427 , dict (113, casesensitive)
00428 , _caseSensitive(casesensitive)
00429 , deliminators(delims)
00430 {
00431 }
00432
00433 HlKeyword::~HlKeyword() {
00434 }
00435
00436
bool HlKeyword::alwaysStartEnable()
const
00437
{
00438
return false;
00439 }
00440
00441
bool HlKeyword::hasCustomStartEnable()
const
00442
{
00443
return true;
00444 }
00445
00446
bool HlKeyword::startEnable(
const QChar& c)
00447 {
00448
return deliminators.
find(c) != -1;
00449 }
00450
00451
00452
00453
void HlKeyword::addWord(
const QString &word)
00454 {
00455 dict.insert(word,&trueBool);
00456 }
00457
00458
void HlKeyword::addList(
const QStringList& list)
00459 {
00460
for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool);
00461 }
00462
00463
int HlKeyword::checkHgl(
const QString& text,
int offset,
int len)
00464 {
00465
if (len == 0 || dict.isEmpty())
return 0;
00466
00467
int offset2 = offset;
00468
00469
while (len > 0 && deliminators.
find(text[offset2]) == -1 )
00470 {
00471 offset2++;
00472 len--;
00473 }
00474
00475
if (offset2 == offset)
return 0;
00476
00477
if ( dict.find(text.
mid(offset, offset2 - offset)) )
return offset2;
00478
00479
return 0;
00480 }
00481
00482
00483
00484 HlInt::HlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00485 : HlItem(attribute,context,regionId,regionId2)
00486 {
00487 }
00488
00489
bool HlInt::alwaysStartEnable()
const
00490
{
00491
return false;
00492 }
00493
00494
int HlInt::checkHgl(
const QString& text,
int offset,
int len)
00495 {
00496
int offset2 = offset;
00497
00498
while ((len > 0) && text[offset2].isDigit())
00499 {
00500 offset2++;
00501 len--;
00502 }
00503
00504
if (offset2 > offset)
00505 {
00506
if (subItems)
00507 {
00508
for (HlItem *it = subItems->first(); it; it = subItems->next())
00509 {
00510
if ( (offset = it->checkHgl(text, offset2, len)) )
00511
return offset;
00512 }
00513 }
00514
00515
return offset2;
00516 }
00517
00518
return 0;
00519 }
00520
00521
00522
00523 HlFloat::HlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00524 : HlItem(attribute,context, regionId,regionId2) {
00525 }
00526
00527
bool HlFloat::alwaysStartEnable()
const
00528
{
00529
return false;
00530 }
00531
00532
int HlFloat::checkHgl(
const QString& text,
int offset,
int len)
00533 {
00534
bool b =
false;
00535
bool p =
false;
00536
00537
while ((len > 0) && text[offset].isDigit())
00538 {
00539 offset++;
00540 len--;
00541 b =
true;
00542 }
00543
00544
if ((len > 0) && (p = (text[offset] ==
'.')))
00545 {
00546 offset++;
00547 len--;
00548
00549
while ((len > 0) && text[offset].isDigit())
00550 {
00551 offset++;
00552 len--;
00553 b =
true;
00554 }
00555 }
00556
00557
if (!b)
00558
return 0;
00559
00560
if ((len > 0) && ((text[offset] & 0xdf) ==
'E'))
00561 {
00562 offset++;
00563 len--;
00564 }
00565
else
00566 {
00567
if (!p)
00568
return 0;
00569
else
00570 {
00571
if (subItems)
00572 {
00573
for (HlItem *it = subItems->first(); it; it = subItems->next())
00574 {
00575
int offset2 = it->checkHgl(text, offset, len);
00576
00577
if (offset2)
00578
return offset2;
00579 }
00580 }
00581
00582
return offset;
00583 }
00584 }
00585
00586
if ((len > 0) && (text[offset] ==
'-' || text[offset] ==
'+'))
00587 {
00588 offset++;
00589 len--;
00590 }
00591
00592 b =
false;
00593
00594
while ((len > 0) && text[offset].isDigit())
00595 {
00596 offset++;
00597 len--;
00598 b =
true;
00599 }
00600
00601
if (b)
00602 {
00603
if (subItems)
00604 {
00605
for (HlItem *it = subItems->first(); it; it = subItems->next())
00606 {
00607
int offset2 = it->checkHgl(text, offset, len);
00608
00609
if (offset2)
00610
return offset2;
00611 }
00612 }
00613
00614
return offset;
00615 }
00616
00617
return 0;
00618 }
00619
00620
00621
00622 HlCOct::HlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00623 : HlItem(attribute,context,regionId,regionId2) {
00624 }
00625
00626
bool HlCOct::alwaysStartEnable()
const
00627
{
00628
return false;
00629 }
00630
00631
int HlCOct::checkHgl(
const QString& text,
int offset,
int len)
00632 {
00633
if ((len > 0) && text[offset] ==
'0')
00634 {
00635 offset++;
00636 len--;
00637
00638
int offset2 = offset;
00639
00640
while ((len > 0) && (text[offset2] >=
'0' && text[offset2] <=
'7'))
00641 {
00642 offset2++;
00643 len--;
00644 }
00645
00646
if (offset2 > offset)
00647 {
00648
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset] & 0xdf) ==
'U' ))
00649 offset2++;
00650
00651
return offset2;
00652 }
00653 }
00654
00655
return 0;
00656 }
00657
00658
00659
00660 HlCHex::HlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00661 : HlItem(attribute,context,regionId,regionId2) {
00662 }
00663
00664
bool HlCHex::alwaysStartEnable()
const
00665
{
00666
return false;
00667 }
00668
00669
int HlCHex::checkHgl(
const QString& text,
int offset,
int len)
00670 {
00671
if ((len > 1) && (text[offset++] ==
'0') && ((text[offset++] & 0xdf) ==
'X' ))
00672 {
00673 len -= 2;
00674
00675
int offset2 = offset;
00676
00677
while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >=
'A' && (text[offset2] & 0xdf) <=
'F')))
00678 {
00679 offset2++;
00680 len--;
00681 }
00682
00683
if (offset2 > offset)
00684 {
00685
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset2] & 0xdf) ==
'U' ))
00686 offset2++;
00687
00688
return offset2;
00689 }
00690 }
00691
00692
return 0;
00693 }
00694
00695
00696
00697 HlCFloat::HlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00698 : HlFloat(attribute,context,regionId,regionId2) {
00699 }
00700
00701
bool HlCFloat::alwaysStartEnable()
const
00702
{
00703
return false;
00704 }
00705
00706
int HlCFloat::checkIntHgl(
const QString& text,
int offset,
int len)
00707 {
00708
int offset2 = offset;
00709
00710
while ((len > 0) && text[offset].isDigit()) {
00711 offset2++;
00712 len--;
00713 }
00714
00715
if (offset2 > offset)
00716
return offset2;
00717
00718
return 0;
00719 }
00720
00721
int HlCFloat::checkHgl(
const QString& text,
int offset,
int len)
00722 {
00723
int offset2 = HlFloat::checkHgl(text, offset, len);
00724
00725
if (offset2)
00726 {
00727
if ((text[offset2] & 0xdf) ==
'F' )
00728 offset2++;
00729
00730
return offset2;
00731 }
00732
else
00733 {
00734 offset2 = checkIntHgl(text, offset, len);
00735
00736
if (offset2 && ((text[offset2] & 0xdf) ==
'F' ))
00737
return ++offset2;
00738
else
00739
return 0;
00740 }
00741 }
00742
00743
00744
00745 HlAnyChar::HlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList)
00746 : HlItem(attribute, context,regionId,regionId2)
00747 , _charList(charList)
00748 {
00749 }
00750
00751
int HlAnyChar::checkHgl(
const QString& text,
int offset,
int len)
00752 {
00753
if ((len > 0) && _charList.find(text[offset]) != -1)
00754
return ++offset;
00755
00756
return 0;
00757 }
00758
00759
00760
00761 HlRegExpr::HlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QString regexp,
bool insensitive,
bool minimal )
00762 : HlItem(attribute, context, regionId,regionId2)
00763 {
00764 handlesLinestart=regexp.
startsWith(
"^");
00765
if(!handlesLinestart) regexp.
prepend(
"^");
00766 Expr=
new QRegExp(regexp, !insensitive);
00767 Expr->setMinimal(minimal);
00768 }
00769
00770
int HlRegExpr::checkHgl(
const QString& text,
int offset,
int )
00771 {
00772
if (offset && handlesLinestart)
00773
return 0;
00774
00775
int offset2 = Expr->search( text, offset, QRegExp::CaretAtOffset );
00776
00777
if (offset2 == -1)
return 0;
00778
00779
return (offset + Expr->matchedLength());
00780 }
00781
00782
00783
00784 HlLineContinue::HlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00785 : HlItem(attribute,context,regionId,regionId2) {
00786 }
00787
00788
int HlLineContinue::checkHgl(
const QString& text,
int offset,
int len)
00789 {
00790
if ((len == 1) && (text[offset] ==
'\\'))
00791
return ++offset;
00792
00793
return 0;
00794 }
00795
00796
00797
00798 HlCStringChar::HlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00799 : HlItem(attribute,context,regionId,regionId2) {
00800 }
00801
00802
00803
static int checkEscapedChar(
const QString& text,
int offset,
int& len)
00804 {
00805
int i;
00806
if (text[offset] ==
'\\' && len > 1)
00807 {
00808 offset++;
00809 len--;
00810
00811
switch(text[offset])
00812 {
00813
case 'a':
00814
case 'b':
00815
case 'e':
00816
case 'f':
00817
00818
case 'n':
00819
case 'r':
00820
case 't':
00821
case 'v':
00822
case '\'':
00823
case '\"':
00824
case '?' :
00825
case '\\':
00826 offset++;
00827 len--;
00828
break;
00829
00830
case 'x':
00831 offset++;
00832 len--;
00833
00834
00835
00836
00837
for (i = 0; (len > 0) && (i < 2) && (text[offset] >=
'0' && text[offset] <=
'9' || (text[offset] & 0xdf) >=
'A' && (text[offset] & 0xdf) <=
'F'); i++)
00838 {
00839 offset++;
00840 len--;
00841 }
00842
00843
if (i == 0)
00844
return 0;
00845
00846
break;
00847
00848
case '0':
case '1':
case '2':
case '3' :
00849
case '4':
case '5':
case '6':
case '7' :
00850
for (i = 0; (len > 0) && (i < 3) && (text[offset] >=
'0'&& text[offset] <=
'7'); i++)
00851 {
00852 offset++;
00853 len--;
00854 }
00855
break;
00856
00857
default:
00858
return 0;
00859 }
00860
00861
return offset;
00862 }
00863
00864
return 0;
00865 }
00866
00867
int HlCStringChar::checkHgl(
const QString& text,
int offset,
int len)
00868 {
00869
return checkEscapedChar(text, offset, len);
00870 }
00871
00872
00873
00874 HlCChar::HlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00875 : HlItem(attribute,context,regionId,regionId2) {
00876 }
00877
00878
int HlCChar::checkHgl(
const QString& text,
int offset,
int len)
00879 {
00880
if ((len > 1) && (text[offset] ==
'\'') && (text[offset+1] !=
'\''))
00881 {
00882
int oldl;
00883 oldl = len;
00884
00885 len--;
00886
00887
int offset2 = checkEscapedChar(text, offset + 1, len);
00888
00889
if (!offset2)
00890 {
00891
if (oldl > 2)
00892 {
00893 offset2 = offset + 2;
00894 len = oldl - 2;
00895 }
00896
else
00897 {
00898
return 0;
00899 }
00900 }
00901
00902
if ((len > 0) && (text[offset2] ==
'\''))
00903
return ++offset2;
00904 }
00905
00906
return 0;
00907 }
00908
00909
00910 ItemData::ItemData(
const QString name,
int defStyleNum)
00911 :
name(
name), defStyleNum(defStyleNum) {
00912 }
00913
00914 HlData::HlData(
const QString &wildcards,
const QString &mimetypes,
const QString &identifier,
int priority)
00915 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
00916 {
00917 }
00918
00919 HlContext::HlContext (
int attribute,
int lineEndContext,
int _lineBeginContext,
bool _fallthrough,
int _fallthroughContext)
00920 {
00921 attr = attribute;
00922 ctx = lineEndContext;
00923 lineBeginContext = _lineBeginContext;
00924 fallthrough = _fallthrough;
00925 ftctx = _fallthroughContext;
00926 }
00927
00928 Hl2CharDetect::Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *s)
00929 : HlItem(attribute,context,regionId,regionId2) {
00930 sChar1 = s[0];
00931 sChar2 = s[1];
00932 }
00933
00934
00935 Highlight::Highlight(
const syntaxModeListItem *def) : refCount(0)
00936 {
00937 m_attributeArrays.setAutoDelete (
true);
00938
00939 errorsAndWarnings =
"";
00940 building=
false;
00941 noHl =
false;
00942 m_foldingIndentationSensitive =
false;
00943 folding=
false;
00944 internalIDList.setAutoDelete(
true);
00945
00946
if (def == 0)
00947 {
00948 noHl =
true;
00949 iName = i18n(
"None");
00950 iSection =
"";
00951 m_priority = 0;
00952 }
00953
else
00954 {
00955 iName = def->
name;
00956 iSection = def->
section;
00957 iWildcards = def->
extension;
00958 iMimetypes = def->
mimetype;
00959 identifier = def->
identifier;
00960 iVersion=def->
version;
00961 m_priority=def->
priority.
toInt();
00962 }
00963
00964 deliminator = stdDeliminator;
00965 }
00966
00967 Highlight::~Highlight()
00968 {
00969 contextList.setAutoDelete(
true );
00970 }
00971
00972
void Highlight::generateContextStack(
int *ctxNum,
int ctx,
QMemArray<short>* ctxs,
int *prevLine,
bool lineContinue)
00973 {
00974
00975
00976
if (lineContinue)
00977 {
00978
if ( !ctxs->
isEmpty() )
00979 {
00980 (*ctxNum)=(*ctxs)[ctxs->size()-1];
00981 (*prevLine)--;
00982 }
00983
else
00984 {
00985
00986 (*ctxNum)=0;
00987 }
00988
00989
return;
00990 }
00991
00992
if (ctx >= 0)
00993 {
00994 (*ctxNum) = ctx;
00995
00996 ctxs->
resize (ctxs->
size()+1);
00997 (*ctxs)[ctxs->
size()-1]=(*ctxNum);
00998 }
00999
else
01000 {
01001
if (ctx < -1)
01002 {
01003
while (ctx < -1)
01004 {
01005
if ( ctxs->
isEmpty() )
01006 (*ctxNum)=0;
01007
else
01008 {
01009 ctxs->
truncate (ctxs->
size()-1);
01010
01011 (*ctxNum) = ( (ctxs->
isEmpty() ) ? 0 : (*ctxs)[ctxs->
size()-1]);
01012 }
01013
01014 ctx++;
01015 }
01016
01017 ctx = 0;
01018
01019
if ((*prevLine) >= (
int)(ctxs->
size()-1))
01020 {
01021 *prevLine=ctxs->
size()-1;
01022
01023
if ( ctxs->
isEmpty() )
01024
return;
01025
01026
if (contextNum((*ctxs)[ctxs->
size()-1]) && (contextNum((*ctxs)[ctxs->
size()-1])->ctx != -1))
01027 {
01028
01029 generateContextStack(ctxNum, contextNum((*ctxs)[ctxs->
size()-1])->ctx,ctxs, prevLine);
01030
return;
01031 }
01032 }
01033 }
01034
else
01035 {
01036
if (ctx == -1)
01037 (*ctxNum)=( (ctxs->
isEmpty() ) ? 0 : (*ctxs)[ctxs->
size()-1]);
01038 }
01039 }
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
void Highlight::doHighlight(
QMemArray<short> oCtx,
TextLine *textLine,
bool lineContinue,
01056
QMemArray<signed char>* foldingList)
01057 {
01058
if (!textLine)
01059
return;
01060
01061
if (noHl)
01062 {
01063 textLine->
setAttribs(0,0,textLine->
length());
01064
return;
01065 }
01066
01067
01068
01069 HlContext *context;
01070
01071
01072
01073
int ctxNum;
01074
int prevLine;
01075
01076
QMemArray<short> ctx;
01077 ctx.
duplicate (oCtx);
01078
01079
if ( oCtx.
isEmpty() )
01080 {
01081
01082 ctxNum=0;
01083 context=contextNum(ctxNum);
01084 prevLine=-1;
01085 }
01086
else
01087 {
01088
01089 ctxNum=ctx[oCtx.
size()-1];
01090
01091
01092
01093
01094
01095
if (!(context = contextNum(ctxNum)))
01096 context = contextNum(0);
01097
01098
01099
01100 prevLine=oCtx.
size()-1;
01101
01102
01103 generateContextStack(&ctxNum, context->ctx, &ctx, &prevLine, lineContinue);
01104
01105
01106
01107
if (!(context = contextNum(ctxNum)))
01108 context = contextNum(0);
01109
01110
01111 }
01112
01113
01114
QChar lastChar =
' ';
01115
const QString& text = textLine->
string();
01116 uint len = textLine->
length();
01117
01118
int offset1 = 0;
01119 uint z = 0;
01120 HlItem *item = 0;
01121
bool found =
false;
01122
01123
while (z < len)
01124 {
01125 found =
false;
01126
01127
bool standardStartEnableDetermined =
false;
01128
bool standardStartEnable =
false;
01129
01130
for (item = context->items.first(); item != 0L; item = context->items.next())
01131 {
01132
bool thisStartEnabled =
false;
01133
01134
if (item->alwaysStartEnable())
01135 {
01136 thisStartEnabled =
true;
01137 }
01138
else if (!item->hasCustomStartEnable())
01139 {
01140
if (!standardStartEnableDetermined)
01141 {
01142 standardStartEnable = stdDeliminator.
find(lastChar) != -1;
01143 standardStartEnableDetermined =
true;
01144 }
01145
01146 thisStartEnabled = standardStartEnable;
01147 }
01148
else if (item->startEnable(lastChar))
01149 {
01150 thisStartEnabled =
true;
01151 }
01152
01153
if (thisStartEnabled)
01154 {
01155
int offset2 = item->checkHgl(text, offset1, len-z);
01156
01157
if (offset2 > offset1)
01158 {
01159 textLine->
setAttribs(item->attr,offset1,offset2);
01160
01161
01162
if (item->region)
01163 {
01164
01165
01166
if ( !foldingList->
isEmpty() && ((item->region < 0) && (*foldingList)[foldingList->
size()-1] == -item->region ) )
01167 {
01168 foldingList->
resize (foldingList->
size()-1);
01169 }
01170
else
01171 {
01172 foldingList->
resize (foldingList->
size()+1);
01173 (*foldingList)[foldingList->
size()-1] = item->region;
01174 }
01175
01176 }
01177
01178
if (item->region2)
01179 {
01180
01181
01182
if ( !foldingList->
isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->
size()-1] == -item->region2 ) )
01183 {
01184 foldingList->
resize (foldingList->
size()-1);
01185 }
01186
else
01187 {
01188 foldingList->
resize (foldingList->
size()+1);
01189 (*foldingList)[foldingList->
size()-1] = item->region2;
01190 }
01191
01192 }
01193
01194 generateContextStack(&ctxNum, item->ctx, &ctx, &prevLine);
01195
01196
01197
01198
01199 context=contextNum(ctxNum);
01200
01201 z = z + offset2 - offset1 - 1;
01202 offset1 = offset2 - 1;
01203 found =
true;
01204
break;
01205 }
01206 }
01207 }
01208
01209 lastChar = text[offset1];
01210
01211
01212
01213
if (!found)
01214 {
01215
if ( context->fallthrough )
01216 {
01217
01218 generateContextStack(&ctxNum, context->ftctx, &ctx, &prevLine);
01219 context=contextNum(ctxNum);
01220
01221
01222
01223
01224
if (z)
01225 lastChar = text[offset1 - 1];
01226
else
01227 lastChar =
'\\';
01228
continue;
01229 }
01230
else
01231 textLine->
setAttribs(context->attr,offset1,offset1 + 1);
01232 }
01233
01234 offset1++;
01235 z++;
01236 }
01237
01238
if (item==0)
01239 textLine->
setHlLineContinue(
false);
01240
else
01241 textLine->
setHlLineContinue(item->lineContinue());
01242
01243 textLine->
setContext(ctx.
data(), ctx.
size());
01244 }
01245
01246
void Highlight::loadWildcards()
01247 {
01248
KConfig *config = HlManager::self()->getKConfig();
01249 config->
setGroup(
"Highlighting " + iName);
01250
01251
QString extensionString = config->
readEntry(
"Wildcards", iWildcards);
01252
01253
if (extensionSource != extensionString) {
01254 regexpExtensions.clear();
01255 plainExtensions.clear();
01256
01257 extensionSource = extensionString;
01258
01259
static QRegExp sep(
"\\s*;\\s*");
01260
01261
QStringList l =
QStringList::split( sep, extensionSource );
01262
01263
static QRegExp boringExpression(
"\\*\\.[\\d\\w]+");
01264
01265
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
01266
if (boringExpression.exactMatch(*it))
01267 plainExtensions.append((*it).mid(1));
01268
else
01269 regexpExtensions.append(
QRegExp((*it),
true,
true));
01270 }
01271 }
01272
01273
QValueList<QRegExp>& Highlight::getRegexpExtensions()
01274 {
01275
return regexpExtensions;
01276 }
01277
01278
QStringList& Highlight::getPlainExtensions()
01279 {
01280
return plainExtensions;
01281 }
01282
01283
QString Highlight::getMimetypes()
01284 {
01285
KConfig *config = HlManager::self()->getKConfig();
01286 config->
setGroup(
"Highlighting " + iName);
01287
01288
return config->
readEntry(
"Mimetypes", iMimetypes);
01289 }
01290
01291
int Highlight::priority()
01292 {
01293
KConfig *config = HlManager::self()->getKConfig();
01294 config->
setGroup(
"Highlighting " + iName);
01295
01296
return config->
readNumEntry(
"Priority", m_priority);
01297 }
01298
01299 HlData *Highlight::getData()
01300 {
01301
KConfig *config = HlManager::self()->getKConfig();
01302 config->
setGroup(
"Highlighting " + iName);
01303
01304 HlData *hlData =
new HlData(
01305 config->
readEntry(
"Wildcards", iWildcards),
01306 config->
readEntry(
"Mimetypes", iMimetypes),
01307 config->
readEntry(
"Identifier", identifier),
01308 config->
readNumEntry(
"Priority", m_priority));
01309
01310
return hlData;
01311 }
01312
01313
void Highlight::setData(HlData *hlData)
01314 {
01315
KConfig *config = HlManager::self()->getKConfig();
01316 config->
setGroup(
"Highlighting " + iName);
01317
01318 config->
writeEntry(
"Wildcards",hlData->wildcards);
01319 config->
writeEntry(
"Mimetypes",hlData->mimetypes);
01320 config->
writeEntry(
"Priority",hlData->priority);
01321 }
01322
01323
void Highlight::getItemDataList (uint schema,
ItemDataList &list)
01324 {
01325
KConfig *config = HlManager::self()->getKConfig();
01326 config->
setGroup(
"Highlighting " + iName +
" - Schema " + KateFactory::self()->schemaManager()->
name(schema));
01327
01328 list.
clear();
01329 createItemData(list);
01330
01331
for (ItemData *p = list.
first(); p != 0L; p = list.
next())
01332 {
01333
QStringList s = config->
readListEntry(p->name);
01334
01335
01336
if (s.count()>0)
01337 {
01338
01339
while(s.count()<9) s<<
"";
01340 p->clear();
01341
01342
QString tmp=s[0];
if (!tmp.
isEmpty()) p->defStyleNum=tmp.
toInt();
01343
01344 QRgb col;
01345
01346 tmp=s[1];
if (!tmp.
isEmpty()) {
01347 col=tmp.
toUInt(0,16); p->setTextColor(col); }
01348
01349 tmp=s[2];
if (!tmp.
isEmpty()) {
01350 col=tmp.
toUInt(0,16); p->setSelectedTextColor(col); }
01351
01352 tmp=s[3];
if (!tmp.
isEmpty()) p->setBold(tmp!=
"0");
01353
01354 tmp=s[4];
if (!tmp.
isEmpty()) p->setItalic(tmp!=
"0");
01355
01356 tmp=s[5];
if (!tmp.
isEmpty()) p->setStrikeOut(tmp!=
"0");
01357
01358 tmp=s[6];
if (!tmp.
isEmpty()) p->setUnderline(tmp!=
"0");
01359
01360 tmp=s[7];
if (!tmp.
isEmpty()) {
01361 col=tmp.
toUInt(0,16); p->setBGColor(col); }
01362
01363 tmp=s[8];
if (!tmp.
isEmpty()) {
01364 col=tmp.
toUInt(0,16); p->setSelectedBGColor(col); }
01365
01366 }
01367 }
01368 }
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
void Highlight::setItemDataList(uint schema,
ItemDataList &list)
01387 {
01388
KConfig *config = HlManager::self()->getKConfig();
01389 config->
setGroup(
"Highlighting " + iName +
" - Schema " + KateFactory::self()->schemaManager()->
name(schema));
01390
01391
QStringList settings;
01392
01393
for (ItemData *p = list.
first(); p != 0L; p = list.
next())
01394 {
01395 settings.clear();
01396 settings<<
QString::number(p->defStyleNum,10);
01397 settings<<(p->itemSet(KateAttribute::TextColor)?
QString::number(p->textColor().rgb(),16):
"");
01398 settings<<(p->itemSet(KateAttribute::SelectedTextColor)?
QString::number(p->selectedTextColor().rgb(),16):
"");
01399 settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?
"1":
"0"):
"");
01400 settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?
"1":
"0"):
"");
01401 settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?
"1":
"0"):
"");
01402 settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?
"1":
"0"):
"");
01403 settings<<(p->itemSet(KateAttribute::BGColor)?
QString::number(p->bgColor().rgb(),16):
"");
01404 settings<<(p->itemSet(KateAttribute::SelectedBGColor)?
QString::number(p->selectedBGColor().rgb(),16):
"");
01405 settings<<
"---";
01406 config->
writeEntry(p->name,settings);
01407 }
01408 }
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
void Highlight::use()
01422 {
01423
if (refCount == 0)
01424 init();
01425
01426 refCount++;
01427 }
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
void Highlight::release()
01441 {
01442 refCount--;
01443
01444
if (refCount == 0)
01445
done();
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
void Highlight::init()
01460 {
01461
if (noHl)
01462
return;
01463
01464 contextList.clear ();
01465 makeContextList();
01466 }
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
void Highlight::done()
01482 {
01483
if (noHl)
01484
return;
01485
01486 contextList.clear ();
01487 internalIDList.clear();
01488 }
01489
01490 HlContext *Highlight::contextNum (uint n)
01491 {
01492
return contextList[n];
01493 }
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
void Highlight::createItemData(
ItemDataList &list)
01510 {
01511
01512
if (noHl)
01513 {
01514 list.
append(
new ItemData(
I18N_NOOP(
"Normal Text"), dsNormal));
01515
return;
01516 }
01517
01518
01519
if (internalIDList.isEmpty())
01520 makeContextList();
01521
01522 list=internalIDList;
01523 }
01524
01525
void Highlight::addToItemDataList()
01526 {
01527
01528 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01529
syntaxContextData *data = HlManager::self()->syntax->getGroupInfo(
"highlighting",
"itemData");
01530
01531
01532
while (HlManager::self()->syntax->nextGroup(data))
01533 {
01534
01535
QString color = HlManager::self()->syntax->groupData(data,
QString(
"color"));
01536
QString selColor = HlManager::self()->syntax->groupData(data,
QString(
"selColor"));
01537
QString bold = HlManager::self()->syntax->groupData(data,
QString(
"bold"));
01538
QString italic = HlManager::self()->syntax->groupData(data,
QString(
"italic"));
01539
QString underline = HlManager::self()->syntax->groupData(data,
QString(
"underline"));
01540
QString strikeOut = HlManager::self()->syntax->groupData(data,
QString(
"strikeOut"));
01541
QString bgColor = HlManager::self()->syntax->groupData(data,
QString(
"backgroundColor"));
01542
QString selBgColor = HlManager::self()->syntax->groupData(data,
QString(
"selBackgroundColor"));
01543
01544 ItemData* newData =
new ItemData(
01545 buildPrefix+HlManager::self()->syntax->groupData(data,
QString(
"name")).simplifyWhiteSpace(),
01546 getDefStyleNum(HlManager::self()->syntax->groupData(data,
QString(
"defStyleNum"))));
01547
01548
01549
01550
if (!color.
isEmpty()) newData->setTextColor(
QColor(color));
01551
if (!selColor.
isEmpty()) newData->setSelectedTextColor(
QColor(selColor));
01552
if (!bold.
isEmpty()) newData->setBold(bold==
"true" || bold==
"1");
01553
if (!italic.
isEmpty()) newData->setItalic(italic==
"true" || italic==
"1");
01554
01555
if (!underline.
isEmpty()) newData->setUnderline(underline==
"true" || underline==
"1");
01556
if (!strikeOut.
isEmpty()) newData->setStrikeOut(strikeOut==
"true" || strikeOut==
"1");
01557
if (!bgColor.
isEmpty()) newData->setBGColor(
QColor(bgColor));
01558
if (!selBgColor.
isEmpty()) newData->setSelectedBGColor(
QColor(selBgColor));
01559
01560 internalIDList.append(newData);
01561 }
01562
01563
01564
if (data)
01565 HlManager::self()->syntax->freeGroupInfo(data);
01566 }
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
int Highlight::lookupAttrName(
const QString& name,
ItemDataList &iDl)
01584 {
01585
for (uint i = 0; i < iDl.
count(); i++)
01586
if (iDl.
at(i)->name == buildPrefix+
name)
01587
return i;
01588
01589
kdDebug(13010)<<
"Couldn't resolve itemDataName"<<
endl;
01590
return 0;
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612 HlItem *Highlight::createHlItem(
struct syntaxContextData *data,
ItemDataList &iDl,
QStringList *RegionList,
QStringList *ContextNameList)
01613 {
01614
01615
if (noHl)
01616
return 0;
01617
01618
01619
QString dataname=HlManager::self()->syntax->groupItemData(data,
QString(
""));
01620
01621
01622
QString tmpAttr=HlManager::self()->syntax->groupItemData(data,
QString(
"attribute")).simplifyWhiteSpace();
01623
int attr;
01624
if (
QString(
"%1").arg(tmpAttr.
toInt())==tmpAttr)
01625 {
01626 errorsAndWarnings+=i18n(
"<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
01627 arg(buildIdentifier).arg(tmpAttr);
01628 attr=tmpAttr.
toInt();
01629 }
01630
else
01631 attr=lookupAttrName(tmpAttr,iDl);
01632
01633
01634
01635
int context;
01636
QString tmpcontext=HlManager::self()->syntax->groupItemData(data,
QString(
"context"));
01637
01638
01639
QString unresolvedContext;
01640 context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
01641
01642
01643
char chr;
01644
if (! HlManager::self()->syntax->groupItemData(data,
QString(
"char")).isEmpty())
01645 chr= (HlManager::self()->syntax->groupItemData(data,
QString(
"char")).latin1())[0];
01646
else
01647 chr=0;
01648
01649
01650
QString stringdata=HlManager::self()->syntax->groupItemData(data,
QString(
"String"));
01651
01652
01653
char chr1;
01654
if (! HlManager::self()->syntax->groupItemData(data,
QString(
"char1")).isEmpty())
01655 chr1= (HlManager::self()->syntax->groupItemData(data,
QString(
"char1")).latin1())[0];
01656
else
01657 chr1=0;
01658
01659
01660
bool insensitive=( HlManager::self()->syntax->groupItemData(data,
QString(
"insensitive")).lower() ==
QString(
"true") );
01661
01662
01663
01664
bool minimal = ( HlManager::self()->syntax->groupItemData(data,
QString(
"minimal")).lower() ==
QString(
"true") );
01665
01666
01667
01668
QString beginRegionStr=HlManager::self()->syntax->groupItemData(data,
QString(
"beginRegion"));
01669
QString endRegionStr=HlManager::self()->syntax->groupItemData(data,
QString(
"endRegion"));
01670
01671
signed char regionId=0;
01672
signed char regionId2=0;
01673
01674
if (!beginRegionStr.
isEmpty())
01675 {
01676 regionId = RegionList->findIndex(beginRegionStr);
01677
01678
if (regionId==-1)
01679 {
01680 (*RegionList)<<beginRegionStr;
01681 regionId = RegionList->findIndex(beginRegionStr);
01682 }
01683
01684 regionId++;
01685
01686
kdDebug () <<
"########### BEG REG: " << beginRegionStr <<
" NUM: " << regionId <<
endl;
01687 }
01688
01689
if (!endRegionStr.
isEmpty())
01690 {
01691 regionId2 = RegionList->findIndex(endRegionStr);
01692
01693
if (regionId2==-1)
01694 {
01695 (*RegionList)<<endRegionStr;
01696 regionId2 = RegionList->findIndex(endRegionStr);
01697 }
01698
01699 regionId2 = -regionId2 - 1;
01700
01701
kdDebug () <<
"########### END REG: " << endRegionStr <<
" NUM: " << regionId2 <<
endl;
01702 }
01703
01704
01705 HlItem *tmpItem;
01706
01707
if (dataname==
"keyword")
01708 {
01709 HlKeyword *keyword=
new HlKeyword(attr,context,regionId,regionId2,casesensitive,
01710 deliminator);
01711
01712
01713 keyword->addList(HlManager::self()->syntax->finddata(
"highlighting",stringdata));
01714 tmpItem=keyword;
01715 }
else
01716
if (dataname==
"Float") tmpItem= (
new HlFloat(attr,context,regionId,regionId2));
else
01717
if (dataname==
"Int") tmpItem=(
new HlInt(attr,context,regionId,regionId2));
else
01718
if (dataname==
"DetectChar") tmpItem=(
new HlCharDetect(attr,context,regionId,regionId2,chr));
else
01719
if (dataname==
"Detect2Chars") tmpItem=(
new Hl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
else
01720
if (dataname==
"RangeDetect") tmpItem=(
new HlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
else
01721
if (dataname==
"LineContinue") tmpItem=(
new HlLineContinue(attr,context,regionId,regionId2));
else
01722
if (dataname==
"StringDetect") tmpItem=(
new HlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
else
01723
if (dataname==
"AnyChar") tmpItem=(
new HlAnyChar(attr,context,regionId,regionId2,stringdata));
else
01724
if (dataname==
"RegExpr") tmpItem=(
new HlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
else
01725
if (dataname==
"HlCChar") tmpItem= (
new HlCChar(attr,context,regionId,regionId2));
else
01726
if (dataname==
"HlCHex") tmpItem= (
new HlCHex(attr,context,regionId,regionId2));
else
01727
if (dataname==
"HlCOct") tmpItem= (
new HlCOct(attr,context,regionId,regionId2));
else
01728
if (dataname==
"HlCFloat") tmpItem= (
new HlCFloat(attr,context,regionId,regionId2));
else
01729
if (dataname==
"HlCStringChar") tmpItem= (
new HlCStringChar(attr,context,regionId,regionId2));
else
01730
01731 {
01732
01733
return 0;
01734 }
01735
01736
if (!unresolvedContext.
isEmpty())
01737 {
01738 unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
01739 }
01740
return tmpItem;
01741 }
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
bool Highlight::isInWord(
QChar c)
01755 {
01756
static const QString sq(
"\"'");
01757
return deliminator.find(c) == -1 && sq.find(c) == -1;
01758 }
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
void Highlight::readCommentConfig()
01773 {
01774 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01775
syntaxContextData *data=HlManager::self()->syntax->getGroupInfo(
"general",
"comment");
01776
01777
if (data)
01778 {
01779
while (HlManager::self()->syntax->nextGroup(data))
01780 {
01781
if (HlManager::self()->syntax->groupData(data,
"name")==
"singleLine")
01782 cslStart=HlManager::self()->syntax->groupData(data,
"start");
01783
01784
if (HlManager::self()->syntax->groupData(data,
"name")==
"multiLine")
01785 {
01786 cmlStart=HlManager::self()->syntax->groupData(data,
"start");
01787 cmlEnd=HlManager::self()->syntax->groupData(data,
"end");
01788 }
01789 }
01790
01791 HlManager::self()->syntax->freeGroupInfo(data);
01792 }
01793
else
01794 {
01795 cslStart =
"";
01796 cmlStart =
"";
01797 cmlEnd =
"";
01798 }
01799 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
void Highlight::readGlobalKeywordConfig()
01816 {
01817
01818
kdDebug(13010)<<
"readGlobalKeywordConfig:BEGIN"<<
endl;
01819
01820 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01821
syntaxContextData *data = HlManager::self()->syntax->getConfig(
"general",
"keywords");
01822
01823
if (data)
01824 {
01825
kdDebug(13010)<<
"Found global keyword config"<<
endl;
01826
01827
if (HlManager::self()->syntax->groupItemData(data,
QString(
"casesensitive"))!=
"0")
01828 casesensitive=
true;
01829
else
01830 casesensitive=
false;
01831
01832
01833 weakDeliminator=(HlManager::self()->syntax->groupItemData(data,
QString(
"weakDeliminator")));
01834
01835
kdDebug(13010)<<
"weak delimiters are: "<<weakDeliminator<<
endl;
01836
01837
01838
for (uint s=0; s < weakDeliminator.length(); s++)
01839 {
01840
int f = deliminator.find (weakDeliminator[s]);
01841
01842
if (f > -1)
01843 deliminator.remove (f, 1);
01844 }
01845
01846
QString addDelim = (HlManager::self()->syntax->groupItemData(data,
QString(
"additionalDeliminator")));
01847
01848
if (!addDelim.
isEmpty())
01849 deliminator=deliminator+addDelim;
01850
01851 HlManager::self()->syntax->freeGroupInfo(data);
01852 }
01853
else
01854 {
01855
01856 casesensitive=
true;
01857 weakDeliminator=
QString(
"");
01858 }
01859
01860
kdDebug(13010)<<
"readGlobalKeywordConfig:END"<<
endl;
01861
01862
kdDebug(13010)<<
"delimiterCharacters are: "<<deliminator<<
endl;
01863 }
01864
01865
01866
void Highlight::readFoldingConfig()
01867 {
01868
01869
kdDebug(13010)<<
"readfoldignConfig:BEGIN"<<
endl;
01870
01871 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01872
syntaxContextData *data = HlManager::self()->syntax->getConfig(
"general",
"folding");
01873
01874
if (data)
01875 {
01876
kdDebug(13010)<<
"Found global keyword config"<<
endl;
01877
01878
if (HlManager::self()->syntax->groupItemData(data,
QString(
"indentationsensitive"))!=
"1")
01879 m_foldingIndentationSensitive=
false;
01880
else
01881 m_foldingIndentationSensitive=
true;
01882
01883 HlManager::self()->syntax->freeGroupInfo(data);
01884 }
01885
else
01886 {
01887
01888 m_foldingIndentationSensitive =
false;
01889 }
01890
01891
kdDebug(13010)<<
"readfoldingConfig:END"<<
endl;
01892
01893
kdDebug(13010)<<
"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<
endl;
01894 }
01895
01896
void Highlight::createContextNameList(
QStringList *ContextNameList,
int ctx0)
01897 {
01898
kdDebug(13010)<<
"creatingContextNameList:BEGIN"<<
endl;
01899
01900
if (ctx0 == 0)
01901 ContextNameList->clear();
01902
01903 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01904
01905
syntaxContextData *data=HlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
01906
01907
int id=ctx0;
01908
01909
if (data)
01910 {
01911
while (HlManager::self()->syntax->nextGroup(data))
01912 {
01913
QString tmpAttr=HlManager::self()->syntax->groupData(data,
QString(
"name")).
simplifyWhiteSpace();
01914
if (tmpAttr.
isEmpty())
01915 {
01916 tmpAttr=
QString(
"!KATE_INTERNAL_DUMMY! %1").
arg(
id);
01917 errorsAndWarnings +=i18n(
"<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(
id-ctx0);
01918 }
01919
else tmpAttr=buildPrefix+tmpAttr;
01920 (*ContextNameList)<<tmpAttr;
01921
id++;
01922 }
01923 HlManager::self()->syntax->freeGroupInfo(data);
01924 }
01925
kdDebug(13010)<<
"creatingContextNameList:END"<<
endl;
01926
01927 }
01928
01929
int Highlight::getIdFromString(
QStringList *ContextNameList,
QString tmpLineEndContext,
QString &unres)
01930 {
01931 unres=
"";
01932
int context;
01933
if ((tmpLineEndContext==
"#stay") || (tmpLineEndContext.
simplifyWhiteSpace().isEmpty())) context=-1;
01934
else if (tmpLineEndContext.
startsWith(
"#pop"))
01935 {
01936 context=-1;
01937
for(;tmpLineEndContext.
startsWith(
"#pop");context--)
01938 {
01939 tmpLineEndContext.
remove(0,4);
01940
kdDebug(13010)<<
"#pop found"<<
endl;
01941 }
01942 }
01943
else
01944
if ( tmpLineEndContext.
startsWith(
"##"))
01945 {
01946
QString tmp=tmpLineEndContext.
right(tmpLineEndContext.
length()-2);
01947
if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,EmbeddedHlInfo());
01948 unres=tmp;
01949 context=0;
01950 }
01951
else
01952 {
01953 context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
01954
if (context==-1)
01955 {
01956 context=tmpLineEndContext.
toInt();
01957 errorsAndWarnings+=i18n(
"<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name").arg(buildIdentifier).arg(tmpLineEndContext);
01958 }
01959
01960
01961 }
01962
return context;
01963 }
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
void Highlight::makeContextList()
01979 {
01980
if (noHl)
01981
return;
01982
01983 embeddedHls.clear();
01984 unresolvedContextReferences.clear();
01985 RegionList.clear();
01986 ContextNameList.clear();
01987
01988
01989 embeddedHls.insert(iName,EmbeddedHlInfo());
01990
01991
bool something_changed;
01992
int startctx=0;
01993 building=
true;
01994
do
01995 {
01996
kdDebug(13010)<<
"**************** Outter loop in make ContextList"<<
endl;
01997
kdDebug(13010)<<
"**************** Hl List count:"<<embeddedHls.count()<<
endl;
01998 something_changed=
false;
01999
for (EmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
02000 {
02001
if (!it.data().loaded)
02002 {
02003
kdDebug(13010)<<
"**************** Inner loop in make ContextList"<<
endl;
02004
QString identifierToUse;
02005
kdDebug(13010)<<
"Trying to open highlighting definition file: "<< it.key()<<
endl;
02006
if (iName==it.key()) identifierToUse=identifier;
02007
else
02008 identifierToUse=HlManager::self()->identifierForName(it.key());
02009
02010
kdDebug(13010)<<
"Location is:"<< identifierToUse<<
endl;
02011
02012 buildPrefix=it.key()+
':';
02013
02014
if (identifierToUse.
isEmpty() )
kdDebug()<<
"OHOH, unknown highlighting description referenced"<<
endl;
02015
02016
kdDebug()<<
"setting ("<<it.key()<<
") to loaded"<<
endl;
02017 it=embeddedHls.insert(it.key(),EmbeddedHlInfo(
true,startctx));
02018 buildContext0Offset=startctx;
02019 startctx=addToContextList(identifierToUse,startctx);
02020
if (noHl)
return;
02021 something_changed=
true;
02022
02023 }
02024 }
02025 }
while (something_changed);
02026
02027
02028
02029
02030
02031
kdDebug(13010)<<
"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<
endl;
02032
02033
for (UnresolvedContextReferences::iterator unresIt=unresolvedContextReferences.begin();
02034 unresIt!=unresolvedContextReferences.end();++unresIt)
02035 {
02036
02037 EmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
02038
if (hlIt!=embeddedHls.end())
02039 *(unresIt.key())=hlIt.data().context0;
02040 }
02041
02042
02043
02044
02045 handleIncludeRules();
02046
02047 embeddedHls.clear();
02048 unresolvedContextReferences.clear();
02049 RegionList.clear();
02050 ContextNameList.clear();
02051
02052
02053
02054
if (!errorsAndWarnings.isEmpty())
02055
KMessageBox::detailedSorry(0L,i18n(
"There were warning(s) and/or error(s) while parsing the syntax highlighting configuration."), errorsAndWarnings, i18n(
"Kate Syntax Highlight Parser"));
02056
02057
02058 building=
false;
02059 }
02060
02061
void Highlight::handleIncludeRules()
02062 {
02063
02064
02065
kdDebug(13010)<<
"IncludeRules, which need attention: " <<includeRules.count()<<
endl;
02066
if (includeRules.isEmpty())
return;
02067
02068 buildPrefix=
"";
02069
QString dummy;
02070
02071
02072
02073
02074
02075
02076
02077
for (IncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
02078 {
02079
02080
if ((*it)->incCtx==-1)
02081 {
02082
02083
if ((*it)->incCtxN.isEmpty())
02084 {
02085
02086 IncludeRules::iterator it1=it;
02087 ++it1;
02088
delete (*it);
02089 includeRules.remove(it);
02090 it=it1;
02091 }
02092
else
02093 {
02094
02095 (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
02096
kdDebug()<<
"Resolved "<<(*it)->incCtxN<<
" to "<<(*it)->incCtx<<
" for include rule"<<
endl;
02097
02098 }
02099 }
else ++it;
02100 }
02101
02102
02103
02104
02105
02106
while (!includeRules.isEmpty())
02107 handleIncludeRulesRecursive(includeRules.begin(),&includeRules);
02108
02109
02110 }
02111
02112
void Highlight::handleIncludeRulesRecursive(IncludeRules::iterator it,
IncludeRules *list)
02113 {
02114
if (it==list->
end())
return;
02115 IncludeRules::iterator it1=it;
02116
int ctx=(*it1)->ctx;
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
while ((it!=list->
end()) && ((*it)->ctx==ctx))
02127 {
02128 it1=it;
02129 ++it;
02130
02131 }
02132
02133
while ((it1!=list->
end()) && ((*it1)->ctx==ctx))
02134 {
02135
02136
02137
02138
int ctx1=(*it1)->incCtx;
02139
02140
02141
for (IncludeRules::iterator it2=list->
begin();it2!=list->
end();++it2)
02142 {
02143
02144
02145
if ((*it2)->ctx==ctx1)
02146 {
02147
02148
02149 handleIncludeRulesRecursive(it2,list);
02150
break;
02151 }
02152 }
02153
02154
02155 HlContext *dest=contextList[ctx];
02156 HlContext *src=contextList[ctx1];
02157 uint p=(*it1)->pos;
02158
for ( HlItem *c = src->items.first(); c; c=src->items.next(), p++ )
02159 dest->items.insert(p,c);
02160
02161 it=it1;
02162 --it1;
02163
delete (*it);
02164 list->
remove(it);
02165 }
02166 }
02167
02168
int Highlight::addToContextList(
const QString &ident,
int ctx0)
02169 {
02170 buildIdentifier=ident;
02171
syntaxContextData *data, *datasub;
02172 HlItem *c;
02173
02174
QString dummy;
02175
02176
02177
if (!HlManager::self()->syntax->setIdentifier(ident))
02178 {
02179 noHl=
true;
02180
KMessageBox::information(0L,i18n(
"Since there has been an error parsing the highlighting description, this highlighting will be disabled"));
02181
return 0;
02182 }
02183
02184 RegionList<<
"!KateInternal_TopLevel!";
02185 readCommentConfig();
02186 readGlobalKeywordConfig();
02187 readFoldingConfig ();
02188
02189
QString ctxName;
02190
02191
02192 addToItemDataList();
02193
ItemDataList iDl = internalIDList;
02194
02195 createContextNameList(&ContextNameList,ctx0);
02196
02197
kdDebug(13010)<<
"Parsing Context structure"<<
endl;
02198
02199 data=HlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
02200 uint i=buildContext0Offset;
02201
if (data)
02202 {
02203
while (HlManager::self()->syntax->nextGroup(data))
02204 {
02205
kdDebug(13010)<<
"Found a context in file, building structure now"<<
endl;
02206
02207
QString tmpAttr=HlManager::self()->syntax->groupData(data,
QString(
"attribute")).
simplifyWhiteSpace();
02208
int attr;
02209
if (
QString(
"%1").arg(tmpAttr.
toInt())==tmpAttr)
02210 attr=tmpAttr.
toInt();
02211
else
02212 attr=lookupAttrName(tmpAttr,iDl);
02213
02214
02215 ctxName=buildPrefix+HlManager::self()->syntax->groupData(data,
QString(
"lineEndContext")).
simplifyWhiteSpace();
02216
02217
QString tmpLineEndContext=HlManager::self()->syntax->groupData(data,
QString(
"lineEndContext")).
simplifyWhiteSpace();
02218
int context;
02219
02220 context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
02221
02222
02223
bool ft =
false;
02224
int ftc = 0;
02225
if ( i > 0 ) {
02226
QString tmpFt = HlManager::self()->syntax->groupData(data,
QString(
"fallthrough") );
02227
if ( tmpFt.
lower() ==
"true" || tmpFt.
toInt() == 1 )
02228 ft =
true;
02229
if ( ft ) {
02230
QString tmpFtc = HlManager::self()->syntax->groupData( data,
QString(
"fallthroughContext") );
02231
02232 ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
02233
if (ftc == -1) ftc =0;
02234
02235
kdDebug(13010)<<
"Setting fall through context (context "<<i<<
"): "<<ftc<<
endl;
02236 }
02237 }
02238
02239
02240 contextList.insert (i,
new HlContext (
02241 attr,
02242 context,
02243 (HlManager::self()->syntax->groupData(data,
QString(
"lineBeginContext"))).isEmpty()?-1:
02244 (HlManager::self()->syntax->groupData(data,
QString(
"lineBeginContext"))).toInt(),
02245 ft, ftc
02246 ));
02247
02248
02249
02250
while (HlManager::self()->syntax->nextItem(data))
02251 {
02252
02253
02254
02255
02256
QString tag = HlManager::self()->syntax->groupItemData(data,
QString(
""));
02257
if ( tag ==
"IncludeRules" ) {
02258
QString incCtx=HlManager::self()->syntax->groupItemData( data,
QString(
"context"));
02259
02260
if (incCtx.
startsWith(
"##") || (!incCtx.
startsWith(
"#"))) {
02261
if (!incCtx.
startsWith(
"#")) {
02262 incCtx=buildPrefix+incCtx.
simplifyWhiteSpace();
02263 includeRules.append(
new IncludeRule(i,contextList[i]->items.count(),incCtx));
02264 }
02265
else {
02266
kdDebug()<<
"Cross highlight reference <IncludeRules>"<<
endl;
02267 IncludeRule *ir=
new IncludeRule(i,contextList[i]->items.count());
02268
02269
if (!embeddedHls.contains(incCtx.
right(incCtx.
length()-2)))
02270 embeddedHls.insert(incCtx.
right(incCtx.
length()-2),EmbeddedHlInfo());
02271 unresolvedContextReferences.insert(&(ir->incCtx),
02272 incCtx.
right(incCtx.
length()-2));
02273 includeRules.append(ir);
02274 }
02275 }
02276
continue;
02277 }
02278
#if 0
02279
QString tag = HlManager::self()->syntax->groupItemData(data,
QString(
""));
02280
if ( tag ==
"IncludeRules" ) {
02281
02282
int ctxId = getIdFromString(&ContextNameList,
02283 HlManager::self()->syntax->groupItemData( data,
QString(
"context")),dummy);
02284
if ( ctxId > -1) {
02285
kdDebug(13010)<<
"makeContextList["<<i<<
"]: including all items of context "<<ctxId<<
endl;
02286
if ( ctxId < (
int) i ) {
02287
for ( c = contextList[ctxId]->items.first(); c; c = contextList[ctxId]->items.next() )
02288 contextList[i]->items.append(c);
02289 }
02290
else
02291
kdDebug(13010)<<
"Context "<<ctxId<<
"not defined. You can not include the rules of an undefined context"<<
endl;
02292 }
02293
continue;
02294 }
02295
#endif
02296
c=createHlItem(data,iDl,&RegionList,&ContextNameList);
02297
if (c)
02298 {
02299 contextList[i]->items.append(c);
02300
02301
02302 datasub=HlManager::self()->syntax->getSubItems(data);
02303
bool tmpbool;
02304
if (tmpbool=HlManager::self()->syntax->nextItem(datasub))
02305 {
02306 c->subItems=
new QPtrList<HlItem>;
02307
for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub))
02308 c->subItems->append(createHlItem(datasub,iDl,&RegionList,&ContextNameList));
02309 }
02310 HlManager::self()->syntax->freeGroupInfo(datasub);
02311
02312 }
02313
02314 }
02315 i++;
02316 }
02317 }
02318
02319 HlManager::self()->syntax->freeGroupInfo(data);
02320
if (RegionList.count()!=1) folding=
true;
02321 folding = folding || m_foldingIndentationSensitive;
02322
return i;
02323 }
02324
02325
void Highlight::clearAttributeArrays ()
02326 {
02327
for (
QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
02328 {
02329
02330
KateAttributeList defaultStyleList;
02331 defaultStyleList.
setAutoDelete(
true);
02332 HlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
02333
02334
ItemDataList itemDataList;
02335 getItemDataList(it.currentKey(), itemDataList);
02336
02337 uint nAttribs = itemDataList.
count();
02338
QMemArray<KateAttribute> *array = it.current();
02339 array->
resize (nAttribs);
02340
02341
for (uint z = 0; z < nAttribs; z++)
02342 {
02343 ItemData *itemData = itemDataList.
at(z);
02344
KateAttribute n = *defaultStyleList.
at(itemData->defStyleNum);
02345
02346
if (itemData && itemData->isSomethingSet())
02347 n += *itemData;
02348
02349 array->
at(z) = n;
02350 }
02351 }
02352 }
02353
02354
QMemArray<KateAttribute> *Highlight::attributes (uint schema)
02355 {
02356
QMemArray<KateAttribute> *array;
02357
02358
02359
if ((array = m_attributeArrays[schema]))
02360
return array;
02361
02362
02363
if (!KateFactory::self()->schemaManager()->validSchema(schema))
02364 {
02365
02366
return attributes (0);
02367 }
02368
02369
02370
KateAttributeList defaultStyleList;
02371 defaultStyleList.
setAutoDelete(
true);
02372 HlManager::self()->getDefaults(schema, defaultStyleList);
02373
02374
ItemDataList itemDataList;
02375 getItemDataList(schema, itemDataList);
02376
02377 uint nAttribs = itemDataList.
count();
02378 array =
new QMemArray<KateAttribute> (nAttribs);
02379
02380
for (uint z = 0; z < nAttribs; z++)
02381 {
02382 ItemData *itemData = itemDataList.
at(z);
02383
KateAttribute n = *defaultStyleList.
at(itemData->defStyleNum);
02384
02385
if (itemData && itemData->isSomethingSet())
02386 n += *itemData;
02387
02388 array->
at(z) = n;
02389 }
02390
02391 m_attributeArrays.insert(schema, array);
02392
02393
return array;
02394 }
02395
02396
void Highlight::getItemDataListCopy (uint schema,
ItemDataList &outlist)
02397 {
02398
ItemDataList itemDataList;
02399 getItemDataList(schema, itemDataList);
02400
02401 outlist.
clear ();
02402 outlist.
setAutoDelete (
true);
02403
for (uint z=0; z < itemDataList.
count(); z++)
02404 outlist.
append (
new ItemData (*itemDataList.
at(z)));
02405 }
02406
02407
02408
02409
02410 HlManager::HlManager()
02411 :
QObject()
02412 , m_config (
"katesyntaxhighlightingrc", false, false)
02413 , commonSuffixes (
QStringList::split(
";",
".orig;.new;~;.bak;.BAK"))
02414 , syntax (new
SyntaxDocument())
02415 {
02416 hlList.setAutoDelete(
true);
02417 hlDict.setAutoDelete(
false);
02418
02419
SyntaxModeList modeList = syntax->modeList();
02420
for (uint i=0; i < modeList.
count(); i++)
02421 {
02422 Highlight *hl =
new Highlight(modeList.
at(i));
02423
02424 uint
insert = 0;
02425
for (;
insert <= hlList.
count();
insert++)
02426 {
02427
if (
insert == hlList.
count())
02428
break;
02429
02430
if (
QString(hlList.at(insert)->section() + hlList.at(insert)->name()).lower()
02431 >
QString(hl->section() + hl->name()).lower() )
02432
break;
02433 }
02434
02435 hlList.insert (insert, hl);
02436 hlDict.insert (hl->name(), hl);
02437 }
02438
02439
02440 Highlight *hl =
new Highlight(0);
02441 hlList.prepend (hl);
02442 hlDict.insert (hl->name(), hl);
02443 }
02444
02445 HlManager::~HlManager()
02446 {
02447
delete syntax;
02448 }
02449
02450
static KStaticDeleter<HlManager> sdHlMan;
02451
02452 HlManager *HlManager::self()
02453 {
02454
if ( !s_self )
02455 sdHlMan.setObject(s_self,
new HlManager ());
02456
02457
return s_self;
02458 }
02459
02460 Highlight *HlManager::getHl(
int n)
02461 {
02462
if (n < 0 || n >= (
int) hlList.count())
02463 n = 0;
02464
02465
return hlList.at(n);
02466 }
02467
02468
int HlManager::nameFind(
const QString &name)
02469 {
02470
int z (hlList.count() - 1);
02471
for (; z > 0; z--)
02472
if (hlList.at(z)->name() ==
name)
02473
return z;
02474
02475
return z;
02476 }
02477
02478
int HlManager::detectHighlighting (KateDocument *doc)
02479 {
02480
int hl = wildcardFind( doc->url().filename() );
02481
02482
if (hl == -1)
02483 {
02484
QByteArray buf (KATE_HL_HOWMANY);
02485 uint bufpos = 0;
02486
for (uint i=0; i < doc->numLines(); i++)
02487 {
02488
QString line = doc->textLine( i );
02489 uint len = line.
length() + 1;
02490
02491
if (bufpos + len > KATE_HL_HOWMANY)
02492 len = KATE_HL_HOWMANY - bufpos;
02493
02494 memcpy(&buf[bufpos], (line +
"\n").latin1(), len);
02495
02496 bufpos += len;
02497
02498
if (bufpos >= KATE_HL_HOWMANY)
02499
break;
02500 }
02501 buf.resize( bufpos );
02502
02503 hl = mimeFind (buf);
02504 }
02505
02506
return hl;
02507 }
02508
02509
int HlManager::wildcardFind(
const QString &fileName)
02510 {
02511
int result = -1;
02512
if ((result = realWildcardFind(fileName)) != -1)
02513
return result;
02514
02515
int length = fileName.
length();
02516
QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
02517
if (fileName.
endsWith(backupSuffix)) {
02518
if ((result = realWildcardFind(fileName.
left(length - backupSuffix.
length()))) != -1)
02519
return result;
02520 }
02521
02522
for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
02523
if (*it != backupSuffix && fileName.
endsWith(*it)) {
02524
if ((result = realWildcardFind(fileName.
left(length - (*it).length()))) != -1)
02525
return result;
02526 }
02527 }
02528
02529
return -1;
02530 }
02531
02532
int HlManager::realWildcardFind(
const QString &fileName)
02533 {
02534
static QRegExp sep(
"\\s*;\\s*");
02535
02536
QPtrList<Highlight> highlights;
02537
02538
for (Highlight *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
02539 highlight->loadWildcards();
02540
02541
for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
02542
if (fileName.
endsWith((*it)))
02543 highlights.
append(highlight);
02544
02545
for (
int i = 0; i < (
int)highlight->getRegexpExtensions().count(); i++) {
02546
QRegExp re = highlight->getRegexpExtensions()[i];
02547
if (re.
exactMatch(fileName))
02548 highlights.
append(highlight);
02549 }
02550 }
02551
02552
if ( !highlights.
isEmpty() )
02553 {
02554
int pri = -1;
02555
int hl = -1;
02556
02557
for (Highlight *highlight = highlights.
first(); highlight != 0L; highlight = highlights.
next())
02558 {
02559
if (highlight->priority() > pri)
02560 {
02561 pri = highlight->priority();
02562 hl = hlList.findRef (highlight);
02563 }
02564 }
02565
02566
return hl;
02567 }
02568
02569
return -1;
02570 }
02571
02572
int HlManager::mimeFind(
const QByteArray &contents)
02573 {
02574
static QRegExp sep(
"\\s*;\\s*");
02575
02576
int accuracy = 0;
02577
KMimeType::Ptr mt =
KMimeType::findByContent( contents, &accuracy );
02578
02579
QPtrList<Highlight> highlights;
02580
02581
for (Highlight *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
02582 {
02583
QStringList l =
QStringList::split( sep, highlight->getMimetypes() );
02584
02585
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
02586 {
02587
if ( *it == mt->name() )
02588 highlights.
append (highlight);
02589 }
02590 }
02591
02592
if ( !highlights.
isEmpty() )
02593 {
02594
int pri = -1;
02595
int hl = -1;
02596
02597
for (Highlight *highlight = highlights.
first(); highlight != 0L; highlight = highlights.
next())
02598 {
02599
if (highlight->priority() > pri)
02600 {
02601 pri = highlight->priority();
02602 hl = hlList.findRef (highlight);
02603 }
02604 }
02605
02606
return hl;
02607 }
02608
02609
return -1;
02610 }
02611
02612 uint HlManager::defaultStyles()
02613 {
02614
return 10;
02615 }
02616
02617
QString HlManager::defaultStyleName(
int n)
02618 {
02619
static QStringList names;
02620
02621
if (names.isEmpty())
02622 {
02623 names << i18n(
"Normal");
02624 names << i18n(
"Keyword");
02625 names << i18n(
"Data Type");
02626 names << i18n(
"Decimal/Value");
02627 names << i18n(
"Base-N Integer");
02628 names << i18n(
"Floating Point");
02629 names << i18n(
"Character");
02630 names << i18n(
"String");
02631 names << i18n(
"Comment");
02632 names << i18n(
"Others");
02633 }
02634
02635
return names[n];
02636 }
02637
02638
void HlManager::getDefaults(uint schema,
KateAttributeList &list)
02639 {
02640 list.
setAutoDelete(
true);
02641
02642
KateAttribute* normal =
new KateAttribute();
02643 normal->
setTextColor(Qt::black);
02644 normal->
setSelectedTextColor(Qt::white);
02645 list.
append(normal);
02646
02647
KateAttribute* keyword =
new KateAttribute();
02648 keyword->
setTextColor(Qt::black);
02649 keyword->
setSelectedTextColor(Qt::white);
02650 keyword->
setBold(
true);
02651 list.
append(keyword);
02652
02653
KateAttribute* dataType =
new KateAttribute();
02654 dataType->
setTextColor(Qt::darkRed);
02655 dataType->
setSelectedTextColor(Qt::white);
02656 list.
append(dataType);
02657
02658
KateAttribute* decimal =
new KateAttribute();
02659 decimal->
setTextColor(Qt::blue);
02660 decimal->
setSelectedTextColor(Qt::cyan);
02661 list.
append(decimal);
02662
02663
KateAttribute* basen =
new KateAttribute();
02664 basen->
setTextColor(Qt::darkCyan);
02665 basen->
setSelectedTextColor(Qt::cyan);
02666 list.
append(basen);
02667
02668
KateAttribute* floatAttribute =
new KateAttribute();
02669 floatAttribute->
setTextColor(Qt::darkMagenta);
02670 floatAttribute->
setSelectedTextColor(Qt::cyan);
02671 list.
append(floatAttribute);
02672
02673
KateAttribute* charAttribute =
new KateAttribute();
02674 charAttribute->
setTextColor(Qt::magenta);
02675 charAttribute->
setSelectedTextColor(Qt::magenta);
02676 list.
append(charAttribute);
02677
02678
KateAttribute* string =
new KateAttribute();
02679 string->
setTextColor(Qt::red);
02680 string->
setSelectedTextColor(Qt::red);
02681 list.
append(string);
02682
02683
KateAttribute* comment =
new KateAttribute();
02684 comment->
setTextColor(Qt::darkGray);
02685 comment->
setSelectedTextColor(Qt::gray);
02686 comment->
setItalic(
true);
02687 list.
append(comment);
02688
02689
KateAttribute* others =
new KateAttribute();
02690 others->
setTextColor(Qt::darkGreen);
02691 others->
setSelectedTextColor(Qt::green);
02692 list.
append(others);
02693
02694
KConfig *config = HlManager::self()->self()->getKConfig();
02695 config->
setGroup(
"Default Item Styles - Schema " + KateFactory::self()->schemaManager()->
name(schema));
02696
02697
for (uint z = 0; z < defaultStyles(); z++)
02698 {
02699
KateAttribute *i = list.
at(z);
02700
QStringList s = config->
readListEntry(defaultStyleName(z));
02701
02702
if (!s.isEmpty())
02703 {
02704
while( s.count()<8)
02705 s <<
"";
02706
02707
QString tmp;
02708 QRgb col;
02709
02710 tmp=s[0];
if (!tmp.
isEmpty()) {
02711 col=tmp.
toUInt(0,16); i->
setTextColor(col); }
02712
02713 tmp=s[1];
if (!tmp.
isEmpty()) {
02714 col=tmp.
toUInt(0,16); i->
setSelectedTextColor(col); }
02715
02716 tmp=s[2];
if (!tmp.
isEmpty()) i->
setBold(tmp!=
"0");
02717
02718 tmp=s[3];
if (!tmp.
isEmpty()) i->
setItalic(tmp!=
"0");
02719
02720 tmp=s[4];
if (!tmp.
isEmpty()) i->
setStrikeOut(tmp!=
"0");
02721
02722 tmp=s[5];
if (!tmp.
isEmpty()) i->
setUnderline(tmp!=
"0");
02723
02724 tmp=s[6];
if (!tmp.
isEmpty()) {
02725 col=tmp.
toUInt(0,16); i->
setBGColor(col); }
02726
02727 tmp=s[7];
if (!tmp.
isEmpty()) {
02728 col=tmp.
toUInt(0,16); i->
setSelectedBGColor(col); }
02729
02730 }
02731
02732 }
02733 }
02734
02735
void HlManager::setDefaults(uint schema,
KateAttributeList &list)
02736 {
02737
KConfig *config = HlManager::self()->self()->getKConfig();
02738 config->
setGroup(
"Default Item Styles - Schema " + KateFactory::self()->schemaManager()->
name(schema));
02739
02740
for (uint z = 0; z < defaultStyles(); z++)
02741 {
02742
QStringList settings;
02743
KateAttribute *i = list.
at(z);
02744
02745 settings<<(i->
itemSet(KateAttribute::TextColor)?
QString::number(i->
textColor().
rgb(),16):
"");
02746 settings<<(i->
itemSet(KateAttribute::SelectedTextColor)?
QString::number(i->
selectedTextColor().
rgb(),16):
"");
02747 settings<<(i->
itemSet(KateAttribute::Weight)?(i->
bold()?
"1":
"0"):
"");
02748 settings<<(i->
itemSet(KateAttribute::Italic)?(i->
italic()?
"1":
"0"):
"");
02749 settings<<(i->
itemSet(KateAttribute::StrikeOut)?(i->
strikeOut()?
"1":
"0"):
"");
02750 settings<<(i->
itemSet(KateAttribute::Underline)?(i->
underline()?
"1":
"0"):
"");
02751 settings<<(i->
itemSet(KateAttribute::BGColor)?
QString::number(i->
bgColor().
rgb(),16):
"");
02752 settings<<(i->
itemSet(KateAttribute::SelectedBGColor)?
QString::number(i->
selectedBGColor().
rgb(),16):
"");
02753 settings<<
"---";
02754
02755 config->
writeEntry(defaultStyleName(z),settings);
02756 }
02757
02758 emit changed();
02759 }
02760
02761
int HlManager::highlights()
02762 {
02763
return (
int) hlList.count();
02764 }
02765
02766
QString HlManager::hlName(
int n)
02767 {
02768
return hlList.at(n)->name();
02769 }
02770
02771
QString HlManager::hlSection(
int n)
02772 {
02773
return hlList.at(n)->section();
02774 }
02775
02776
QString HlManager::identifierForName(
const QString& name)
02777 {
02778 Highlight *hl = 0;
02779
02780
if ((hl = hlDict[
name]))
02781
return hl->getIdentifier ();
02782
02783
return QString();
02784 }
02785
02786
02787
void KateViewHighlightAction::init()
02788 {
02789 m_doc = 0;
02790 subMenus.setAutoDelete(
true );
02791
02792 connect(popupMenu(),SIGNAL(aboutToShow()),
this,SLOT(slotAboutToShow()));
02793 }
02794
02795
void KateViewHighlightAction::updateMenu (
Kate::Document *doc)
02796 {
02797 m_doc = doc;
02798 }
02799
02800
void KateViewHighlightAction::slotAboutToShow()
02801 {
02802
Kate::Document *doc=m_doc;
02803
int count = HlManager::self()->highlights();
02804
02805
for (
int z=0; z<count; z++)
02806 {
02807
QString hlName = HlManager::self()->hlName (z);
02808
QString hlSection = HlManager::self()->hlSection (z);
02809
02810
if ( !hlSection.
isEmpty() && (names.contains(hlName) < 1) )
02811 {
02812
if (subMenusName.contains(hlSection) < 1)
02813 {
02814 subMenusName << hlSection;
02815
QPopupMenu *menu =
new QPopupMenu ();
02816 subMenus.append(menu);
02817 popupMenu()->insertItem (hlSection, menu);
02818 }
02819
02820
int m = subMenusName.findIndex (hlSection);
02821 names << hlName;
02822 subMenus.
at(m)->insertItem ( hlName,
this, SLOT(setHl(
int)), 0, z);
02823 }
02824
else if (names.contains(hlName) < 1)
02825 {
02826 names << hlName;
02827 popupMenu()->insertItem ( hlName,
this, SLOT(setHl(
int)), 0, z);
02828 }
02829 }
02830
02831
if (!doc)
return;
02832
02833
for (uint i=0;i<subMenus.count();i++)
02834 {
02835
for (uint i2=0;i2<subMenus.at(i)->count();i2++)
02836 subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),
false);
02837 }
02838 popupMenu()->setItemChecked (0,
false);
02839
02840
int i = subMenusName.findIndex (HlManager::self()->hlSection(doc->hlMode()));
02841
if (i >= 0 && subMenus.at(i))
02842 subMenus.at(i)->setItemChecked (doc->hlMode(),
true);
02843
else
02844 popupMenu()->setItemChecked (0,
true);
02845 }
02846
02847
void KateViewHighlightAction::setHl (
int mode)
02848 {
02849
Kate::Document *doc=m_doc;
02850
02851
if (doc)
02852 doc->setHlMode((uint)mode);
02853 }
02854
02855