00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katescriptdocument.h"
00020
00021 #include "katedocument.h"
00022 #include "kateview.h"
00023 #include "katerenderer.h"
00024 #include "katehighlight.h"
00025 #include "katescript.h"
00026
00027 #include <QtScript/QScriptEngine>
00028
00029 KateScriptDocument::KateScriptDocument(QObject *parent)
00030 : QObject(parent), m_document(0)
00031 {
00032 }
00033
00034 void KateScriptDocument::setDocument(KateDocument *document)
00035 {
00036 m_document = document;
00037 }
00038
00039 KateDocument *KateScriptDocument::document()
00040 {
00041 return m_document;
00042 }
00043
00044 int KateScriptDocument::defStyleNum(int line, int column)
00045 {
00046 KateDocCursor cursor(line, column, m_document);
00047 QList<KTextEditor::Attribute::Ptr> attributes = m_document->highlight()->attributes(((KateView*) m_document->activeView())->renderer()->config()->schema());
00048 KTextEditor::Attribute::Ptr a = attributes[cursor.currentAttrib()];
00049 return a->property(KateExtendedAttribute::AttributeDefaultStyleIndex).toInt();
00050 }
00051
00052 bool KateScriptDocument::isCode(int line, int column)
00053 {
00054 const int defaultStyle = defStyleNum(line, column);
00055 return _isCode(defaultStyle);
00056 }
00057
00058 bool KateScriptDocument::isComment(int line, int column)
00059 {
00060 const int defaultStyle = defStyleNum(line, column);
00061 return defaultStyle == KateExtendedAttribute::dsComment;
00062 }
00063
00064 bool KateScriptDocument::isString(int line, int column)
00065 {
00066 const int defaultStyle = defStyleNum(line, column);
00067 return defaultStyle == KateExtendedAttribute::dsString;
00068 }
00069
00070 bool KateScriptDocument::isRegionMarker(int line, int column)
00071 {
00072 const int defaultStyle = defStyleNum(line, column);
00073 return defaultStyle == KateExtendedAttribute::dsRegionMarker;
00074 }
00075
00076 bool KateScriptDocument::isChar(int line, int column)
00077 {
00078 const int defaultStyle = defStyleNum(line, column);
00079 return defaultStyle == KateExtendedAttribute::dsChar;
00080 }
00081
00082 bool KateScriptDocument::isOthers(int line, int column)
00083 {
00084 const int defaultStyle = defStyleNum(line, column);
00085 return defaultStyle == KateExtendedAttribute::dsOthers;
00086 }
00087
00088 int KateScriptDocument::firstVirtualColumn(int line)
00089 {
00090 const int tabWidth = m_document->config()->tabWidth();
00091 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00092 const int firstPos = textLine ? textLine->firstChar() : -1;
00093 if(!textLine || firstPos == -1)
00094 return -1;
00095 return textLine->indentDepth(tabWidth);
00096 }
00097
00098 int KateScriptDocument::lastVirtualColumn(int line)
00099 {
00100 const int tabWidth = m_document->config()->tabWidth();
00101 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00102 const int lastPos = textLine ? textLine->lastChar() : -1;
00103 if(!textLine || lastPos == -1)
00104 return -1;
00105 return textLine->toVirtualColumn(lastPos, tabWidth);
00106 }
00107
00108 int KateScriptDocument::toVirtualColumn(int line, int column)
00109 {
00110 const int tabWidth = m_document->config()->tabWidth();
00111 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00112 if (!textLine || column < 0 || column > textLine->length()) return -1;
00113 return textLine->toVirtualColumn(column, tabWidth);
00114 }
00115
00116 int KateScriptDocument::fromVirtualColumn(int line, int virtualColumn)
00117 {
00118 const int tabWidth = m_document->config()->tabWidth();
00119 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00120 if(!textLine || virtualColumn < 0 || virtualColumn > textLine->virtualLength(tabWidth))
00121 return -1;
00122 return textLine->fromVirtualColumn(virtualColumn, tabWidth);
00123 }
00124
00125 QScriptValue KateScriptDocument::rfind(int line, int column, const QString& text, int attribute)
00126 {
00127 KateDocCursor cursor(line, column, m_document);
00128 const int start = cursor.line();
00129 QList<KTextEditor::Attribute::Ptr> attributes =
00130 m_document->highlight()->attributes(((KateView*)m_document->activeView())->renderer()->config()->schema());
00131
00132 do {
00133 KateTextLine::Ptr textLine = m_document->plainKateTextLine(cursor.line());
00134 if (!textLine)
00135 break;
00136
00137 if (cursor.line() != start) {
00138 cursor.setColumn(textLine->length());
00139 } else if (column >= textLine->length()) {
00140 cursor.setColumn(qMax(textLine->length(), 0));
00141 }
00142
00143 bool found = true;
00144 while (found) {
00145 uint foundAt;
00146 found = textLine->searchText(0, cursor.column(), text, &foundAt, 0, true, true);
00147 if (found) {
00148 bool hasStyle = true;
00149 if (attribute != -1) {
00150 KTextEditor::Attribute::Ptr a = attributes[textLine->attribute(foundAt)];
00151 const int ds = a->property(KateExtendedAttribute::AttributeDefaultStyleIndex).toInt();
00152 hasStyle = (ds == attribute);
00153 }
00154
00155 if (hasStyle) {
00156 QScriptValue position = engine()->newObject();
00157 position.setProperty("line", QScriptValue(engine(), cursor.line()));
00158 position.setProperty("column", QScriptValue(engine(), foundAt));
00159 return position;
00160 } else {
00161 cursor.setColumn(foundAt);
00162 }
00163 }
00164 }
00165 } while (cursor.gotoPreviousLine());
00166
00167 return QScriptValue();
00168 }
00169
00170 KTextEditor::Cursor KateScriptDocument::anchor(int line, int column, QChar character)
00171 {
00172 KateDocCursor cursor(line, column, m_document);
00173 QList<KTextEditor::Attribute::Ptr> attributes =
00174 m_document->highlight()->attributes(((KateView*) m_document->activeView())->renderer()->config()->schema());
00175 int count = 1;
00176 QChar lc = character;
00177 QChar rc;
00178 if (lc == '(') rc = ')';
00179 else if (lc == '{') rc = '}';
00180 else if (lc == '[') rc = ']';
00181 else return KTextEditor::Cursor::invalid ();
00182
00183
00184 while (cursor.moveBackward(1)) {
00185 QChar ch = cursor.currentChar();
00186 if (ch == lc) {
00187 KTextEditor::Attribute::Ptr a = attributes[cursor.currentAttrib()];
00188 const int ds = a->property(KateExtendedAttribute::AttributeDefaultStyleIndex).toInt();
00189 if (_isCode(ds)) {
00190 --count;
00191 }
00192 }
00193 else if (ch == rc) {
00194 KTextEditor::Attribute::Ptr a = attributes[cursor.currentAttrib()];
00195 const int ds = a->property(KateExtendedAttribute::AttributeDefaultStyleIndex).toInt();
00196 if (_isCode(ds)) {
00197 ++count;
00198 }
00199 }
00200
00201 if (count == 0) {
00202 return cursor;
00203 }
00204 }
00205 return KTextEditor::Cursor::invalid ();
00206 }
00207
00208 bool KateScriptDocument::startsWith (int line, const QString &pattern, bool skipWhiteSpaces)
00209 {
00210 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00211
00212 if (!textLine)
00213 return false;
00214
00215 if (skipWhiteSpaces)
00216 return textLine->matchesAt(textLine->firstChar(), pattern);
00217
00218 return textLine->startsWith (pattern);
00219 }
00220
00221 bool KateScriptDocument::endsWith (int line, const QString &pattern, bool skipWhiteSpaces)
00222 {
00223 KateTextLine::Ptr textLine = m_document->plainKateTextLine(line);
00224
00225 if (!textLine)
00226 return false;
00227
00228 if (skipWhiteSpaces)
00229 return textLine->matchesAt(textLine->lastChar() - pattern.length() + 1, pattern);
00230
00231 return textLine->endsWith (pattern);
00232 }
00233
00234
00235
00236 QString KateScriptDocument::fileName()
00237 {
00238 return m_document->documentName();
00239 }
00240
00241 QString KateScriptDocument::url()
00242 {
00243 return m_document->url().prettyUrl();
00244 }
00245
00246 QString KateScriptDocument::mimeType()
00247 {
00248 return m_document->mimeType();
00249 }
00250
00251 QString KateScriptDocument::encoding()
00252 {
00253 return m_document->encoding();
00254 }
00255
00256 bool KateScriptDocument::isModified()
00257 {
00258 return m_document->isModified();
00259 }
00260
00261 QString KateScriptDocument::text()
00262 {
00263 return m_document->text();
00264 }
00265
00266 QString KateScriptDocument::textRange(int i, int j, int k, int l)
00267 {
00268 return m_document->text(KTextEditor::Range(i, j, k, l));
00269 }
00270
00271 QString KateScriptDocument::line(int i)
00272 {
00273 return m_document->line (i);
00274 }
00275
00276 QString KateScriptDocument::wordAt(int i, int j)
00277 {
00278 return m_document->getWord(KTextEditor::Cursor(i, j));
00279 }
00280
00281 QString KateScriptDocument::charAt(int i, int j)
00282 {
00283 const QChar c = m_document->character (KTextEditor::Cursor(i, j));
00284 return c.isNull() ? "" : QString(c);
00285 }
00286
00287 QString KateScriptDocument::firstChar(int i)
00288 {
00289 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00290 if(!textLine) return "";
00291
00292 const QChar c = textLine->at(textLine->firstChar());
00293 return c.isNull() ? "" : QString(c);
00294 }
00295
00296 QString KateScriptDocument::lastChar(int i)
00297 {
00298 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00299 if(!textLine) return "";
00300
00301 const QChar c = textLine->at(textLine->lastChar());
00302 return c.isNull() ? "" : QString(c);
00303 }
00304
00305 bool KateScriptDocument::isSpace(int i, int j)
00306 {
00307 return m_document->character (KTextEditor::Cursor(i, j)).isSpace();
00308 }
00309
00310 bool KateScriptDocument::matchesAt(int i, int j, const QString &s)
00311 {
00312 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00313 return textLine ? textLine->matchesAt(j, s) : false;
00314 }
00315
00316 bool KateScriptDocument::setText(const QString &s)
00317 {
00318 return m_document->setText(s);
00319 }
00320
00321 bool KateScriptDocument::clear()
00322 {
00323 return m_document->clear();
00324 }
00325
00326 bool KateScriptDocument::truncate(int i, int j)
00327 {
00328 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00329 if(textLine) textLine->truncate(j);
00330 return static_cast<bool>(textLine);
00331 }
00332
00333 bool KateScriptDocument::insertText(int i, int j, const QString &s)
00334 {
00335 return m_document->insertText (KTextEditor::Cursor(i, j), s);
00336 }
00337
00338 bool KateScriptDocument::removeText(int i, int j, int k, int l)
00339 {
00340 return m_document->removeText(KTextEditor::Range(i, j, k, l));
00341 }
00342
00343 bool KateScriptDocument::insertLine(int i, const QString &s)
00344 {
00345 return m_document->insertLine (i, s);
00346 }
00347
00348 bool KateScriptDocument::removeLine(int i)
00349 {
00350 return m_document->removeLine (i);
00351 }
00352
00353 void KateScriptDocument::joinLines(int i, int j)
00354 {
00355 m_document->joinLines (i, j);
00356 return;
00357 }
00358
00359 int KateScriptDocument::lines()
00360 {
00361 return m_document->lines();
00362 }
00363
00364 int KateScriptDocument::length()
00365 {
00366 return m_document->totalCharacters();
00367 }
00368
00369 int KateScriptDocument::lineLength(int i)
00370 {
00371 return m_document->lineLength(i);
00372 }
00373
00374 void KateScriptDocument::editBegin()
00375 {
00376 m_document->editBegin();
00377 return;
00378 }
00379
00380 void KateScriptDocument::editEnd()
00381 {
00382 m_document->editEnd ();
00383 return;
00384 }
00385
00386 int KateScriptDocument::firstColumn(int i)
00387 {
00388 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00389 return textLine ? textLine->firstChar() : -1;
00390 }
00391
00392 int KateScriptDocument::lastColumn(int i)
00393 {
00394 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00395 return textLine ? textLine->lastChar() : -1;
00396 }
00397
00398 int KateScriptDocument::prevNonSpaceColumn(int i, int j)
00399 {
00400 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00401 if(!textLine) return -1;
00402 return textLine->previousNonSpaceChar(j);
00403 }
00404
00405 int KateScriptDocument::nextNonSpaceColumn(int i, int j)
00406 {
00407 KateTextLine::Ptr textLine = m_document->plainKateTextLine(i);
00408 if(!textLine) return -1;
00409 return textLine->nextNonSpaceChar(j);
00410 }
00411
00412 int KateScriptDocument::prevNonEmptyLine(int i)
00413 {
00414 const int startLine = i;
00415 for (int currentLine = startLine; currentLine >= 0; --currentLine) {
00416 KateTextLine::Ptr textLine = m_document->plainKateTextLine(currentLine);
00417 if(!textLine)
00418 return -1;
00419 if(textLine->firstChar() != -1)
00420 return currentLine;
00421 }
00422 return -1;
00423 }
00424
00425 int KateScriptDocument::nextNonEmptyLine(int i)
00426 {
00427 const int startLine = i;
00428 for (int currentLine = startLine; currentLine < m_document->lines(); ++currentLine) {
00429 KateTextLine::Ptr textLine = m_document->plainKateTextLine(currentLine);
00430 if(!textLine)
00431 return -1;
00432 if(textLine->firstChar() != -1)
00433 return currentLine;
00434 }
00435 return -1;
00436 }
00437
00438 bool KateScriptDocument::isInWord(const QString &s, int i)
00439 {
00440 return m_document->highlight()->isInWord(s.at(0), i);
00441 }
00442
00443 bool KateScriptDocument::canBreakAt(const QString &s, int i)
00444 {
00445 return m_document->highlight()->canBreakAt(s.at(0), i);
00446 }
00447
00448 bool KateScriptDocument::canComment(int i, int j)
00449 {
00450 return m_document->highlight()->canComment(i, j);
00451 }
00452
00453 QString KateScriptDocument::commentMarker(int i)
00454 {
00455 return m_document->highlight()->getCommentSingleLineStart(i);
00456 }
00457
00458 QString KateScriptDocument::commentStart(int i)
00459 {
00460 return m_document->highlight()->getCommentStart(i);
00461 }
00462
00463 QString KateScriptDocument::commentEnd(int i)
00464 {
00465 return m_document->highlight()->getCommentEnd(i);
00466 }
00467
00468 int KateScriptDocument::attribute(int i, int j)
00469 {
00470 KateTextLine::Ptr textLine = m_document->kateTextLine(i);
00471 if(!textLine) return 0;
00472 return textLine->attribute(j);
00473 }
00474
00475 QString KateScriptDocument::variable(const QString &s)
00476 {
00477 return m_document->variable(s);
00478 }
00479
00480
00481
00482 bool KateScriptDocument::_isCode(int defaultStyle)
00483 {
00484 return (defaultStyle != KateExtendedAttribute::dsComment
00485 && defaultStyle != KateExtendedAttribute::dsString
00486 && defaultStyle != KateExtendedAttribute::dsRegionMarker
00487 && defaultStyle != KateExtendedAttribute::dsChar
00488 && defaultStyle != KateExtendedAttribute::dsOthers);
00489 }
00490
00491
00492