Index: src/document/katedocument.cpp =================================================================== --- src/document/katedocument.cpp +++ src/document/katedocument.cpp @@ -3975,38 +3975,73 @@ } +int firstGoodChar(const Kate::TextLine &line) +{ + // Inspired by (aka stolen from) KTextEditor::ViewPrivate::smartNewline() + int col = 0; + while (line->length() > col && + !(line->at(col).isLetterOrNumber() || line->at(col) == QLatin1Char('_')) + ) { + ++col; + } + + return col; +} + void KTextEditor::DocumentPrivate::joinLines(uint first, uint last) { // if ( first == last ) last += 1; editStart(); - int line(first); + const int line(first); + + Kate::TextLine l = kateTextLine(line); + if (!l) { // Just for the overanxious + return; + } + // Smart Join Line: Remove everything from next line(s) which may be annoying... + QString peskyPrefix = l->string(0, firstGoodChar(l)); + if (!peskyPrefix.endsWith(QStringLiteral(" "))) { + // ...but try to avoid to damage stuff like HTML or Latex tags... + peskyPrefix.clear(); + } else if (peskyPrefix.endsWith(QStringLiteral("} "))) { + // ...and make an exception for braces like in THIS codeblock here + peskyPrefix.clear(); + } + while (first < last) { // Normalize the whitespace in the joined lines by making sure there's // always exactly one space between the joined lines // This cannot be done in editUnwrapLine, because we do NOT want this // behavior when deleting from the start of a line, just when explicitly // calling the join command - Kate::TextLine l = kateTextLine(line); Kate::TextLine tl = kateTextLine(line + 1); if (!l || !tl) { editEnd(); return; } - int pos = tl->firstChar(); - if (pos >= 0) { - if (pos != 0) { - editRemoveText(line + 1, 0, pos); - } - if (!(l->length() == 0 || l->at(l->length() - 1).isSpace())) { - editInsertText(line + 1, 0, QLatin1String(" ")); - } + const int pos = l->lastChar(); + if (pos < 0) { + // Line contains only space, clear all + editRemoveText(line, 0, l->length()); + } else if (pos == l->length() - 1) { + // No trailing space, add one + editInsertText(line, l->length(), QStringLiteral(" ")); } else { - // Just remove the whitespace and let Kate handle the rest - editRemoveText(line + 1, 0, tl->length()); + // Remove all but one trailing space + editRemoveText(line, pos + 2, l->length()); + } + + // Remove all from next line which may annoying, or not + if (tl->startsWith(peskyPrefix) && true /*TODO Add config option*/) { + // No check here for size=0, will catch in editRemoveText() + editRemoveText(line + 1, 0, peskyPrefix.size()); } + // Remove all leading space from next line + editRemoveText(line + 1, 0, tl->firstChar()); + editUnWrapLine(line); first++; }