diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-02-22 23:41:12 +0100 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-03-13 08:20:00 +0000 |
commit | 3107633731c086771d45c46122625eb192294d2a (patch) | |
tree | d5c256c6b886de2b4aa6b250651c6fbdc229231b /src/plugins/texteditor | |
parent | 2166647682cd34968ec002f859e8263b90585189 (diff) |
TextEditor: Split FormatText into input and output structs
Remove output data from FormatText and rename it into FormatInput.
Use Utils::expected_str<QString> for output data and alias it with
FormatOutput.
Change-Id: I2cf21d73d2e973eeeb4431ae30b56bb5987986f6
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/texteditor')
-rw-r--r-- | src/plugins/texteditor/formattexteditor.cpp | 124 |
1 files changed, 57 insertions, 67 deletions
diff --git a/src/plugins/texteditor/formattexteditor.cpp b/src/plugins/texteditor/formattexteditor.cpp index 879387b991..b5340281b3 100644 --- a/src/plugins/texteditor/formattexteditor.cpp +++ b/src/plugins/texteditor/formattexteditor.cpp @@ -12,8 +12,9 @@ #include <utils/async.h> #include <utils/differ.h> -#include <utils/qtcprocess.h> +#include <utils/expected.h> #include <utils/qtcassert.h> +#include <utils/qtcprocess.h> #include <utils/temporarydirectory.h> #include <utils/textutils.h> @@ -27,18 +28,17 @@ using namespace std::chrono_literals; namespace TextEditor { -class FormatTask +struct FormatInput { -public: Utils::FilePath filePath; QString sourceData; TextEditor::Command command; int startPos = -1; int endPos = 0; - QString formattedData = {}; - QString error = {}; }; +using FormatOutput = expected_str<QString>; + void formatCurrentFile(const Command &command, int startPos, int endPos) { if (TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget()) @@ -52,89 +52,80 @@ static QString sourceData(TextEditorWidget *editor, int startPos, int endPos) : Utils::Text::textAt(editor->textCursor(), startPos, (endPos - startPos)); } -static FormatTask format(FormatTask task) +static FormatOutput format(const FormatInput &input) { - task.error.clear(); - task.formattedData.clear(); - - const FilePath executable = task.command.executable(); + const FilePath executable = input.command.executable(); if (executable.isEmpty()) - return task; + return {}; - switch (task.command.processing()) { + switch (input.command.processing()) { case Command::FileProcessing: { // Save text to temporary file Utils::TempFileSaver sourceFile(Utils::TemporaryDirectory::masterDirectoryPath() - + "/qtc_beautifier_XXXXXXXX." - + task.filePath.suffix()); + + "/qtc_beautifier_XXXXXXXX." + input.filePath.suffix()); sourceFile.setAutoRemove(true); - sourceFile.write(task.sourceData.toUtf8()); + sourceFile.write(input.sourceData.toUtf8()); if (!sourceFile.finalize()) { - task.error = Tr::tr("Cannot create temporary file \"%1\": %2.") - .arg(sourceFile.filePath().toUserOutput(), sourceFile.errorString()); - return task; + return Utils::make_unexpected(Tr::tr("Cannot create temporary file \"%1\": %2.") + .arg(sourceFile.filePath().toUserOutput(), sourceFile.errorString())); } // Format temporary file - QStringList options = task.command.options(); + QStringList options = input.command.options(); options.replaceInStrings(QLatin1String("%file"), sourceFile.filePath().toString()); Process process; process.setCommand({executable, options}); process.runBlocking(5s); if (process.result() != ProcessResult::FinishedWithSuccess) { - task.error = Tr::tr("Failed to format: %1.").arg(process.exitMessage()); - return task; + return Utils::make_unexpected(Tr::tr("Failed to format: %1.") + .arg(process.exitMessage())); } const QString output = process.cleanedStdErr(); if (!output.isEmpty()) - task.error = executable.toUserOutput() + ": " + output; + return Utils::make_unexpected(executable.toUserOutput() + ": " + output); // Read text back Utils::FileReader reader; if (!reader.fetch(sourceFile.filePath(), QIODevice::Text)) { - task.error = Tr::tr("Cannot read file \"%1\": %2.") - .arg(sourceFile.filePath().toUserOutput(), reader.errorString()); - return task; + return Utils::make_unexpected(Tr::tr("Cannot read file \"%1\": %2.") + .arg(sourceFile.filePath().toUserOutput(), reader.errorString())); } - task.formattedData = QString::fromUtf8(reader.data()); + return QString::fromUtf8(reader.data()); } - return task; case Command::PipeProcessing: { Process process; - QStringList options = task.command.options(); - options.replaceInStrings("%filename", task.filePath.fileName()); - options.replaceInStrings("%file", task.filePath.toString()); + QStringList options = input.command.options(); + options.replaceInStrings("%filename", input.filePath.fileName()); + options.replaceInStrings("%file", input.filePath.toString()); process.setCommand({executable, options}); - process.setWriteData(task.sourceData.toUtf8()); + process.setWriteData(input.sourceData.toUtf8()); process.start(); if (!process.waitForFinished(5s)) { - task.error = Tr::tr("Cannot call %1 or some other error occurred. Timeout " - "reached while formatting file %2.") - .arg(executable.toUserOutput(), task.filePath.displayName()); - return task; + return Utils::make_unexpected(Tr::tr("Cannot call %1 or some other error occurred. " + "Timeout reached while formatting file %2.") + .arg(executable.toUserOutput(), input.filePath.displayName())); } const QString errorText = process.readAllStandardError(); if (!errorText.isEmpty()) { - task.error = QString("%1: %2").arg(executable.toUserOutput(), errorText); - return task; + return Utils::make_unexpected(QString("%1: %2").arg(executable.toUserOutput(), + errorText)); } - task.formattedData = process.readAllStandardOutput(); + QString formattedData = process.readAllStandardOutput(); - if (task.command.pipeAddsNewline() && task.formattedData.endsWith('\n')) { - task.formattedData.chop(1); - if (task.formattedData.endsWith('\r')) - task.formattedData.chop(1); + if (input.command.pipeAddsNewline() && formattedData.endsWith('\n')) { + formattedData.chop(1); + if (formattedData.endsWith('\r')) + formattedData.chop(1); } - if (task.command.returnsCRLF()) - task.formattedData.replace("\r\n", "\n"); + if (input.command.returnsCRLF()) + formattedData.replace("\r\n", "\n"); - return task; + return formattedData; } } - - return task; + return {}; } /** @@ -268,28 +259,26 @@ static void showError(const QString &error) * Checks the state of @a task and if the formatting was successful calls updateEditorText() with * the respective members of @a task. */ -static void checkAndApplyTask(const QPointer<QPlainTextEdit> &textEditor, const FormatTask &task) +static void checkAndApplyTask(const QPointer<QPlainTextEdit> &textEditor, const FormatInput &input, + const FormatOutput &output) { - if (!task.error.isEmpty()) { - showError(task.error); + if (!output.has_value()) { + showError(output.error()); return; } - if (task.formattedData.isEmpty()) { - showError(Tr::tr("Could not format file %1.").arg(task.filePath.displayName())); + if (output->isEmpty()) { + showError(Tr::tr("Could not format file %1.").arg(input.filePath.displayName())); return; } if (!textEditor) { - showError(Tr::tr("File %1 was closed.").arg(task.filePath.displayName())); + showError(Tr::tr("File %1 was closed.").arg(input.filePath.displayName())); return; } - const QString formattedData = (task.startPos < 0) - ? task.formattedData - : QString(textEditor->toPlainText()).replace( - task.startPos, (task.endPos - task.startPos), task.formattedData); - + const QString formattedData = (input.startPos < 0) ? *output + : textEditor->toPlainText().replace(input.startPos, (input.endPos - input.startPos), *output); updateEditorText(textEditor, formattedData); } @@ -307,8 +296,8 @@ void formatEditor(TextEditorWidget *editor, const Command &command, int startPos const QString sd = sourceData(editor, startPos, endPos); if (sd.isEmpty()) return; - checkAndApplyTask(editor, - format({editor->textDocument()->filePath(), sd, command, startPos, endPos})); + const FormatInput input{editor->textDocument()->filePath(), sd, command, startPos, endPos}; + checkAndApplyTask(editor, input, format(input)); } /** @@ -322,19 +311,20 @@ void formatEditorAsync(TextEditorWidget *editor, const Command &command, int sta if (sd.isEmpty()) return; - auto watcher = new QFutureWatcher<FormatTask>; + auto watcher = new QFutureWatcher<FormatOutput>; const TextDocument *doc = editor->textDocument(); - QObject::connect(doc, &TextDocument::contentsChanged, watcher, &QFutureWatcher<FormatTask>::cancel); - QObject::connect(watcher, &QFutureWatcherBase::finished, - [watcher, editor = QPointer<QPlainTextEdit>(editor)] { + const FormatInput input{doc->filePath(), sd, command, startPos, endPos}; + QObject::connect(doc, &TextDocument::contentsChanged, watcher, + &QFutureWatcher<FormatOutput>::cancel); + QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, + [watcher, editor = QPointer<QPlainTextEdit>(editor), input] { if (watcher->isCanceled()) showError(Tr::tr("File was modified.")); else - checkAndApplyTask(editor, watcher->result()); + checkAndApplyTask(editor, input, watcher->result()); watcher->deleteLater(); }); - watcher->setFuture( - Utils::asyncRun(&format, FormatTask{doc->filePath(), sd, command, startPos, endPos})); + watcher->setFuture(Utils::asyncRun(&format, input)); } } // namespace TextEditor |