86 && settings.isSet(QQmlFormatSettings::s_indentWidthSetting)) {
87 setIndentWidth(settings.value(QQmlFormatSettings::s_indentWidthSetting).toInt()
);
90 if (!isMarked(
Settings::UseTabs) && settings.isSet(QQmlFormatSettings::s_useTabsSetting)) {
91 setTabsEnabled(settings.value(QQmlFormatSettings::s_useTabsSetting).toBool()
);
95 && settings.isSet(QQmlFormatSettings::s_maxColumnWidthSetting)) {
100 && settings.isSet(QQmlFormatSettings::s_normalizeSetting)) {
106 settings.value(QQmlFormatSettings::s_newlineSetting).toString()));
110 && settings.isSet(QQmlFormatSettings::s_objectsSpacingSetting)) {
115 && settings.isSet(QQmlFormatSettings::s_functionsSpacingSetting)) {
121 && settings.isSet(QQmlFormatSettings::s_groupAttributesTogetherSetting)) {
123 settings.value(QQmlFormatSettings::s_groupAttributesTogetherSetting).toBool()
);
127 && settings.isSet(QQmlFormatSettings::s_sortImportsSetting)) {
128 setSortImports(settings.value(QQmlFormatSettings::s_sortImportsSetting).toBool()
);
132 && settings.isSet(QQmlFormatSettings::s_singleLineEmptyObjectsSetting)) {
137 && settings.isSet(QQmlFormatSettings::s_semiColonRuleSetting)) {
138 const auto semicolonRule = parseSemicolonRule(
139 settings.value(QQmlFormatSettings::s_semiColonRuleSetting).toString());
140 if (!semicolonRule.has_value()) {
141 qWarning().noquote() <<
"Invalid semicolon rule in settings file, using 'always'";
142 setSemicolonRule(QQmlJS::Dom::LineWriterOptions::SemicolonRule::Always);
144 setSemicolonRule(semicolonRule.value());
152 QCommandLineParser parser;
153 parser.setApplicationDescription(
154 "Formats QML files according to the QML Coding Conventions.\n"_L1
155 "Options below the \"Formatting options\" section can also be set via .qmlformat.ini"_L1
156 " unless --ignore-settings is used"_L1);
157 parser.addHelpOption();
158 parser.addVersionOption();
164 QCommandLineOption({
"V"_L1,
"verbose"_L1 },
165 QStringLiteral(
"Verbose mode. Outputs more detailed information.")));
167 QCommandLineOption writeDefaultsOption(
168 QStringList() <<
"write-defaults"_L1,
169 QLatin1String(
"Writes defaults settings to .qmlformat.ini and exits (Warning: This "
170 "will overwrite any existing settings and comments!)"_L1));
171 parser.addOption(writeDefaultsOption);
173 QCommandLineOption outputOptionsOption(
174 QStringList() <<
"output-options"_L1,
175 QLatin1String(
"Output available options and their defaults values in JSON format."_L1));
176 parser.addOption(outputOptionsOption);
178 QCommandLineOption ignoreSettings(QStringList() <<
"ignore-settings"_L1,
179 QLatin1String(
"Ignores all settings files and only takes "
180 "command line options into consideration"_L1));
181 parser.addOption(ignoreSettings);
183 QCommandLineOption filesOption(
184 {
"F"_L1,
"files"_L1 },
"Format all files listed in file, in-place"_L1,
"file"_L1);
185 parser.addOption(filesOption);
188 QCommandLineOption dryrunOption(
189 QStringList() <<
"dry-run"_L1,
190 QStringLiteral(
"Prints the settings file that would be used for this instance."
191 "This is useful to see what settings would be used "
192 "without actually performing anything."));
193 parser.addOption(dryrunOption);
195 QCommandLineOption settingsOption(
196 {
"s"_L1,
"settings"_L1 },
197 QStringLiteral(
"Use the specified .qmlformat.ini file as the only configuration source."
198 "Overrides any per-directory configuration lookup."),
200 parser.addOption(settingsOption);
202 parser.addOption(QCommandLineOption(
203 {
"i"_L1,
"inplace"_L1 },
204 QStringLiteral(
"Edit file in-place instead of outputting to stdout.")));
208 parser.addOption(QCommandLineOption({
"f"_L1,
"force"_L1 },
210 "Continue even if an error has occurred.\n<><><><><><><><><>\nFormatting options\n<><><><><><><><><>"_L1
212 u"Continue even if an error has occurred.\n♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦\nFormatting options\n♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦"_s
220 parser.addOption(QCommandLineOption({
"t"_L1,
"tabs"_L1 },
221 QStringLiteral(
"Use tabs instead of spaces.")));
223 parser.addOption(QCommandLineOption({
"w"_L1,
"indent-width"_L1 },
224 QStringLiteral(
"How many spaces are used when indenting."),
225 "width"_L1,
"4"_L1));
227 QCommandLineOption columnWidthOption(
228 {
"W"_L1,
"column-width"_L1 },
229 QStringLiteral(
"Breaks the line into multiple lines if exceedes the specified width. "
230 "Use -1 to disable line wrapping. (default)"),
231 "width"_L1,
"-1"_L1);
232 parser.addOption(columnWidthOption);
233 parser.addOption(QCommandLineOption({
"n"_L1,
"normalize"_L1 },
234 QStringLiteral(
"Reorders and sorts the attributes of the objects "
235 "according to the QML Coding Guidelines. "
236 "Incompatible with --group-attributes-together.")));
239 parser.addOption(QCommandLineOption(
240 {
"l"_L1,
"newline"_L1 },
241 QStringLiteral(
"Override the new line format to use (native macos unix windows)."),
242 "newline"_L1,
"native"_L1));
244 parser.addOption(QCommandLineOption(
245 QStringList() <<
"objects-spacing"_L1,
246 QStringLiteral(
"Ensure spaces between objects (only works with normalize or group-attributes-together option).")));
248 parser.addOption(QCommandLineOption(
249 QStringList() <<
"functions-spacing"_L1,
250 QStringLiteral(
"Ensure spaces between functions (only works with normalize or group-attributes-together option).")));
253 QCommandLineOption(QStringList() <<
"group-attributes-together"_L1,
254 QStringLiteral(
"Reorders but does not sort the attributes of the objects "
255 "according to the QML Coding Guidelines. "
256 "Incompatible with --normalize.")));
259 QCommandLineOption({
"S"_L1,
"sort-imports"_L1 },
260 QStringLiteral(
"Sort imports alphabetically "
261 "(Warning: this might change semantics if a given "
262 "name identifies types in multiple modules!).")));
264 parser.addOption(QCommandLineOption(
265 QStringList() <<
"single-line-empty-objects"_L1,
266 QStringLiteral(
"Write empty objects on a single line (only works with normalize or group-attributes-together option).")));
268 QCommandLineOption semicolonRuleOption(
269 QStringList() <<
"semicolon-rule"_L1,
270 QStringLiteral(
"Specify the semicolon rule to use (always, essential).\n"
271 "always: always adds semicolon [default].\n"
272 "essential: adds only when ASI wouldn't be relied on."),
273 "rule"_L1,
"always"_L1);
274 parser.addOption(semicolonRuleOption);
276 parser.addPositionalArgument(
"filenames"_L1,
"files to be processed by qmlformat"_L1);
278 parser.process(args);
280 if (parser.isSet(writeDefaultsOption)) {
285 if (parser.isSet(outputOptionsOption)) {
290 if (parser.positionalArguments().empty() && !parser.isSet(filesOption)) {
291 options.addError(
"Error: Expected at least one input file."_L1);
295 bool indentWidthOkay =
false;
296 const int indentWidth = parser.value(
"indent-width"_L1).toInt(&indentWidthOkay);
297 if (!indentWidthOkay) {
298 options.addError(
"Error: Invalid value passed to -w"_L1);
303 if (!parser.value(
"files"_L1).isEmpty()) {
304 const QString path = parser.value(
"files"_L1);
306 if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) {
307 options.addError(
"Error: Could not open file \""_L1 + path +
"\" for option -F."_L1);
311 QTextStream in(&file);
312 while (!in.atEnd()) {
313 QString file = in.readLine();
318 files.push_back(file);
321 if (files.isEmpty()) {
322 options.addError(
"Error: File \""_L1 + path +
"\" for option -F is empty."_L1);
326 for (
const auto &file : std::as_const(files)) {
327 if (!QFile::exists(file)) {
328 options.addError(
"Error: Entry \""_L1 + file +
"\" of file \""_L1 + path
329 +
"\" passed to option -F could not be found."_L1);
334 const auto &args = parser.positionalArguments();
335 for (
const auto &file : args) {
336 if (!QFile::exists(file)) {
337 options.addError(
"Error: Could not find file \""_L1 + file +
"\"."_L1);
349 if (parser.isSet(
"tabs"_L1)) {
353 if (parser.isSet(
"normalize"_L1)) {
357 if (parser.isSet(
"objects-spacing"_L1)) {
361 if (parser.isSet(
"functions-spacing"_L1)) {
366 if (parser.isSet(
"group-attributes-together"_L1)) {
370 if (parser.isSet(
"sort-imports"_L1)) {
374 if (parser.isSet(
"single-line-empty-objects"_L1)) {
378 if (parser.isSet(
"indent-width"_L1)) {
383 if (parser.isSet(
"newline"_L1)) {
385 options
.setNewline(QQmlFormatOptions::parseEndings(parser.value(
"newline"_L1)));
388 if (parser.isSet(settingsOption)) {
390 const auto value = parser.value(settingsOption);
391 if (value.isEmpty()) {
392 options.addError(
"Error: No settings file specified for option -s."_L1);
395 if (!QFile::exists(value)) {
396 options.addError(
"Error: Could not find file \""_L1 + value +
"\"."_L1);
399 options.setSettingsFile(value);
402 if (parser.isSet(semicolonRuleOption)) {
404 const auto value = parser.value(semicolonRuleOption);
405 auto semicolonRule = parseSemicolonRule(value);
406 if (!semicolonRule.has_value()) {
407 options.addError(
"Error: Invalid value passed to --semicolon-rule. Must be 'always' or 'essential'."_L1);
410 options.setSemicolonRule(semicolonRule.value());
412 options.setFiles(files);
413 options.setArguments(parser.positionalArguments());
415 if (parser.isSet(columnWidthOption)) {
416 bool isValidValue =
false;
417 const int maxColumnWidth = parser.value(columnWidthOption).toInt(&isValidValue);
418 if (!isValidValue || maxColumnWidth < -1) {
419 options.addError(
"Error: Invalid value passed to -W. Must be an integer >= -1"_L1);