diff --git a/src/view/kateview.h b/src/view/kateview.h --- a/src/view/kateview.h +++ b/src/view/kateview.h @@ -135,7 +135,12 @@ private Q_SLOTS: /** - * internal use, apply word wrap + * Wrap lines touched by the selection with respect of existing paragraphs. + * To do so will the paragraph prior to the wrap joined as one single line + * which cause an almost perfect wrapped paragraph as long as there are no + * unneeded spaces exist or some formatting like this comment block. + * Without any selection the current line is wrapped. + * Empty lines around each paragraph are untouched. */ void applyWordWrap(); diff --git a/src/view/kateview.cpp b/src/view/kateview.cpp --- a/src/view/kateview.cpp +++ b/src/view/kateview.cpp @@ -2340,11 +2340,53 @@ void KTextEditor::ViewPrivate::applyWordWrap() { - if (selection()) { - doc()->wrapText(selectionRange().start().line(), selectionRange().end().line()); - } else { - doc()->wrapText(0, doc()->lastLine()); + doc()->editStart(); + int first = selectionRange().start().line(); + int last = selectionRange().end().line(); + if (first == last) { + // Either no selection or only one line selected, wrap only the current line + first = cursorPosition().line(); + doc()->wrapText(first, first); + doc()->editEnd(); + return; } + + // Because we shrink and expand lines, we need a powerful "Moving Cursor" + KTextEditor::MovingCursor *curr = doc()->newMovingCursor(KTextEditor::Cursor(selectionRange().start())); + + // Scan the selected range for paragraphs, whereas each empty line trigger a new paragraph + for (int line = first; line <= selectionRange().end().line(); ++line) { + // Is our first line a somehow filled line? + while(doc()->plainKateTextLine(first)->firstChar() < 0) { + // Fast forward to first non empty line + ++first; + curr->setPosition(curr->line() + 1, 0); + // Yeah GOTO! We must increment "line" too but also check the boundaries, so this way we avoid some fidgeting + // C++ can only continue the inner loop, but we need here to continue our "for" loop + goto NextLine; + } + + // Is our current line a somehow filled line? If not, wrap the paragraph + if (doc()->plainKateTextLine(line)->firstChar() < 0) { + curr->setPosition(line, 0); // Set on empty line + doc()->joinLines(first, line - 1); + doc()->wrapText(first, first); + first = curr->line() + 1; + line = first; + } + + NextLine:; // Our fancy goto target + } + + // If there was no paragraph, we need to wrap now + bool needWrap = (curr->line() != selectionRange().end().line()); + if (needWrap && doc()->plainKateTextLine(first)->firstChar() != -1) { + doc()->joinLines(first, selectionRange().end().line()); + doc()->wrapText(first, first); + } + + delete curr; + doc()->editEnd(); } //END