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 the attributes of the objects "
235 "according to the QML Coding Guidelines.")));
238 parser.addOption(QCommandLineOption(
239 {
"l"_L1,
"newline"_L1 },
240 QStringLiteral(
"Override the new line format to use (native macos unix windows)."),
241 "newline"_L1,
"native"_L1));
243 parser.addOption(QCommandLineOption(
244 QStringList() <<
"objects-spacing"_L1,
245 QStringLiteral(
"Ensure spaces between objects (only works with normalize option).")));
247 parser.addOption(QCommandLineOption(
248 QStringList() <<
"functions-spacing"_L1,
249 QStringLiteral(
"Ensure spaces between functions (only works with normalize option).")));
252 QCommandLineOption(QStringList() <<
"group-attributes-together"_L1,
253 QStringLiteral(
"Reorders and groups the attributes of the objects "
254 "according to the QML Coding Guidelines. "
255 "Implies --normalize.")));
258 QCommandLineOption({
"S"_L1,
"sort-imports"_L1 },
259 QStringLiteral(
"Sort imports alphabetically "
260 "(Warning: this might change semantics if a given "
261 "name identifies types in multiple modules!).")));
263 parser.addOption(QCommandLineOption(
264 QStringList() <<
"single-line-empty-objects"_L1,
265 QStringLiteral(
"Write empty objects on a single line (only works with normalize option).")));
267 QCommandLineOption semicolonRuleOption(
268 QStringList() <<
"semicolon-rule"_L1,
269 QStringLiteral(
"Specify the semicolon rule to use (always, essential).\n"
270 "always: always adds semicolon [default].\n"
271 "essential: adds only when ASI wouldn't be relied on."),
272 "rule"_L1,
"always"_L1);
273 parser.addOption(semicolonRuleOption);
275 parser.addPositionalArgument(
"filenames"_L1,
"files to be processed by qmlformat"_L1);
277 parser.process(args);
279 if (parser.isSet(writeDefaultsOption)) {
284 if (parser.isSet(outputOptionsOption)) {
289 if (parser.positionalArguments().empty() && !parser.isSet(filesOption)) {
290 options.addError(
"Error: Expected at least one input file."_L1);
294 bool indentWidthOkay =
false;
295 const int indentWidth = parser.value(
"indent-width"_L1).toInt(&indentWidthOkay);
296 if (!indentWidthOkay) {
297 options.addError(
"Error: Invalid value passed to -w"_L1);
302 if (!parser.value(
"files"_L1).isEmpty()) {
303 const QString path = parser.value(
"files"_L1);
305 if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) {
306 options.addError(
"Error: Could not open file \""_L1 + path +
"\" for option -F."_L1);
310 QTextStream in(&file);
311 while (!in.atEnd()) {
312 QString file = in.readLine();
317 files.push_back(file);
320 if (files.isEmpty()) {
321 options.addError(
"Error: File \""_L1 + path +
"\" for option -F is empty."_L1);
325 for (
const auto &file : std::as_const(files)) {
326 if (!QFile::exists(file)) {
327 options.addError(
"Error: Entry \""_L1 + file +
"\" of file \""_L1 + path
328 +
"\" passed to option -F could not be found."_L1);
333 const auto &args = parser.positionalArguments();
334 for (
const auto &file : args) {
335 if (!QFile::exists(file)) {
336 options.addError(
"Error: Could not find file \""_L1 + file +
"\"."_L1);
348 if (parser.isSet(
"tabs"_L1)) {
352 if (parser.isSet(
"normalize"_L1)) {
356 if (parser.isSet(
"objects-spacing"_L1)) {
360 if (parser.isSet(
"functions-spacing"_L1)) {
365 if (parser.isSet(
"group-attributes-together"_L1)) {
369 if (parser.isSet(
"sort-imports"_L1)) {
373 if (parser.isSet(
"single-line-empty-objects"_L1)) {
377 if (parser.isSet(
"indent-width"_L1)) {
382 if (parser.isSet(
"newline"_L1)) {
384 options
.setNewline(QQmlFormatOptions::parseEndings(parser.value(
"newline"_L1)));
387 if (parser.isSet(settingsOption)) {
389 const auto value = parser.value(settingsOption);
390 if (value.isEmpty()) {
391 options.addError(
"Error: No settings file specified for option -s."_L1);
394 if (!QFile::exists(value)) {
395 options.addError(
"Error: Could not find file \""_L1 + value +
"\"."_L1);
398 options.setSettingsFile(value);
401 if (parser.isSet(semicolonRuleOption)) {
403 const auto value = parser.value(semicolonRuleOption);
404 auto semicolonRule = parseSemicolonRule(value);
405 if (!semicolonRule.has_value()) {
406 options.addError(
"Error: Invalid value passed to --semicolon-rule. Must be 'always' or 'essential'."_L1);
409 options.setSemicolonRule(semicolonRule.value());
411 options.setFiles(files);
412 options.setArguments(parser.positionalArguments());
414 if (parser.isSet(columnWidthOption)) {
415 bool isValidValue =
false;
416 const int maxColumnWidth = parser.value(columnWidthOption).toInt(&isValidValue);
417 if (!isValidValue || maxColumnWidth < -1) {
418 options.addError(
"Error: Invalid value passed to -W. Must be an integer >= -1"_L1);