diff --git a/dist/clangformat/README.md b/dist/clangformat/README.md index ae714aad9eeb9e53fb05ff33668c9d01219eca67..aa3584e462112bad2a388de5c6e4efb4c2a62e3d 100644 --- a/dist/clangformat/README.md +++ b/dist/clangformat/README.md @@ -58,6 +58,7 @@ For Windows: In Menu: Tools > Options > Environment > Keyboard * ClangFormat / FormatFile - e.g. Alt+C, F * ClangFormat / FormatSelectedText - e.g. Alt+C, S + * ClangFormat / DisableFormattingSelectedText - e.g. Alt+C, D Due to several issues outlined below the FormatFile action might be of limited use. diff --git a/doc/src/editors/creator-beautifier.qdoc b/doc/src/editors/creator-beautifier.qdoc index c47f9fb512135e0c1b0db7bbb392851a6da64218..e93d222594ad5b9761ff4c4e6d69a333e6e15de0 100644 --- a/doc/src/editors/creator-beautifier.qdoc +++ b/doc/src/editors/creator-beautifier.qdoc @@ -178,4 +178,8 @@ select it when no text is selected, the whole file is formatted by default. To disable this behavior, deselect the \uicontrol {Format entire file if no text was selected} check box. + + ClangFormat provides additionally the \uicontrol {Disable Formatting for + Selected Text} command. If you select it, the selected lines will be + wrapped within \c {// clang-format off} and \c {// clang-format on}. */ diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index 0dcfbf7c0effa704014f417e570ced92a6a31156..947233606c1f803e61a8ce5210d621f6a9d3e843 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -496,6 +496,12 @@ QString BeautifierPlugin::msgFormatSelectedText() return tr("Format &Selected Text"); } +QString BeautifierPlugin::msgDisableFormattingSelectedText() +{ + //: Menu entry + return tr("&Disable Formatting for Selected Text"); +} + QString BeautifierPlugin::msgCommandPromptDialogTitle(const QString &command) { //: File dialog title for path chooser when choosing binary diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h index 14d6674ab8aef98c17895e1777aafb23ab86f7e1..32189bcb19d4924597409f2a60d028bc2268e259 100644 --- a/src/plugins/beautifier/beautifierplugin.h +++ b/src/plugins/beautifier/beautifierplugin.h @@ -80,6 +80,7 @@ public: static QString msgCannotGetConfigurationFile(const QString &command); static QString msgFormatCurrentFile(); static QString msgFormatSelectedText(); + static QString msgDisableFormattingSelectedText(); static QString msgCommandPromptDialogTitle(const QString &command); static void showError(const QString &error); diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index 13f7caab24faad2051335013a79a4e1f158bf30a..b677a59fbccb7b79c2c4a8eaea22a0b9e54e79d7 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -48,6 +48,7 @@ #include <QAction> #include <QMenu> +#include <QTextBlock> namespace Beautifier { namespace Internal { @@ -88,6 +89,14 @@ bool ClangFormat::initialize() menu->addAction(cmd); connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatSelectedText); + m_disableFormattingSelectedText + = new QAction(BeautifierPlugin::msgDisableFormattingSelectedText(), this); + cmd = Core::ActionManager::registerAction( + m_disableFormattingSelectedText, Constants::ClangFormat::ACTION_DISABLEFORMATTINGSELECTED); + menu->addAction(cmd); + connect(m_disableFormattingSelectedText, &QAction::triggered, + this, &ClangFormat::disableFormattingSelectedText); + Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); connect(m_settings, &ClangFormatSettings::supportedMimeTypesChanged, @@ -130,6 +139,42 @@ void ClangFormat::formatSelectedText() } } +void ClangFormat::disableFormattingSelectedText() +{ + TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + if (!widget) + return; + + const QTextCursor tc = widget->textCursor(); + if (!tc.hasSelection()) + return; + + // Insert start marker + const QTextBlock selectionStartBlock = tc.document()->findBlock(tc.selectionStart()); + QTextCursor insertCursor(tc.document()); + insertCursor.beginEditBlock(); + insertCursor.setPosition(selectionStartBlock.position()); + insertCursor.insertText("// clang-format off\n"); + const int positionToRestore = tc.position(); + + // Insert end marker + QTextBlock selectionEndBlock = tc.document()->findBlock(tc.selectionEnd()); + insertCursor.setPosition(selectionEndBlock.position() + selectionEndBlock.length() - 1); + insertCursor.insertText("\n// clang-format on"); + insertCursor.endEditBlock(); + + // Reset the cursor position in order to clear the selection. + QTextCursor restoreCursor(tc.document()); + restoreCursor.setPosition(positionToRestore); + widget->setTextCursor(restoreCursor); + + // 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(); + m_beautifierPlugin->formatCurrentFile(command(selectionStartBlock.position(), + reformatTextLength)); +} + Command ClangFormat::command() const { Command command; diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h index 86037fac0cc6000fbc5c03912b5676826e663b2f..bb5e5bf78812e9b31688f38cc4f0bf2f08946587 100644 --- a/src/plugins/beautifier/clangformat/clangformat.h +++ b/src/plugins/beautifier/clangformat/clangformat.h @@ -55,9 +55,11 @@ public: private: void formatFile(); void formatSelectedText(); + void disableFormattingSelectedText(); BeautifierPlugin *m_beautifierPlugin; QAction *m_formatFile = nullptr; QAction *m_formatRange = nullptr; + QAction *m_disableFormattingSelectedText = nullptr; ClangFormatSettings *m_settings; Command command(int offset, int length) const; }; diff --git a/src/plugins/beautifier/clangformat/clangformatconstants.h b/src/plugins/beautifier/clangformat/clangformatconstants.h index 837d3323069f63fbf4d4199c6258b6293aa9f88f..51f3981fc5de3101b1d51de321b89a9b816b18e6 100644 --- a/src/plugins/beautifier/clangformat/clangformatconstants.h +++ b/src/plugins/beautifier/clangformat/clangformatconstants.h @@ -34,6 +34,7 @@ namespace ClangFormat { const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::ClangFormat::ClangFormat", "ClangFormat"); const char ACTION_FORMATFILE[] = "ClangFormat.FormatFile"; const char ACTION_FORMATSELECTED[] = "ClangFormat.FormatSelectedText"; +const char ACTION_DISABLEFORMATTINGSELECTED[] = "ClangFormat.DisableFormattingSelectedText"; const char MENU_ID[] = "ClangFormat.Menu"; const char OPTION_ID[] = "ClangFormat"; const char SETTINGS_NAME[] = "clangformat";