diff --git a/src/completion/katewordcompletion.cpp b/src/completion/katewordcompletion.cpp --- a/src/completion/katewordcompletion.cpp +++ b/src/completion/katewordcompletion.cpp @@ -247,31 +247,73 @@ ) const { KTextEditor::ViewPrivate *v = qobject_cast (view); + + const bool completeBlockSelection = v->blockSelection() && v->selection(); + if (v->config()->wordCompletionRemoveTail()) { - int tailStart = word.end().column(); - const QString &line = view->document()->line(word.end().line()); - int tailEnd = line.length(); - for (int i = word.end().column(); i < tailEnd; ++i) { - // Letters, numbers and underscore are part of a word! - /// \todo Introduce configurable \e word-separators?? - if (!line[i].isLetterOrNumber() && line[i] != QLatin1Char('_')) { - tailEnd = i; + if (completeBlockSelection) { + KTextEditor::Range selectionRange1 = view->selectionRange(); + // startLine and endLine are the same for both selectionRange{1,2} + const int startLine = selectionRange1.start().line(); + const int endLine = selectionRange1.end().line(); + // remove word from all lines in the block selection + v->doc()->removeText(KTextEditor::Range(word.start(), selectionRange1.end()), true); + // typeChars will take care of inserting the completion text + // on every line in the block selection + v->doc()->typeChars(v, m_matches.at(index.row())); + v->doc()->editEnd(); + + KTextEditor::Range selectionRange2 = view->selectionRange(); + // this column is where all the tails would begin + const int selectionEndColumn = selectionRange2.end().column(); + v->doc()->editStart(); + for (int i = startLine; i <= endLine; ++i) { + const QString &line = view->document()->line(i); + int tailEnd = line.length(); + for (int j = selectionEndColumn; j < tailEnd; ++j) { + // Letters, numbers and underscore are part of a word! + /// \todo Introduce configurable \e word-separators?? + if (!line[j].isLetterOrNumber() && line[j] != QLatin1Char('_')) { + tailEnd = j; + } + } + + v->doc()->removeText(KTextEditor::Range(KTextEditor::Cursor(i, selectionEndColumn), KTextEditor::Cursor(i, tailEnd))); + } + } else { + int tailStart = word.end().column(); + const QString &line = view->document()->line(word.end().line()); + int tailEnd = line.length(); + for (int i = word.end().column(); i < tailEnd; ++i) { + // Letters, numbers and underscore are part of a word! + /// \todo Introduce configurable \e word-separators?? + if (!line[i].isLetterOrNumber() && line[i] != QLatin1Char('_')) { + tailEnd = i; + } } - } - int sizeDiff = m_matches.at(index.row()).size() - (word.end().column() - word.start().column()); + int sizeDiff = m_matches.at(index.row()).size() - (word.end().column() - word.start().column()); - tailStart += sizeDiff; - tailEnd += sizeDiff; + tailStart += sizeDiff; + tailEnd += sizeDiff; - KTextEditor::Range tail(KTextEditor::Cursor(word.start().line(), tailStart), KTextEditor::Cursor(word.end().line(), tailEnd)); + KTextEditor::Range tail(KTextEditor::Cursor(word.start().line(), tailStart), KTextEditor::Cursor(word.end().line(), tailEnd)); - view->document()->replaceText(word, m_matches.at(index.row())); - v->doc()->editEnd(); - v->doc()->editStart(); - view->document()->replaceText(tail, QString()); + view->document()->replaceText(word, m_matches.at(index.row())); + v->doc()->editEnd(); + v->doc()->editStart(); + view->document()->replaceText(tail, QString()); + } } else { - view->document()->replaceText(word, m_matches.at(index.row())); + if (completeBlockSelection) { + // remove word from all lines in the block selection + v->doc()->removeText(KTextEditor::Range(word.start(), v->selectionRange().end()), true); + // typeChars will take care of inserting the completion text + // on the lines in the block selection + v->doc()->typeChars(v, m_matches.at(index.row())); + } else { + v->doc()->replaceText(word, m_matches.at(index.row())); + } } }