| 516 | } |
| 517 | |
| 518 | QString SourceFormatterController::FileFormatter::addModeline(QString input) const |
| 519 | { |
| 520 | Q_ASSERT(m_formatter); |
| 521 | |
| 522 | QRegExp kateModelineWithNewline(QStringLiteral("\\s*\\n//\\s*kate:(.*)$")); |
| 523 | |
| 524 | // If there already is a modeline in the document, adapt it while formatting, even |
| 525 | // if "add modeline" is disabled. |
| 526 | if (!m_sourceFormatterConfig.readEntry(SourceFormatterController::kateModeLineConfigKey(), false) |
| 527 | && kateModelineWithNewline.indexIn(input) == -1) |
| 528 | return input; |
| 529 | |
| 530 | const auto indentation = m_formatter->indentation(m_style, m_url, m_mimeType); |
| 531 | if( !indentation.isValid() ) |
| 532 | return input; |
| 533 | |
| 534 | QString output; |
| 535 | QTextStream os(&output, QIODevice::WriteOnly); |
| 536 | QTextStream is(&input, QIODevice::ReadOnly); |
| 537 | |
| 538 | QString modeline(QStringLiteral("// kate: ") + QLatin1String("indent-mode ") + indentationMode(m_mimeType) |
| 539 | + QLatin1String("; ")); |
| 540 | |
| 541 | if(indentation.indentWidth) // We know something about indentation-width |
| 542 | modeline.append(QStringLiteral("indent-width %1; ").arg(indentation.indentWidth)); |
| 543 | |
| 544 | if(indentation.indentationTabWidth != 0) // We know something about tab-usage |
| 545 | { |
| 546 | const auto state = (indentation.indentationTabWidth == -1) ? QLatin1String("on") : QLatin1String("off"); |
| 547 | modeline += QLatin1String("replace-tabs ") + state + QLatin1String("; "); |
| 548 | if(indentation.indentationTabWidth > 0) |
| 549 | modeline.append(QStringLiteral("tab-width %1; ").arg(indentation.indentationTabWidth)); |
| 550 | } |
| 551 | |
| 552 | qCDebug(SHELL) << "created modeline: " << modeline; |
| 553 | |
| 554 | QRegExp kateModeline(QStringLiteral("^\\s*//\\s*kate:(.*)$")); |
| 555 | |
| 556 | bool modelinefound = false; |
| 557 | QRegExp knownOptions(QStringLiteral("\\s*(indent-width|space-indent|tab-width|indent-mode|replace-tabs)")); |
| 558 | while (!is.atEnd()) { |
| 559 | QString line = is.readLine(); |
| 560 | // replace only the options we care about |
| 561 | if (kateModeline.indexIn(line) >= 0) { // match |
| 562 | qCDebug(SHELL) << "Found a kate modeline: " << line; |
| 563 | modelinefound = true; |
| 564 | QString options = kateModeline.cap(1); |
| 565 | const QStringList optionList = options.split(QLatin1Char(';'), Qt::SkipEmptyParts); |
| 566 | |
| 567 | os << modeline; |
| 568 | for (QString s : optionList) { |
| 569 | if (knownOptions.indexIn(s) < 0) { // unknown option, add it |
| 570 | if(s.startsWith(QLatin1Char(' '))) |
| 571 | s.remove(0, 1); |
| 572 | os << s << ";"; |
| 573 | qCDebug(SHELL) << "Found unknown option: " << s; |
| 574 | } |
| 575 | } |
no test coverage detected