diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index f7a289945fd..8f8d1b8fde8 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include using namespace TextEditor; @@ -106,6 +108,25 @@ void ClangFormat::formatFile() formatCurrentFile(command()); } +void ClangFormat::formatAtPosition(const int pos, const int length) +{ + const TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget(); + if (!widget) + return; + + const QTextCodec *codec = widget->textDocument()->codec(); + if (!codec) { + formatCurrentFile(command(pos, length)); + return; + } + + const QString &text = widget->textAt(0, pos + length); + const QStringView buffer(text); + const int encodedOffset = codec->fromUnicode(buffer.left(pos)).size(); + const int encodedLength = codec->fromUnicode(buffer.mid(pos, length)).size(); + formatCurrentFile(command(encodedOffset, encodedLength)); +} + void ClangFormat::formatAtCursor() { const TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget(); @@ -113,18 +134,16 @@ void ClangFormat::formatAtCursor() return; const QTextCursor tc = widget->textCursor(); + if (tc.hasSelection()) { - const int offset = tc.selectionStart(); - const int length = tc.selectionEnd() - offset; - formatCurrentFile(command(offset, length)); + const int selectionStart = tc.selectionStart(); + formatAtPosition(selectionStart, tc.selectionEnd() - selectionStart); } else { // Pretend that the current line was selected. // Note that clang-format will extend the range to the next bigger // syntactic construct if needed. const QTextBlock block = tc.block(); - const int offset = block.position(); - const int length = block.length(); - formatCurrentFile(command(offset, length)); + formatAtPosition(block.position(), block.length()); } } @@ -185,7 +204,7 @@ void ClangFormat::disableFormattingSelectedText() // The indentation of these markers might be undesired, so reformat. // This is not optimal because two undo steps will be needed to remove the markers. const int reformatTextLength = insertCursor.position() - selectionStartBlock.position(); - formatCurrentFile(command(selectionStartBlock.position(), reformatTextLength)); + formatAtPosition(selectionStartBlock.position(), reformatTextLength); } Command ClangFormat::command() const diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h index 24ce566861d..2189398d5a6 100644 --- a/src/plugins/beautifier/clangformat/clangformat.h +++ b/src/plugins/beautifier/clangformat/clangformat.h @@ -47,6 +47,7 @@ public: private: void formatFile(); + void formatAtPosition(const int pos, const int length); void formatAtCursor(); void formatLines(); void disableFormattingSelectedText();