21 #include "kateautoindent.h" 22 #include "kateautoindent.moc" 24 #include "kateconfig.h" 25 #include "katehighlight.h" 26 #include "katefactory.h" 27 #include "katejscript.h" 32 #include <tdepopupmenu.h> 40 if (mode == KateDocumentConfig::imNormal)
42 else if (mode == KateDocumentConfig::imCStyle)
43 return new KateCSmartIndent (doc);
44 else if (mode == KateDocumentConfig::imPythonStyle)
45 return new KatePythonIndent (doc);
46 else if (mode == KateDocumentConfig::imXmlStyle)
47 return new KateXmlIndent (doc);
48 else if (mode == KateDocumentConfig::imCSAndS)
49 return new KateCSAndSIndent (doc);
50 else if ( mode == KateDocumentConfig::imVarIndent )
76 if (mode == KateDocumentConfig::imNormal)
77 return TQString (
"normal");
78 else if (mode == KateDocumentConfig::imCStyle)
79 return TQString (
"cstyle");
80 else if (mode == KateDocumentConfig::imPythonStyle)
81 return TQString (
"python");
82 else if (mode == KateDocumentConfig::imXmlStyle)
83 return TQString (
"xml");
84 else if (mode == KateDocumentConfig::imCSAndS)
85 return TQString (
"csands");
86 else if ( mode == KateDocumentConfig::imVarIndent )
87 return TQString(
"varindent" );
91 return TQString (
"none");
96 if (mode == KateDocumentConfig::imNormal)
97 return i18n (
"Normal");
98 else if (mode == KateDocumentConfig::imCStyle)
99 return i18n (
"C Style");
100 else if (mode == KateDocumentConfig::imPythonStyle)
101 return i18n (
"Python Style");
102 else if (mode == KateDocumentConfig::imXmlStyle)
103 return i18n (
"XML Style");
104 else if (mode == KateDocumentConfig::imCSAndS)
105 return i18n (
"S&S C Style");
106 else if ( mode == KateDocumentConfig::imVarIndent )
107 return i18n(
"Variable Based Indenter");
111 return i18n (
"None");
116 if (
modeName(KateDocumentConfig::imNormal) == name)
117 return KateDocumentConfig::imNormal;
118 else if (
modeName(KateDocumentConfig::imCStyle) == name)
119 return KateDocumentConfig::imCStyle;
120 else if (
modeName(KateDocumentConfig::imPythonStyle) == name)
121 return KateDocumentConfig::imPythonStyle;
122 else if (
modeName(KateDocumentConfig::imXmlStyle) == name)
123 return KateDocumentConfig::imXmlStyle;
124 else if (
modeName(KateDocumentConfig::imCSAndS) == name)
125 return KateDocumentConfig::imCSAndS;
126 else if (
modeName( KateDocumentConfig::imVarIndent ) == name )
127 return KateDocumentConfig::imVarIndent;
131 return KateDocumentConfig::imNone;
151 : TQObject(), doc(_doc)
161 KateViewIndentationAction::KateViewIndentationAction(KateDocument *_doc,
const TQString& text, TQObject* parent,
const char* name)
164 connect(popupMenu(),TQ_SIGNAL(aboutToShow()),
this,TQ_SLOT(slotAboutToShow()));
167 void KateViewIndentationAction::slotAboutToShow()
171 popupMenu()->clear ();
172 for (uint z=0; z<modes.size(); ++z)
175 popupMenu()->setItemChecked (doc->config()->indentationMode(),
true);
178 void KateViewIndentationAction::setMode (
int mode)
180 doc->config()->setIndentationMode((uint)mode);
190 connect(_doc, TQ_SIGNAL(hlChanged()),
this, TQ_SLOT(
updateConfig()));
199 KateDocumentConfig *config = doc->config();
201 useSpaces = config->configFlags() & KateDocument::cfSpaceIndent || config->configFlags() & KateDocumentConfig::cfReplaceTabsDyn;
203 keepProfile = config->configFlags() & KateDocument::cfKeepIndentProfile;
208 doxyCommentAttrib = 255;
216 extensionAttrib = 255;
217 preprocessorAttrib = 255;
221 KateHlItemDataList items;
222 doc->highlight()->getKateHlItemDataListCopy (0, items);
224 for (uint i=0; i<items.count(); i++)
226 TQString name = items.at(i)->name;
227 if (name.find(
"Comment") != -1 && commentAttrib == 255)
231 else if (name.find(
"Region Marker") != -1 && regionAttrib == 255)
235 else if (name.find(
"Symbol") != -1 && symbolAttrib == 255)
239 else if (name.find(
"Alert") != -1)
243 else if (name.find(
"Comment") != -1 && commentAttrib != 255 && doxyCommentAttrib == 255)
245 doxyCommentAttrib = i;
247 else if (name.find(
"Tags") != -1 && tagAttrib == 255)
251 else if (name.find(
"Word") != -1 && wordAttrib == 255)
255 else if (name.find(
"Keyword") != -1 && keywordAttrib == 255)
259 else if (name.find(
"Normal") != -1 && normalAttrib == 255)
263 else if (name.find(
"Extensions") != -1 && extensionAttrib == 255)
267 else if (name.find(
"Preprocessor") != -1 && preprocessorAttrib == 255)
269 preprocessorAttrib = i;
271 else if (name.find(
"String") != -1 && stringAttrib == 255)
275 else if (name.find(
"Char") != -1 && charAttrib == 255)
285 bool atLeastOne =
false;
286 bool getNext =
false;
288 pos = doc->plainKateTextLine(begin.line())->firstChar();
294 TQChar c = begin.currentChar();
295 if (begin.currentAttrib() == symbolAttrib)
312 else if (getNext && !c.isSpace())
318 if (atLeastOne && parenOpen <= 0)
321 if (!begin.moveForward(1))
325 return (atLeastOne) ? false :
true;
330 int curLine = cur.line();
339 uchar attrib = cur.currentAttrib();
340 const TQString hlFile = doc->highlight()->hlKeyForAttrib( attrib );
342 if (attrib != commentAttrib && attrib != regionAttrib && attrib != alertAttrib && attrib != preprocessorAttrib && !hlFile.endsWith(
"doxygen.xml"))
344 TQChar c = cur.currentChar();
345 if (!c.isNull() && !c.isSpace())
349 if (!cur.moveForward(1))
356 if (curLine != cur.line())
360 curLine = cur.line();
375 return doc->plainKateTextLine(cur.line())->cursorX(cur.col(),
tabWidth);
381 pos = kMin (pos, 80U);
401 int line = begin.line() - 1;
402 int pos = begin.col();
404 while ((line > 0) && (pos < 0))
405 pos = doc->plainKateTextLine(--line)->firstChar();
409 TQString filler = doc->text(line, 0, line, pos);
410 doc->insertText(begin.line(), 0, filler);
411 begin.setCol(filler.length());
421 KateCSmartIndent::KateCSmartIndent (KateDocument *doc)
424 processingBlock (
false)
426 kdDebug(13030)<<
"CREATING KATECSMART INTDETER"<<
endl;
429 KateCSmartIndent::~KateCSmartIndent ()
436 kdDebug(13030)<<
"PROCESSING LINE "<<line.line()<<
endl;
439 int firstChar = textLine->firstChar();
441 if (firstChar == -1 && processingBlock)
447 TQChar first = textLine->getChar(firstChar);
448 TQChar last = textLine->getChar(textLine->lastChar());
452 indent = findOpeningBrace(line);
454 else if (first ==
')')
456 indent = findOpeningParen(line);
458 else if (first ==
'{')
462 if (!firstOpeningBrace(temp))
463 indent = calcIndent(temp,
false);
465 else if (first ==
':')
468 int pos = findOpeningBrace(line);
474 else if (last ==
':')
476 if (textLine->stringAtPos (firstChar,
"case") ||
477 textLine->stringAtPos (firstChar,
"default") ||
478 textLine->stringAtPos (firstChar,
"public") ||
479 textLine->stringAtPos (firstChar,
"private") ||
480 textLine->stringAtPos (firstChar,
"protected") ||
481 textLine->stringAtPos (firstChar,
"signals") ||
482 textLine->stringAtPos (firstChar,
"slots"))
487 else if (first ==
'*')
491 int lineEnd = textLine->lastChar();
492 if (lineEnd > 0 && textLine->getChar(lineEnd - 1) ==
'*')
494 indent = findOpeningComment(line);
495 if (textLine->attribute(firstChar) == doxyCommentAttrib)
504 if (textLine->attribute(firstChar) == doxyCommentAttrib)
505 indent = calcIndent(temp,
false) + 1;
507 indent = calcIndent(temp,
true);
510 else if (first ==
'#')
513 if (textLine->stringAtPos (firstChar,
"#region") ||
514 textLine->stringAtPos (firstChar,
"#endregion"))
517 indent = calcIndent(temp,
true);
523 if (first ==
'/' && last !=
'/')
527 indent = calcIndent(temp,
true);
536 if (indent !=
measureIndent(line) || first ==
'}' || first ==
'{' || first ==
'#')
538 doc->removeText(line.line(), 0, line.line(), firstChar);
540 if (indent > 0) doc->insertText(line.line(), 0, filler);
541 if (!processingBlock) line.setCol(filler.length());
552 processingBlock = (end.line() - cur.line() > 0) ?
true :
false;
554 while (cur.line() <= end.line())
557 if (!cur.gotoNextLine())
561 processingBlock =
false;
562 kdDebug(13030) <<
"+++ total: " << t.elapsed() <<
endl;
568 int line = begin.line();
570 while ((line > 0) && (first < 0))
571 first = doc->plainKateTextLine(--line)->firstChar();
576 bool insideDoxygen =
false;
577 bool justAfterDoxygen =
false;
578 if (textLine->attribute(first) == doxyCommentAttrib || textLine->attribute(textLine->lastChar()) == doxyCommentAttrib)
580 const int last = textLine->lastChar();
581 if (last <= 0 || !(justAfterDoxygen = textLine->stringAtPos(last-1,
"*/")))
582 insideDoxygen =
true;
583 if (justAfterDoxygen)
584 justAfterDoxygen &= textLine->string().find(
"/**") < 0;
585 while (textLine->attribute(first) != doxyCommentAttrib && first <= textLine->lastChar())
587 if (textLine->stringAtPos(first,
"//"))
594 textLine = doc->plainKateTextLine(begin.line());
595 first = textLine->firstChar();
596 int indent = findOpeningComment(begin);
599 bool doxygenAutoInsert = doc->config()->configFlags() & KateDocumentConfig::cfDoxygenAutoTyping;
601 if ( doxygenAutoInsert &&
602 ((first < 0) || (!textLine->stringAtPos(first,
"*/") && !textLine->stringAtPos(first,
"*"))))
604 filler = filler +
" * ";
607 doc->removeText (begin.line(), 0, begin.line(), first);
608 doc->insertText (begin.line(), 0, filler);
609 begin.setCol(filler.length());
615 else if (justAfterDoxygen)
617 textLine = doc->plainKateTextLine(begin.line());
618 first = textLine->firstChar();
619 int indent = findOpeningComment(begin);
622 doc->removeText (begin.line(), 0, begin.line(), first);
623 doc->insertText (begin.line(), 0, filler);
624 begin.setCol(filler.length());
633 void KateCSmartIndent::processNewline (
KateDocCursor &begin,
bool needContinue)
635 if (!handleDoxygen (begin))
638 bool inMiddle = textLine->firstChar() > -1;
640 int indent = calcIndent (begin, needContinue);
642 if (indent > 0 || inMiddle)
645 doc->insertText (begin.line(), 0, filler);
646 begin.setCol(filler.length());
652 begin.setCol(textLine->firstChar());
675 uchar attr1, uchar attr2,
676 TQChar prev1, TQChar prev2)
678 return attr1 == indenter.preprocessorAttrib
681 || attr1 == indenter.commentAttrib
682 || attr1 == indenter.doxyCommentAttrib
683 || attr1 == indenter.stringAttrib && (attr2 != indenter.stringAttrib
684 || (prev1 !=
'"' || prev2 ==
'\\' && attr2 == indenter.charAttrib))
685 || prev1 ==
'\'' && attr1 != indenter.charAttrib;
699 const TQString txt = line->string(0,curCol);
701 for (
int pos = 0; (pos = txt.find(
':', pos)) >= 0; pos++) {
702 if (line->attribute(pos) == indenter.symbolAttrib)
710 return !isColonImmune(indenter, line->attribute(curCol - 1),
711 line->attribute(curCol - 2),
712 txt[curCol - 1], txt[curCol - 2]);
715 void KateCSmartIndent::processChar(TQChar c)
720 static const TQString triggers(
"}{)/:#n");
721 static const TQString firstTriggers(
"}{)/:#");
722 static const TQString lastTriggers(
":n");
723 if (triggers.find(c) < 0)
726 KateView *view = doc->activeView();
727 int curCol = view->cursorColumnReal() - 1;
731 const TQChar curChar = textLine->getChar(curCol);
732 const int first = textLine->firstChar();
733 const TQChar firstChar = textLine->getChar(first);
738 kdDebug() <<
"curChar " << curChar <<
" curCol " << curCol <<
" textlen " << textLine->length() <<
" a " << textLine->attribute( curCol ) <<
" sym " << symbolAttrib <<
" pp " << preprocessorAttrib <<
endl;
739 if (!(((curChar ==
'#' || curChar ==
'n')
740 && textLine->attribute( curCol ) == preprocessorAttrib)
741 || textLine->attribute( curCol ) == symbolAttrib)
749 if (firstChar !=
'#' || textLine->string(curCol-5, 5) != TQString::fromLatin1(
"regio"))
756 if ( textLine->attribute( begin.col() ) == doxyCommentAttrib )
762 && textLine->nextNonSpaceChar( first+1 ) == view->cursorColumnReal()-1 )
763 doc->removeText( view->cursorLine(), first+1, view->cursorLine(), view->cursorColumnReal()-1);
774 const TQChar lastChar = textLine->getChar(textLine->lastChar());
776 if (((c == firstChar && firstTriggers.find(firstChar) >= 0)
777 || (c == lastChar && lastTriggers.find(lastChar) >= 0))
778 && (c !=
':' || colonPermitsReindent(*
this, textLine, curCol)))
783 uint KateCSmartIndent::calcIndent(
KateDocCursor &begin,
bool needContinue)
788 uint anchorIndent = 0;
792 bool isSpecial =
false;
793 bool potentialAnchorSeen =
false;
795 bool parenthesizedArg =
false;
800 while (cur.gotoPreviousLine())
802 isSpecial = found =
false;
803 textLine = doc->plainKateTextLine(cur.line());
806 int pos = textLine->lastChar();
808 int otherAnchor = -1;
811 if (textLine->attribute(pos) == symbolAttrib)
813 TQChar tc = textLine->getChar (pos);
814 if ((tc ==
';' || tc ==
':' || tc ==
',') && otherAnchor == -1 && parenCount <= 0) {
815 otherAnchor = pos, potentialAnchorSeen =
true;
817 }
else if (tc ==
')')
820 parenCount--, parenthesizedArg = isArg, potentialAnchorSeen =
true;
825 openCount++, potentialAnchorSeen =
true;
830 }
while (--pos >= textLine->firstChar());
832 if (openCount != 0 || otherAnchor != -1)
838 else if (openCount < 0)
840 else if (otherAnchor >= 0)
841 c = textLine->getChar (otherAnchor);
843 int specialIndent = 0;
844 if (c ==
':' && needContinue)
847 specialIndent = textLine->firstChar();
848 if (textLine->stringAtPos(specialIndent,
"case"))
849 ch = textLine->getChar(specialIndent + 4);
850 else if (textLine->stringAtPos(specialIndent,
"default"))
851 ch = textLine->getChar(specialIndent + 7);
852 else if (textLine->stringAtPos(specialIndent,
"public"))
853 ch = textLine->getChar(specialIndent + 6);
854 else if (textLine->stringAtPos(specialIndent,
"private"))
855 ch = textLine->getChar(specialIndent + 7);
856 else if (textLine->stringAtPos(specialIndent,
"protected"))
857 ch = textLine->getChar(specialIndent + 9);
858 else if (textLine->stringAtPos(specialIndent,
"signals"))
859 ch = textLine->getChar(specialIndent + 7);
860 else if (textLine->stringAtPos(specialIndent,
"slots"))
861 ch = textLine->getChar(specialIndent + 5);
863 if (ch.isNull() || (!ch.isSpace() && ch !=
'(' && ch !=
':'))
867 lineBegin.setCol(specialIndent);
874 skip.setCol(textLine->lastChar());
877 anchorPos = skip.col();
883 if (result && skip < begin)
890 anchorIndent = specialIndent;
895 if ((c ==
'{' || c ==
'}') && textLine->getChar(textLine->firstChar()) == c)
897 cur.setCol(anchorPos = textLine->firstChar());
905 if (cur.line() == 0 && cur.col() == 0 && potentialAnchorSeen)
911 uint continueIndent = (needContinue) ? calcContinue (cur, begin) : 0;
916 textLine = doc->plainKateTextLine(cur.line());
917 TQChar lastChar = textLine->getChar (anchorPos);
918 int lastLine = cur.line();
919 if (lastChar ==
'#' || lastChar ==
'[')
927 while (cur.validPosition() && cur < begin)
930 return isArg && !parenthesizedArg ? begin.col() : 0;
932 TQChar tc = cur.currentChar();
934 if (cur == begin || tc.isNull())
937 if (!tc.isSpace() && cur < begin)
939 uchar attrib = cur.currentAttrib();
940 if (tc ==
'{' && attrib == symbolAttrib)
942 else if (tc ==
'}' && attrib == symbolAttrib)
946 lastLine = cur.line();
955 if (lastChar ==
'{' || (lastChar ==
':' && isSpecial && needContinue))
959 else if (lastChar ==
'}')
961 indent = anchorIndent;
963 else if (lastChar ==
';')
965 indent = anchorIndent + ((allowSemi && needContinue) ? continueIndent : 0);
967 else if (lastChar ==
',' || lastChar ==
'(')
969 textLine = doc->plainKateTextLine(lastLine);
971 KateDocCursor finish(lastLine, textLine->lastChar() + 1, doc);
974 if (
isBalanced(start, finish, TQChar(
'('), TQChar(
')'), pos) &&
false)
975 indent = anchorIndent;
979 indent = ((pos < 48) ? pos : anchorIndent + (
indentWidth * 2));
982 else if (!lastChar.isNull())
984 if (anchorIndent != 0)
985 indent = anchorIndent + continueIndent;
987 indent = continueIndent;
997 bool needsBalanced =
true;
1004 if (textLine->attribute(cur.col()) == symbolAttrib)
1010 if (textLine->getChar(cur.col()) ==
'}')
1013 if (cur.line() != start.line())
1014 textLine = doc->plainKateTextLine(cur.line());
1016 if (textLine->stringAtPos(cur.col(),
"else"))
1017 cur.setCol(cur.col() + 4);
1021 needsBalanced =
false;
1023 else if (textLine->stringAtPos(cur.col(),
"else"))
1025 cur.setCol(cur.col() + 4);
1026 needsBalanced =
false;
1027 int next = textLine->nextNonSpaceChar(cur.col());
1028 if (next >= 0 && textLine->stringAtPos(next,
"if"))
1030 cur.setCol(next + 2);
1031 needsBalanced =
true;
1034 else if (textLine->stringAtPos(cur.col(),
"if"))
1036 cur.setCol(cur.col() + 2);
1038 else if (textLine->stringAtPos(cur.col(),
"do"))
1040 cur.setCol(cur.col() + 2);
1041 needsBalanced =
false;
1043 else if (textLine->stringAtPos(cur.col(),
"for"))
1045 cur.setCol(cur.col() + 3);
1048 else if (textLine->stringAtPos(cur.col(),
"while"))
1050 cur.setCol(cur.col() + 5);
1052 else if (textLine->stringAtPos(cur.col(),
"switch"))
1054 cur.setCol(cur.col() + 6);
1056 else if (textLine->stringAtPos(cur.col(),
"using"))
1058 cur.setCol(cur.col() + 5);
1066 if (needsBalanced && !
isBalanced (cur, end, TQChar(
'('), TQChar(
')'), openPos))
1070 return (openPos - textLine->firstChar());
1091 uint KateCSmartIndent::findOpeningBrace(
KateDocCursor &start)
1098 while (cur.moveBackward(1))
1100 if (cur.currentAttrib() == symbolAttrib)
1102 TQChar ch = cur.currentChar();
1110 KateDocCursor temp(cur.line(), doc->plainKateTextLine(cur.line())->firstChar(), doc);
1119 bool KateCSmartIndent::firstOpeningBrace(
KateDocCursor &start)
1124 while(cur.moveBackward(1))
1126 if (cur.currentAttrib() == symbolAttrib)
1128 TQChar ch = cur.currentChar();
1131 else if (ch ==
'}' && cur.col() == 0)
1139 uint KateCSmartIndent::findOpeningParen(
KateDocCursor &start)
1146 while (cur.moveBackward(1))
1148 if (cur.currentAttrib() == symbolAttrib)
1150 TQChar ch = cur.currentChar();
1164 uint KateCSmartIndent::findOpeningComment(
KateDocCursor &start)
1173 int pos = textLine->string().find(
"/*",
false);
1180 }
while (cur.gotoPreviousLine());
1189 TQRegExp KatePythonIndent::endWithColon = TQRegExp(
"^[^#]*:\\s*(#.*)?$" );
1190 TQRegExp KatePythonIndent::stopStmt = TQRegExp(
"^\\s*(break|continue|raise|return|pass)\\b.*" );
1191 TQRegExp KatePythonIndent::blockBegin = TQRegExp(
"^\\s*(class|def|if|elif|else|for|while|try)\\b.*" );
1193 KatePythonIndent::KatePythonIndent (KateDocument *doc)
1197 KatePythonIndent::~KatePythonIndent ()
1201 void KatePythonIndent::processNewline (
KateDocCursor &begin,
bool )
1203 int prevLine = begin.line() - 1;
1204 int prevPos = begin.col();
1206 while ((prevLine > 0) && (prevPos < 0))
1207 prevPos = doc->plainKateTextLine(--prevLine)->firstChar();
1209 int prevBlock = prevLine;
1210 int prevBlockPos = prevPos;
1211 int extraIndent = calcExtra (prevBlock, prevBlockPos, begin);
1213 int indent = doc->plainKateTextLine(prevBlock)->cursorX(prevBlockPos,
tabWidth);
1214 if (extraIndent == 0)
1216 if (!stopStmt.exactMatch(doc->plainKateTextLine(prevLine)->string()))
1218 if (endWithColon.exactMatch(doc->plainKateTextLine(prevLine)->string()))
1221 indent = doc->plainKateTextLine(prevLine)->cursorX(prevPos,
tabWidth);
1225 indent += extraIndent;
1230 doc->insertText (begin.line(), 0, filler);
1231 begin.setCol(filler.length());
1237 int KatePythonIndent::calcExtra (
int &prevBlock,
int &pos,
KateDocCursor &end)
1240 bool levelFound =
false;
1241 while ((prevBlock > 0))
1243 if (blockBegin.exactMatch(doc->plainKateTextLine(prevBlock)->string()))
1245 if ((!levelFound && nestLevel == 0) || (levelFound && nestLevel - 1 <= 0))
1247 pos = doc->plainKateTextLine(prevBlock)->firstChar();
1253 else if (stopStmt.exactMatch(doc->plainKateTextLine(prevBlock)->string()))
1264 int extraIndent = 0;
1265 while (cur.line() < end.line())
1267 c = cur.currentChar();
1275 else if (c ==
'\'' || c ==
'"' )
1276 traverseString( c, cur, end );
1278 if (c.isNull() || c ==
'#')
1290 bool escape =
false;
1293 c = cur.currentChar();
1294 while ( ( c != stringChar || escape ) && cur.line() < end.line() )
1298 else if ( c ==
'\\' )
1302 c = cur.currentChar();
1332 const TQRegExp KateXmlIndent::startsWithCloseTag(
"^[ \t]*</");
1333 const TQRegExp KateXmlIndent::unclosedDoctype(
"<!DOCTYPE[^>]*$");
1335 KateXmlIndent::KateXmlIndent (KateDocument *doc)
1340 KateXmlIndent::~KateXmlIndent ()
1344 void KateXmlIndent::processNewline (
KateDocCursor &begin,
bool )
1349 void KateXmlIndent::processChar (TQChar c)
1351 if(c !=
'/')
return;
1354 KateView *view = doc->activeView();
1355 TQString text = doc->plainKateTextLine(view->cursorLine())->
string();
1356 if(text.find(startsWithCloseTag) == -1)
return;
1370 int endLine = end.line();
1374 if(!cur.gotoNextLine())
break;
1375 }
while(cur.line() < endLine);
1378 void KateXmlIndent::getLineInfo (uint line, uint &prevIndent,
int &numTags,
1379 uint &attrCol,
bool &unclosedTag)
1387 prevLine = doc->plainKateTextLine(line);
1388 if( (firstChar = prevLine->firstChar()) < 0) {
1394 prevIndent = prevLine->cursorX(prevLine->firstChar(),
tabWidth);
1395 TQString text = prevLine->string();
1401 if(text.find(startsWithCloseTag) != -1) ++numTags;
1405 uint pos, len = text.length();
1406 bool seenOpen =
false;
1407 for(pos = 0; pos < len; ++pos) {
1408 int ch = text.at(pos).unicode();
1419 if(lastCh ==
'<') --numTags;
1424 if(lastCh ==
'<') --numTags;
1439 for(uint backLine = line; backLine; ) {
1442 if(x->string().find(
'<') == -1)
continue;
1445 if(x->string().find(unclosedDoctype) != -1) --numTags;
1446 getLineInfo(backLine, prevIndent, numTags, attrCol, unclosedTag);
1450 if(lastCh ==
'/') --numTags;
1451 unclosedTag =
false;
1455 if(lastCh ==
'<') numTags -= 2;
1464 lastCh = text.at(++attrCol).unicode();
1465 }
while(lastCh && lastCh !=
' ' && lastCh !=
'\t');
1467 while(lastCh ==
' ' || lastCh ==
'\t') {
1468 lastCh = text.at(++attrCol).unicode();
1471 attrCol = prevLine->cursorX(attrCol,
tabWidth);
1475 uint KateXmlIndent::processLine (uint line)
1478 if(!kateLine)
return 0;
1481 uint prevIndent = 0, attrCol = 0;
1483 bool unclosedTag =
false;
1486 getLineInfo(line - 1, prevIndent, numTags, attrCol, unclosedTag);
1491 if(unclosedTag) indent = attrCol;
1493 if(indent < 0) indent = 0;
1496 if(kateLine->string().find(startsWithCloseTag) != -1) {
1499 if(indent < 0) indent = 0;
1502 doc->removeText(line, 0, line, kateLine->firstChar());
1504 doc->insertText(line, 0, filler);
1506 return filler.length();
1513 KateCSAndSIndent::KateCSAndSIndent (KateDocument *doc)
1518 void KateCSAndSIndent::updateIndentString()
1523 indentString =
'\t';
1526 KateCSAndSIndent::~KateCSAndSIndent ()
1537 updateIndentString();
1539 const int oldCol = line.col();
1540 TQString whitespace = calcIndent(line);
1542 int oldIndent = textLine->firstChar();
1543 if ( oldIndent < 0 )
1544 oldIndent = doc->lineLength( line.line() );
1546 doc->removeText(line.line(), 0, line.line(), oldIndent);
1548 doc->insertText(line.line(), 0, whitespace);
1551 if (
int(oldCol + whitespace.length()) >= oldIndent )
1552 line.setCol( oldCol + whitespace.length() - oldIndent );
1559 TQTime t; t.start();
1563 if (!cur.gotoNextLine())
1566 kdDebug(13030) <<
"+++ total: " << t.elapsed() <<
endl;
1574 static TQString initialWhitespace(
const KateTextLine::Ptr &line,
int chars,
bool convert =
true)
1576 TQString text = line->string(0, chars);
1577 if( (
int)text.length() < chars )
1579 TQString filler; filler.fill(
' ',chars - text.length());
1582 for( uint n = 0; n < text.length(); ++n )
1584 if( text[n] !=
'\t' && text[n] !=
' ' )
1587 return text.left( n );
1594 TQString KateCSAndSIndent::findOpeningCommentIndentation(
const KateDocCursor &start)
1603 int pos = textLine->string().findRev(
"/*");
1606 return initialWhitespace(textLine, pos);
1607 }
while (cur.gotoPreviousLine());
1610 kdWarning( 13030 ) <<
" in a comment, but can't find the start of it" <<
endl;
1611 return TQString::null;
1617 int line = begin.line();
1619 while ((line > 0) && (first < 0))
1620 first = doc->plainKateTextLine(--line)->firstChar();
1632 if ( !(textLine->attribute(textLine->lastChar()) == doxyCommentAttrib && !textLine->endingWith(
"*/")) &&
1633 !(textLine->attribute(textLine->firstChar()) == doxyCommentAttrib && !textLine->string().contains(
"*/")) )
1637 textLine = doc->plainKateTextLine(begin.line());
1638 first = textLine->firstChar();
1639 TQString indent = findOpeningCommentIndentation(begin);
1641 bool doxygenAutoInsert = doc->config()->configFlags() & KateDocumentConfig::cfDoxygenAutoTyping;
1644 if ( first >= 0 && textLine->stringAtPos(first,
"*") )
1645 indent = indent +
" ";
1647 else if ( doxygenAutoInsert )
1648 indent = indent +
" * ";
1653 doc->removeText (begin.line(), 0, begin.line(), first);
1654 doc->insertText (begin.line(), 0, indent);
1655 begin.setCol(indent.length());
1666 void KateCSAndSIndent::processNewline (
KateDocCursor &begin,
bool )
1669 if( handleDoxygen(begin) )
1676 int cursorPos = doc->plainKateTextLine( begin.line() )->firstChar();
1677 if ( cursorPos < 0 )
1678 cursorPos = doc->lineLength( begin.line() );
1679 begin.setCol( cursorPos );
1688 bool KateCSAndSIndent::startsWithLabel(
int line )
1692 const int indentFirst = indentLine->firstChar();
1695 int attrib = indentLine->attribute(indentFirst);
1696 if (attrib != 0 && attrib != keywordAttrib && attrib != normalAttrib && attrib != extensionAttrib)
1700 const TQString lineContents = indentLine->string();
1701 const int indentLast = indentLine->lastChar();
1702 bool whitespaceFound =
false;
1703 for (
int n = indentFirst; n <= indentLast; ++n )
1707 char c = lineContents[n].latin1();
1711 if ( n < lineContents.length() - 1 )
1713 if ( lineContents[n+1].latin1() ==
':' )
1720 if ( n == indentFirst)
1730 if (!whitespaceFound)
1732 if (lineContents.mid(indentFirst, n - indentFirst) ==
"case")
1734 else if (lineContents.mid(indentFirst, n - indentFirst) ==
"class")
1736 whitespaceFound =
true;
1740 else if ( !isalnum(c) && c !=
'_' )
1748 template<
class T> T min(T a, T b) {
return (a < b) ? a : b; }
1750 int KateCSAndSIndent::lastNonCommentChar(
const KateDocCursor &line )
1753 TQString str = textLine->string();
1757 do p = str.find(
"//", p + 2 );
1758 while ( p >= 0 && textLine->attribute(p) != commentAttrib && textLine->attribute(p) != doxyCommentAttrib );
1765 while( p > 0 && str[p-1].isSpace() ) --p;
1769 bool KateCSAndSIndent::inForStatement(
int line )
1773 int parens = 0, semicolons = 0;
1774 for ( ; line >= 0; --line )
1777 const int first = textLine->firstChar();
1778 const int last = textLine->lastChar();
1784 for (
int curr = last; curr >= first; --curr )
1786 if ( textLine->attribute(curr) != symbolAttrib )
1789 switch( textLine->getChar(curr) )
1792 if( ++semicolons > 2 )
1814 bool KateCSAndSIndent::inStatement(
const KateDocCursor &begin )
1819 const int first = textLine->firstChar();
1823 const int attrib = textLine->attribute(first);
1824 if( first >= 0 && (attrib == 0 || attrib == symbolAttrib) && textLine->getChar(first) ==
'{' )
1828 for ( line = begin.line() - 1; line >= 0; --line )
1830 textLine = doc->plainKateTextLine(line);
1831 const int first = textLine->firstChar();
1837 if ( textLine->getChar( first ) ==
'#' )
1840 currLine.setLine( line );
1841 const int last = lastNonCommentChar( currLine );
1850 const int attrib = textLine->attribute(last);
1851 if ( attrib == commentAttrib || attrib == doxyCommentAttrib )
1854 char c = textLine->getChar(last);
1857 if ( attrib == symbolAttrib && c ==
'{' || c ==
'}' )
1861 if ( attrib == symbolAttrib && c ==
';' )
1862 return inForStatement( line );
1865 if ( attrib == symbolAttrib && c ==
':' )
1871 if( startsWithLabel( line ) )
1888 TQString KateCSAndSIndent::continuationIndent(
const KateDocCursor &begin )
1890 if( !inStatement( begin ) )
1891 return TQString::null;
1892 return indentString;
1898 TQString KateCSAndSIndent::calcIndent (
const KateDocCursor &begin)
1901 int currLineFirst = currLine->firstChar();
1906 if ( currLineFirst >= 0 &&
1907 (currLine->attribute(currLineFirst) == commentAttrib ||
1908 currLine->attribute(currLineFirst) == doxyCommentAttrib) )
1909 return currLine->string( 0, currLineFirst );
1912 if( currLineFirst >= 0 && currLine->getChar(currLineFirst) ==
'#' )
1914 if( !currLine->stringAtPos( currLineFirst+1, TQString::fromLatin1(
"region") ) &&
1915 !currLine->stringAtPos( currLineFirst+1, TQString::fromLatin1(
"endregion") ) )
1916 return TQString::null;
1927 int pos, openBraceCount = 0, openParenCount = 0;
1928 bool lookingForScopeKeywords =
true;
1929 const char *
const scopeKeywords[] = {
"for",
"do",
"while",
"if",
"else" };
1930 const char *
const blockScopeKeywords[] = {
"try",
"catch",
"switch" };
1932 while (cur.gotoPreviousLine())
1935 const int lastChar = textLine->lastChar();
1936 const int firstChar = textLine->firstChar();
1939 for( pos = lastChar; pos >= firstChar; --pos )
1941 if (textLine->attribute(pos) == symbolAttrib)
1943 char tc = textLine->getChar (pos);
1947 if( ++openParenCount > 0 )
1948 return calcIndentInBracket( begin, cur, pos );
1950 case ')':
case ']': openParenCount--;
break;
1952 if( ++openBraceCount > 0 )
1953 return calcIndentInBrace( begin, cur, pos );
1955 case '}': openBraceCount--; lookingForScopeKeywords =
false;
break;
1957 if( openParenCount == 0 )
1958 lookingForScopeKeywords =
false;
1965 if ( lookingForScopeKeywords && openParenCount == 0 &&
1966 textLine->attribute(pos) == keywordAttrib &&
1967 (pos == 0 || textLine->attribute(pos-1) != keywordAttrib ) )
1969 #define ARRLEN( array ) ( sizeof(array)/sizeof(array[0]) ) 1970 for( uint n = 0; n < ARRLEN(scopeKeywords); ++n )
1971 if( textLine->stringAtPos(pos, TQString::fromLatin1(scopeKeywords[n]) ) )
1972 return calcIndentAfterKeyword( begin, cur, pos,
false );
1973 for( uint n = 0; n < ARRLEN(blockScopeKeywords); ++n )
1974 if( textLine->stringAtPos(pos, TQString::fromLatin1(blockScopeKeywords[n]) ) )
1975 return calcIndentAfterKeyword( begin, cur, pos,
true );
1982 return TQString::null;
1985 TQString KateCSAndSIndent::calcIndentInBracket(
const KateDocCursor &indentCursor,
const KateDocCursor &bracketCursor,
int bracketPos)
1992 if ( bracketPos > 48 )
2004 return indentString + initialWhitespace( bracketLine, bracketLine->firstChar() );
2007 const int indentLineFirst = indentLine->firstChar();
2010 const int attrib = indentLine->attribute(indentLineFirst);
2011 if( indentLineFirst >= 0 && (attrib == 0 || attrib == symbolAttrib) &&
2012 ( indentLine->getChar(indentLineFirst) ==
')' || indentLine->getChar(indentLineFirst) ==
']' ) )
2015 indentTo = bracketPos;
2020 indentTo = bracketLine->nextNonSpaceChar( bracketPos + 1 );
2021 if( indentTo == -1 )
2022 indentTo = bracketPos + 2;
2024 return initialWhitespace( bracketLine, indentTo );
2027 TQString KateCSAndSIndent::calcIndentAfterKeyword(
const KateDocCursor &indentCursor,
const KateDocCursor &keywordCursor,
int keywordPos,
bool blockKeyword)
2032 TQString whitespaceToKeyword = initialWhitespace( keywordLine, keywordPos,
false );
2033 if( blockKeyword ) {
2038 int first = indentLine->firstChar();
2040 const int attrib = indentLine->attribute(first);
2041 if( first >= 0 && (attrib == 0 || attrib == symbolAttrib) && indentLine->getChar(first) ==
'{' )
2042 return whitespaceToKeyword;
2051 return indentString + whitespaceToKeyword;
2054 TQString KateCSAndSIndent::calcIndentInBrace(
const KateDocCursor &indentCursor,
const KateDocCursor &braceCursor,
int bracePos)
2057 const int braceFirst = braceLine->firstChar();
2059 TQString whitespaceToOpenBrace = initialWhitespace( braceLine, bracePos,
false );
2066 if( braceFirst >= 0 && braceLine->attribute(braceFirst) == keywordAttrib &&
2067 braceLine->stringAtPos( braceFirst, TQString::fromLatin1(
"namespace" ) ) )
2068 return continuationIndent(indentCursor) + whitespaceToOpenBrace;
2070 if( braceCursor.line() > 0 )
2073 int firstPrev = prevLine->firstChar();
2074 if( firstPrev >= 0 && prevLine->attribute(firstPrev) == keywordAttrib &&
2075 prevLine->stringAtPos( firstPrev, TQString::fromLatin1(
"namespace" ) ) )
2076 return continuationIndent(indentCursor) + whitespaceToOpenBrace;
2081 const int indentFirst = indentLine->firstChar();
2084 if( indentFirst >= 0 && indentLine->getChar(indentFirst) ==
'}' )
2085 return whitespaceToOpenBrace;
2089 if ( indentFirst >= 0 && indentLine->attribute(indentFirst) == symbolAttrib &&
2090 indentLine->getChar(indentFirst) ==
':' && indentLine->getChar(indentFirst+1) !=
':' )
2092 return indentString + indentString + whitespaceToOpenBrace;
2095 const bool continuation = inStatement(indentCursor);
2097 if( !continuation && startsWithLabel( indentCursor.line() ) )
2098 return whitespaceToOpenBrace;
2101 TQString continuationIndent = continuation ? indentString : TQString::null;
2102 return indentString + continuationIndent + whitespaceToOpenBrace;
2105 void KateCSAndSIndent::processChar(TQChar c)
2108 static const TQString triggers(
"}{)]/:;#n");
2109 if (triggers.find(c) == -1)
2114 KateView *view = doc->activeView();
2120 int first = textLine->firstChar();
2121 if( first < 0 || textLine->getChar(first) !=
'#' )
2125 if ( textLine->attribute( begin.col() ) == doxyCommentAttrib )
2130 int first = textLine->firstChar();
2134 && textLine->getChar( first ) ==
'*' 2135 && textLine->nextNonSpaceChar( first+1 ) == view->cursorColumnReal()-1 )
2136 doc->removeText( view->cursorLine(), first+1, view->cursorLine(), view->cursorColumnReal()-1);
2149 class KateVarIndentPrivate {
2151 TQRegExp reIndentAfter, reIndent, reUnindent;
2157 KateVarIndent::KateVarIndent( KateDocument *doc )
2160 d =
new KateVarIndentPrivate;
2161 d->reIndentAfter = TQRegExp( doc->variable(
"var-indent-indent-after" ) );
2162 d->reIndent = TQRegExp( doc->variable(
"var-indent-indent" ) );
2163 d->reUnindent = TQRegExp( doc->variable(
"var-indent-unindent" ) );
2164 d->triggers = doc->variable(
"var-indent-triggerchars" );
2165 d->coupleAttrib = 0;
2167 slotVariableChanged(
"var-indent-couple-attribute", doc->variable(
"var-indent-couple-attribute" ) );
2168 slotVariableChanged(
"var-indent-handle-couples", doc->variable(
"var-indent-handle-couples" ) );
2171 connect( doc, TQ_SIGNAL(variableChanged(
const TQString&,
const TQString&) ),
2172 this, TQ_SLOT(slotVariableChanged(
const TQString&,
const TQString& )) );
2175 KateVarIndent::~KateVarIndent()
2191 if ( d->triggers.contains( c ) )
2193 KateTextLine::Ptr ln = doc->plainKateTextLine( doc->activeView()->cursorLine() );
2194 if ( ln->attribute( doc->activeView()->cursorColumn()-1 ) == commentAttrib )
2197 KateView *view = doc->activeView();
2199 kdDebug(13030)<<
"variable indenter: process char '"<<c<<
", line "<<begin.line()<<
endl;
2210 int ln = line.line();
2213 if ( ! ktl )
return;
2216 KateView *v = doc->activeView();
2217 if ( (ktl->firstChar() < 0) && (!v || (
int)v->cursorLine() != ln ) )
2225 ktl = doc->plainKateTextLine( --ln );
2226 fc = ktl->firstChar();
2227 if ( ktl->attribute( fc ) != commentAttrib )
2230 while ( (ln > 0) && (pos < 0) );
2235 pos = ktl->cursorX( pos,
tabWidth );
2241 if ( d->couples & Parens && coupleBalance( ln,
'(',
')' ) > 0 )
2243 else if ( d->couples & Braces && coupleBalance( ln,
'{',
'}' ) > 0 )
2245 else if ( d->couples & Brackets && coupleBalance( ln,
'[',
']' ) > 0 )
2260 int i = tl->firstChar();
2263 TQChar ch = tl->getChar( i );
2264 uchar at = tl->attribute( i );
2266 if ( d->couples & Parens && ch ==
')' 2267 && ( at == d->coupleAttrib
2268 || (! at && hasRelevantOpening(
KateDocCursor( line.line(), i, doc ) ))
2272 else if ( d->couples & Braces && ch ==
'}' 2273 && ( at == d->coupleAttrib
2274 || (! at && hasRelevantOpening(
KateDocCursor( line.line(), i, doc ) ))
2278 else if ( d->couples & Brackets && ch ==
']' 2279 && ( at == d->coupleAttrib
2280 || (! at && hasRelevantOpening(
KateDocCursor( line.line(), i, doc ) ))
2286 #define ISCOMMENTATTR(attr) (attr==commentAttrib||attr==doxyCommentAttrib) 2287 #define ISCOMMENT (ISCOMMENTATTR(ktl->attribute(ktl->firstChar()))||ISCOMMENTATTR(ktl->attribute(matchpos))) 2290 kdDebug(13030)<<
"variable indenter: starting indent: "<<pos<<
endl;
2293 if ( ktl && ! d->reIndentAfter.isEmpty()
2294 && (matchpos = d->reIndentAfter.search( doc->textLine( ln ) )) > -1
2299 ktl = doc->plainKateTextLine( line.line() );
2300 if ( ! d->reIndent.isEmpty()
2301 && (matchpos = d->reIndent.search( doc->textLine( line.line() ) )) > -1
2306 if ( ! d->reUnindent.isEmpty()
2307 && (matchpos = d->reUnindent.search( doc->textLine( line.line() ) )) > -1
2311 kdDebug(13030)<<
"variable indenter: adjusting by "<<adjustment<<
" units"<<
endl;
2313 if ( adjustment > 0 )
2315 else if ( adjustment < 0 )
2319 fc = doc->plainKateTextLine( ln )->firstChar();
2329 doc->removeText (ln, 0, ln, fc );
2335 doc->insertText (ln, 0, indent);
2344 while (cur.line() <= end.line())
2347 if (!cur.gotoNextLine())
2352 void KateVarIndent::slotVariableChanged(
const TQString &var,
const TQString &val )
2354 if ( ! var.startsWith(
"var-indent") )
2357 if ( var ==
"var-indent-indent-after" )
2358 d->reIndentAfter.setPattern( val );
2359 else if ( var ==
"var-indent-indent" )
2360 d->reIndent.setPattern( val );
2361 else if ( var ==
"var-indent-unindent" )
2362 d->reUnindent.setPattern( val );
2363 else if ( var ==
"var-indent-triggerchars" )
2365 else if ( var ==
"var-indent-handle-couples" )
2368 TQStringList l = TQStringList::split(
" ", val );
2369 if ( l.contains(
"parens") ) d->couples |= Parens;
2370 if ( l.contains(
"braces") ) d->couples |= Braces;
2371 if ( l.contains(
"brackets") ) d->couples |= Brackets;
2373 else if ( var ==
"var-indent-couple-attribute" )
2376 KateHlItemDataList items;
2377 doc->highlight()->getKateHlItemDataListCopy (0, items);
2379 for (uint i=0; i<items.count(); i++)
2381 if ( items.at(i)->name.section(
':', 1 ) == val )
2383 d->coupleAttrib = i;
2390 int KateVarIndent::coupleBalance (
int line,
const TQChar &open,
const TQChar &close )
const 2395 if ( ! ln || ! ln->length() )
return 0;
2397 for ( uint z=0; z < ln->length(); z++ )
2399 TQChar c = ln->getChar( z );
2400 if ( ln->attribute(z) == d->coupleAttrib )
2405 else if (c == close)
2412 bool KateVarIndent::hasRelevantOpening(
const KateDocCursor &end )
const 2417 TQChar close = cur.currentChar();
2419 if ( close ==
'}' ) opener =
'{';
2420 else if ( close =
')' ) opener =
'(';
2421 else if (close =
']' ) opener =
'[';
2425 while (cur.moveBackward(1))
2427 if (cur.currentAttrib() == d->coupleAttrib)
2429 TQChar ch = cur.currentChar();
2432 else if (ch == close)
2447 KateScriptIndent::KateScriptIndent( KateDocument *doc )
2450 m_script=KateFactory::self()->indentScript (
"script-indent-c1-test");
2453 KateScriptIndent::~KateScriptIndent()
2457 void KateScriptIndent::processNewline(
KateDocCursor &begin,
bool needContinue )
2460 KateView *view = doc->activeView();
2468 kdDebug(13030)<<
"calling m_script.processChar"<<
endl;
2469 if( !m_script.processNewline( view, begin, needContinue , errorMsg ) )
2471 kdDebug(13030) <<
"Error in script-indent: " << errorMsg <<
endl;
2473 kdDebug(13030) <<
"ScriptIndent::TIME in ms: " << t.elapsed() <<
endl;
2477 void KateScriptIndent::processChar( TQChar c )
2480 KateView *view = doc->activeView();
2488 kdDebug(13030)<<
"calling m_script.processChar"<<
endl;
2489 if( !m_script.processChar( view, c , errorMsg ) )
2491 kdDebug(13030) <<
"Error in script-indent: " << errorMsg <<
endl;
2493 kdDebug(13030) <<
"ScriptIndent::TIME in ms: " << t.elapsed() <<
endl;
2500 KateView *view = doc->activeView();
2508 kdDebug(13030)<<
"calling m_script.processLine"<<
endl;
2509 if( !m_script.processLine( view, line , errorMsg ) )
2511 kdDebug(13030) <<
"Error in script-indent: " << errorMsg <<
endl;
2513 kdDebug(13030) <<
"ScriptIndent::TIME in ms: " << t.elapsed() <<
endl;
2519 #include <tqlabel.h> 2520 ScriptIndentConfigPage::ScriptIndentConfigPage ( TQWidget *parent,
const char *name )
2523 TQLabel* hello =
new TQLabel(
"Hello world! Dummy for testing purpose.",
this);
2527 ScriptIndentConfigPage::~ScriptIndentConfigPage ()
2531 void ScriptIndentConfigPage::apply ()
2533 kdDebug(13030) <<
"ScriptIndentConfigPagE::apply() was called, save config options now!" <<
endl;
Provides Auto-Indent functionality for katepart.
virtual void updateConfig()
Update indenter's configuration (indention width, attributes etc.)
Cursor class with a pointer to its document.
static TQStringList listModes()
List all possible modes by name.
virtual void processNewline(KateDocCursor &cur, bool needContinue)
Called every time a newline character is inserted in the document.
virtual uint modeNumber() const
Mode index of this mode.
This indenter uses document variables to determine when to add/remove indents.
This widget will be embedded into a modal dialog when clicking the "Configure..." button in the inden...
static bool hasConfigPage(uint mode)
Config page support.
virtual void processLine(KateDocCursor &line)
Aligns/indents the given line to the proper indent position.
TQString tabString(uint length) const
Produces a string with the proper indentation characters for its length.
kdbgstream kdDebug(int area=0)
virtual void processSection(const KateDocCursor &begin, const KateDocCursor &end)
Processes a section of text, indenting each line in between.
uint tabWidth
The number of characters simulated for a tab.
bool useSpaces
Should we use spaces or tabs to indent.
virtual void processLine(KateDocCursor &)
Aligns/indents the given line to the proper indent position.
Provides Auto-Indent functionality for katepart.
kdbgstream kdWarning(int area=0)
virtual ~KateNormalIndent()
Virtual Destructor for the baseclass.
static KateAutoIndent * createIndenter(KateDocument *doc, uint mode)
Static methods to create and list indention modes.
KateNormalIndent(KateDocument *doc)
Constructor.
static TQString modeName(uint mode)
Return the mode name given the mode.
static IndenterConfigPage * configPage(TQWidget *parent, uint mode)
Support for a config page.
bool keepProfile
Always try to honor the leading whitespace of lines already in the file.
bool skipBlanks(KateDocCursor &cur, KateDocCursor &max, bool newline) const
Skip all whitespace starting at cur and ending at max.
uint measureIndent(KateDocCursor &cur) const
Measures the indention of the current textline marked by cur.
virtual void processChar(TQChar c)
Called every time a character is inserted into the document.
bool mixedIndent
Optimize indent by mixing spaces and tabs, ala emacs.
virtual void processNewline(KateDocCursor &cur, bool needContinue)
Called every time a newline character is inserted in the document.
kndbgstream & endl(kndbgstream &s)
static TQString modeDescription(uint mode)
Return the mode description.
bool isBalanced(KateDocCursor &begin, const KateDocCursor &end, TQChar open, TQChar close, uint &pos) const
Determines if the characters open and close are balanced between begin and end Fills in pos with the ...
KateAutoIndent(KateDocument *doc)
Constructor.
virtual ~KateAutoIndent()
Virtual Destructor for the baseclass.
uint indentWidth
The number of characters used when tabs are replaced by spaces.