cspell 9.3.2 → 9.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,13 +12,13 @@ A Spell Checker for Code!
12
12
 
13
13
  <!--- @@inject: ../../static/sponsor.md --->
14
14
 
15
- - [![GitHub Sponsors](https://img.shields.io/badge/-black?style=social&logo=githubsponsors&label=GitHub%20Sponsor%3A%20Street%20Side%20Software)](https://github.com/sponsors/streetsidesoftware)
16
- - [![PayPal](https://img.shields.io/badge/-black?style=social&logo=paypal&label=PayPal%20Donate%3A%20Street%20Side%20Software)](https://www.paypal.com/donate/?hosted_button_id=26LNBP2Q6MKCY)
17
- - [![Open Collective](https://img.shields.io/badge/-black?style=social&logo=opencollective&label=Open%20Collective%3A%20CSpell)](https://opencollective.com/cspell)
15
+ [![GitHub Sponsors](https://img.shields.io/badge/-Street_Side_Software-black?style=for-the-badge&logo=githubsponsors&label=GitHub%20Sponsor%3A)](https://github.com/sponsors/streetsidesoftware)
18
16
 
19
- <!---
20
- - [![Patreon](https://img.shields.io/badge/-black?style=social&logo=patreon&label=Patreon%3A%20Street%20Side%20Software)](https://patreon.com/streetsidesoftware)
21
- --->
17
+ [![Open Collective](https://img.shields.io/badge/-CSpell-black?style=for-the-badge&logo=opencollective&label=Open%20Collective%3A)](https://opencollective.com/cspell)
18
+
19
+ [![Street Side Software](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fstreetsidesoftware%2Fcspell%2Frefs%2Fheads%2Fmain%2Fstatic%2Fcspell-badge.json)](https://streetsidesoftware.com/sponsor/)
20
+
21
+ [![PayPal](https://img.shields.io/badge/-Street_Side_Software-black?style=for-the-badge&logo=paypal&label=PayPal%20Donate%3A)](https://www.paypal.com/donate/?hosted_button_id=26LNBP2Q6MKCY)
22
22
 
23
23
  <!--- @@inject-end: ../../static/sponsor.md --->
24
24
 
@@ -146,7 +146,8 @@ Options:
146
146
  the files being checked. Useful for limiting
147
147
  config inheritance.
148
148
  -v, --verbose Display more information about the files being
149
- checked and the configuration.
149
+ checked. Add more than one -v for increased
150
+ verbosity.
150
151
  --locale <locale> Set language locales. i.e. "en,fr" for English
151
152
  and French, or "en-GB" for British English.
152
153
  --language-id <file-type> Force programming language for unknown
@@ -196,6 +197,8 @@ Options:
196
197
  --gitignore-root <path> Prevent searching for .gitignore files past
197
198
  root.
198
199
  --validate-directives Validate in-document CSpell directives.
200
+ --max-file-size <size> Prevent checking large files. i.e 1MB, 50KB,
201
+ 1GB
199
202
  --color Force color.
200
203
  --no-color Turn off color.
201
204
  --no-default-configuration Do not load the default configuration and
@@ -566,6 +569,9 @@ _cspell_'s behavior can be controlled through a config file. By default it looks
566
569
  - `cspell.config.js`
567
570
  - `cspell.config.cjs`
568
571
  - `cspell.config.mjs`
572
+ - `cspell.config.ts`
573
+ - `cspell.config.cts`
574
+ - `cspell.config.mts`
569
575
  - `cspell.config.json`
570
576
  - `cspell.config.yaml`
571
577
  - `cspell.config.yml`
@@ -0,0 +1,8 @@
1
+ let _cspell_cspell_types = require("@cspell/cspell-types");
2
+
3
+ Object.defineProperty(exports, 'defineConfig', {
4
+ enumerable: true,
5
+ get: function () {
6
+ return _cspell_cspell_types.defineConfig;
7
+ }
8
+ });
@@ -0,0 +1,2 @@
1
+ import { defineConfig } from "@cspell/cspell-types";
2
+ export { defineConfig };
package/dist/esm/app.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as LinterCliOptions } from "./options-BeJCICDB.js";
1
+ import { i as LinterCliOptions } from "./options-D_PtlSKK.js";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/util/errors.d.ts
package/dist/esm/app.js CHANGED
@@ -1,11 +1,9 @@
1
- import { a as parseApplicationFeatureFlags, c as listDictionaries, d as npmPackage, h as console, i as lint, l as ReportChoicesAll, m as CheckFailed, n as checkText, o as suggestions, p as ApplicationError, r as createInit, s as trace, t as IncludeExcludeFlag, u as DEFAULT_CACHE_LOCATION } from "./application-CGIx5L0D.js";
2
- import { Option, program } from "commander";
3
- import { satisfies } from "semver";
4
- import chalk from "chalk";
1
+ import { C as CheckFailed, S as ApplicationError, _ as padLeft, a as parseApplicationFeatureFlags, b as pruneAnsiTextStart, c as listDictionaries, d as validateUnitSize, f as unindent, g as tableToLines, i as lint, l as ReportChoicesAll, m as npmPackage, n as checkText, o as suggestions, p as DEFAULT_CACHE_LOCATION, r as createInit, s as trace, t as IncludeExcludeFlag, u as cvtLinterCliCommandOptionsToLinterCliOptions, v as padWidth, w as console, x as width, y as pruneAnsiTextEnd } from "./application-BJHh60xM.js";
5
2
  import { Link } from "cspell-lib";
6
- import assert from "node:assert";
7
- import { stripVTControlCharacters } from "node:util";
3
+ import chalk from "chalk";
8
4
  import * as iPath from "node:path";
5
+ import { Option, program } from "commander";
6
+ import { satisfies } from "semver";
9
7
 
10
8
  //#region src/commandCheck.ts
11
9
  function commandCheck(prog) {
@@ -42,7 +40,7 @@ function commandCheck(prog) {
42
40
  * @param previous the previous values.
43
41
  * @returns the new values appended to the previous values.
44
42
  */
45
- function collect(value, previous) {
43
+ function collect$1(value, previous) {
46
44
  const values = Array.isArray(value) ? value : [value];
47
45
  return previous ? [...previous, ...values] : values;
48
46
  }
@@ -61,257 +59,6 @@ function crOpt(name, description, parseArg, defaultValue) {
61
59
  return option;
62
60
  }
63
61
 
64
- //#endregion
65
- //#region src/util/pad.ts
66
- function pad(s, w) {
67
- const p = padWidth(s, w);
68
- if (!p) return s;
69
- return s.padEnd(p + s.length);
70
- }
71
- function padWidth(s, target) {
72
- const sWidth = ansiWidth(s);
73
- return Math.max(target - sWidth, 0);
74
- }
75
- function padLeft(s, w) {
76
- const p = padWidth(s, w);
77
- if (!p) return s;
78
- return s.padStart(p + s.length);
79
- }
80
- function isAnsiString(s) {
81
- return s.includes("\x1B") || s.includes("›");
82
- }
83
- function width(s) {
84
- assert(!s.includes("\x1B"), "String contains ANSI control characters");
85
- return s.replaceAll(/[\u0000-\u001F\u0300-\u036F]/g, "").replaceAll(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, ".").replaceAll("…", ".").replaceAll(/\p{M}/gu, "").length;
86
- }
87
- function ansiWidth(s) {
88
- return width(stripVTControlCharacters(s));
89
- }
90
- /**
91
- * Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
92
- * @param str - the text to prune - ANSI is not supported
93
- * @param maxWidth - the maximum width of the text
94
- * @param pad - the string to use for padding, default is '…'
95
- * @returns the pruned text
96
- */
97
- function pruneTextEnd(str, maxWidth$2, pad$1 = "…") {
98
- if (!maxWidth$2 || maxWidth$2 <= 0) return str;
99
- if (str.length <= maxWidth$2) return str;
100
- if (isAnsiString(str)) return pruneAnsiTextEnd(str, maxWidth$2, pad$1);
101
- const maxWidthWithPad = maxWidth$2 - width(pad$1);
102
- const letters = [...str];
103
- let len = 0;
104
- for (let i = 0; i < letters.length; i++) {
105
- const c = letters[i];
106
- len += width(c);
107
- if (len > maxWidthWithPad) {
108
- let j = i + 1;
109
- while (j < letters.length && width(letters[j]) === 0) ++j;
110
- return j === letters.length ? str : letters.slice(0, i).join("") + pad$1;
111
- }
112
- }
113
- return str;
114
- }
115
- /**
116
- * Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
117
- * @param str - the text to prune - ANSI is not supported
118
- * @param maxWidth - the maximum width of the text
119
- * @param pad - the string to use for padding, default is '…'
120
- * @returns the pruned text
121
- */
122
- function pruneTextStart(str, maxWidth$2, pad$1 = "…") {
123
- if (!maxWidth$2 || maxWidth$2 <= 0) return str;
124
- if (str.length <= maxWidth$2) return str;
125
- const maxWidthWithPad = maxWidth$2 - width(pad$1);
126
- const letters = [...str];
127
- let len = 0;
128
- for (let i = letters.length - 1; i >= 1; i--) {
129
- const c = letters[i];
130
- len += width(c);
131
- if (len > maxWidthWithPad) {
132
- i += 1;
133
- while (i < letters.length && width(letters[i]) === 0) ++i;
134
- return pad$1 + letters.slice(i).join("");
135
- }
136
- }
137
- return str;
138
- }
139
- const ansi = new RegExp("[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))", "g");
140
- function parseAnsiStr(str) {
141
- const fragments = [];
142
- let lastIndex = 0;
143
- for (const match of str.matchAll(ansi)) {
144
- if (match.index > lastIndex) fragments.push({
145
- type: "text",
146
- text: str.slice(lastIndex, match.index)
147
- });
148
- fragments.push({
149
- type: "ansi",
150
- text: match[0]
151
- });
152
- lastIndex = match.index + match[0].length;
153
- }
154
- if (lastIndex < str.length) fragments.push({
155
- type: "text",
156
- text: str.slice(lastIndex)
157
- });
158
- return fragments;
159
- }
160
- /**
161
- * Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
162
- * @param str - the text to prune - ANSI is supported
163
- * @param maxWidth - the maximum width of the text
164
- * @param pad - the string to use for padding, default is '…'
165
- * @returns the pruned text
166
- */
167
- function pruneAnsiTextEnd(str, maxWidth$2, pad$1 = "…") {
168
- if (!maxWidth$2 || maxWidth$2 <= 0) return str;
169
- if (str.length <= maxWidth$2) return str;
170
- if (ansiWidth(str) <= maxWidth$2) return str;
171
- const padWidth$1 = ansiWidth(pad$1);
172
- const fragments = parseAnsiStr(str);
173
- let remaining = maxWidth$2 - padWidth$1;
174
- for (const frag of fragments) {
175
- if (frag.type !== "text") continue;
176
- if (remaining <= 0) {
177
- frag.text = "";
178
- continue;
179
- }
180
- const pruned = pruneTextEnd(frag.text, remaining, pad$1);
181
- if (pruned !== frag.text) {
182
- frag.text = pruned;
183
- remaining = 0;
184
- continue;
185
- }
186
- remaining -= width(frag.text);
187
- }
188
- return fragments.map((frag) => frag.text).join("");
189
- }
190
- /**
191
- * Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
192
- * @param str - the text to prune - ANSI is supported
193
- * @param maxWidth - the maximum width of the text
194
- * @param pad - the string to use for padding, default is '…'
195
- * @returns the pruned text
196
- */
197
- function pruneAnsiTextStart(str, maxWidth$2, pad$1 = "…") {
198
- if (!maxWidth$2 || maxWidth$2 <= 0) return str;
199
- if (str.length <= maxWidth$2) return str;
200
- if (ansiWidth(str) <= maxWidth$2) return str;
201
- const padWidth$1 = ansiWidth(pad$1);
202
- const fragments = parseAnsiStr(str);
203
- let remaining = maxWidth$2 - padWidth$1;
204
- for (const frag of fragments.reverse()) {
205
- if (frag.type !== "text") continue;
206
- if (remaining <= 0) {
207
- frag.text = "";
208
- continue;
209
- }
210
- const pruned = pruneTextStart(frag.text, remaining, pad$1);
211
- if (pruned !== frag.text) {
212
- frag.text = pruned;
213
- remaining = 0;
214
- continue;
215
- }
216
- remaining -= width(frag.text);
217
- }
218
- return fragments.reverse().map((frag) => frag.text).join("");
219
- }
220
-
221
- //#endregion
222
- //#region src/util/table.ts
223
- function tableToLines(table, deliminator) {
224
- const del = deliminator || table.deliminator || " | ";
225
- const columnWidths = [];
226
- const maxColumnWidthsMap = table.maxColumnWidths || {};
227
- const { header, rows } = table;
228
- const simpleHeader = header.map((col) => Array.isArray(col) ? col[1] : col);
229
- const columnFieldNames = header.map((col) => Array.isArray(col) ? col[0] : col);
230
- const maxColumnWidths = columnFieldNames.map((field, idx) => maxColumnWidthsMap[field] ?? maxColumnWidthsMap[idx]);
231
- function getCell(row, col) {
232
- return getCellFromRow(rows[row], col);
233
- }
234
- function getCellFromRow(row, col) {
235
- if (!row) return void 0;
236
- if (Array.isArray(row)) return row[col];
237
- return row[columnFieldNames[col]];
238
- }
239
- function rowToCells(row) {
240
- if (Array.isArray(row)) return row;
241
- return columnFieldNames.map((fieldName) => row[fieldName]);
242
- }
243
- function getText(col, maxWidth$2) {
244
- return !col ? "" : typeof col === "string" ? pruneTextEnd(col, maxWidth$2) : col(maxWidth$2);
245
- }
246
- function getRCText(row, col, maxWidth$2) {
247
- return getText(getCell(row, col), maxWidth$2);
248
- }
249
- function recordHeaderWidths(header$1) {
250
- header$1.forEach((col, idx) => {
251
- columnWidths[idx] = Math.max(ansiWidth(col), columnWidths[idx] || 0);
252
- });
253
- }
254
- function recordColWidths() {
255
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) for (let colIndex = 0; colIndex < columnFieldNames.length; colIndex++) columnWidths[colIndex] = Math.max(ansiWidth(getRCText(rowIndex, colIndex, void 0)), columnWidths[colIndex] || 0);
256
- }
257
- function justifyRow(c, i) {
258
- return pad(c, columnWidths[i]);
259
- }
260
- function toHeaderLine(header$1) {
261
- return decorateRowWith(header$1.map((c, i) => getText(c, columnWidths[i])), justifyRow, headerDecorator).join(del);
262
- }
263
- function toLine(row) {
264
- return decorateRowWith(rowToCells(row).map((c, i) => getText(c, columnWidths[i])), justifyRow).join(del);
265
- }
266
- function* process$1() {
267
- yield toHeaderLine(simpleHeader);
268
- yield* rows.map(toLine);
269
- }
270
- function sumColumnWidths() {
271
- return columnWidths.reduce((sum, width$1) => sum + width$1, 0);
272
- }
273
- function adjustColWidths() {
274
- for (let i = 0; i < columnWidths.length; i++) {
275
- const mw = maxColumnWidths[i];
276
- if (!mw) continue;
277
- columnWidths[i] = Math.min(columnWidths[i], mw);
278
- }
279
- if (!table.terminalWidth) return;
280
- const dWidth = (columnWidths.length - 1) * ansiWidth(del);
281
- const lineWidth = table.terminalWidth - dWidth;
282
- if (lineWidth <= columnWidths.length * 2) {
283
- const fixedWidth = Math.max(Math.min(...columnWidths), 5);
284
- for (let i = 0; i < columnWidths.length; i++) columnWidths[i] = fixedWidth;
285
- return;
286
- }
287
- if (columnWidths.length === 1) {
288
- columnWidths[0] = lineWidth;
289
- return;
290
- }
291
- function trimWidestColumn(neededToTrim) {
292
- let first = 0;
293
- let second = 0;
294
- for (let i = 0; i < columnWidths.length; i++) if (columnWidths[i] > columnWidths[first]) {
295
- second = first;
296
- first = i;
297
- } else if (columnWidths[i] > columnWidths[second]) second = i;
298
- const diff$1 = Math.max(columnWidths[first] - columnWidths[second], 1);
299
- columnWidths[first] -= Math.min(diff$1, neededToTrim);
300
- }
301
- for (let sum = sumColumnWidths(); sum > lineWidth; sum = sumColumnWidths()) trimWidestColumn(sum - lineWidth);
302
- }
303
- recordHeaderWidths(simpleHeader);
304
- recordColWidths();
305
- adjustColWidths();
306
- return [...process$1()];
307
- }
308
- function headerDecorator(t) {
309
- return chalk.bold(chalk.underline(t));
310
- }
311
- function decorateRowWith(row, ...decorators) {
312
- return decorators.reduce((row$1, decorator) => row$1.map(decorator), row);
313
- }
314
-
315
62
  //#endregion
316
63
  //#region src/emitters/helpers.ts
317
64
  function trimMidPath(s, w, sep$1) {
@@ -354,13 +101,13 @@ function trimMid(s, w) {
354
101
  const r = Math.ceil((w - 1) / 2);
355
102
  return s.slice(0, l) + "…" + s.slice(-r);
356
103
  }
357
- function formatDictionaryLocation(dictSource, maxWidth$2, { cwd, dictionaryPathFormat: format$1, iPath: iPath$1 }) {
104
+ function formatDictionaryLocation(dictSource, maxWidth$2, { cwd, dictionaryPathFormat: format, iPath: iPath$1 }) {
358
105
  let relPath = cwd ? iPath$1.relative(cwd, dictSource) : dictSource;
359
106
  const idxNodeModule = relPath.lastIndexOf("node_modules");
360
107
  const isNodeModule = idxNodeModule >= 0;
361
- if (format$1 === "hide") return "";
362
- if (format$1 === "short") return (isNodeModule ? "[node_modules]/" : relPath.startsWith(".." + iPath$1.sep + "..") ? "…/" : relPath.startsWith(".." + iPath$1.sep) ? "../" : "") + iPath$1.basename(dictSource);
363
- if (format$1 === "full") return dictSource;
108
+ if (format === "hide") return "";
109
+ if (format === "short") return (isNodeModule ? "[node_modules]/" : relPath.startsWith(".." + iPath$1.sep + "..") ? "…/" : relPath.startsWith(".." + iPath$1.sep) ? "../" : "") + iPath$1.basename(dictSource);
110
+ if (format === "full") return dictSource;
364
111
  relPath = isNodeModule ? relPath.slice(idxNodeModule) : relPath;
365
112
  return trimMidPath(relPath.length < dictSource.length ? relPath : dictSource, maxWidth$2, iPath$1.sep);
366
113
  }
@@ -485,7 +232,7 @@ function commandInit(prog) {
485
232
  "yml",
486
233
  "json",
487
234
  "jsonc"
488
- ]).default("yaml")).option("--import <path|package>", "Import a configuration file or dictionary package.", collect).option("--locale <locale>", "Define the locale to use when spell checking (e.g., en, en-US, de).").addOption(crOpt("--dictionary <dictionary>", "Enable a dictionary. Can be used multiple times.", collect).default(void 0)).addOption(crOpt("--comments", "Add comments to the config file.").default(void 0).hideHelp()).option("--no-comments", "Do not add comments to the config file.").addOption(crOpt("--remove-comments", "Remove all comments from the config file.").implies({ comments: false })).option("--no-schema", "Do not add the schema reference to the config file.").option("--stdout", "Write the configuration to stdout instead of a file.").action((options) => {
235
+ ]).default("yaml")).option("--import <path|package>", "Import a configuration file or dictionary package.", collect$1).option("--locale <locale>", "Define the locale to use when spell checking (e.g., en, en-US, de).").addOption(crOpt("--dictionary <dictionary>", "Enable a dictionary. Can be used multiple times.", collect$1).default(void 0)).addOption(crOpt("--comments", "Add comments to the config file.").default(void 0).hideHelp()).option("--no-comments", "Do not add comments to the config file.").addOption(crOpt("--remove-comments", "Remove all comments from the config file.").implies({ comments: false })).option("--no-schema", "Do not add the schema reference to the config file.").option("--stdout", "Write the configuration to stdout instead of a file.").action((options) => {
489
236
  return createInit(options);
490
237
  });
491
238
  }
@@ -555,60 +302,6 @@ function commandLink(prog) {
555
302
  return linkCommand;
556
303
  }
557
304
 
558
- //#endregion
559
- //#region src/util/unindent.ts
560
- /**
561
- * Inject values into a template string.
562
- * @param {TemplateStringsArray} template
563
- * @param {...any} values
564
- * @returns
565
- */
566
- function _inject(template, ...values) {
567
- const strings = template;
568
- const adjValues = [];
569
- for (let i = 0; i < values.length; ++i) {
570
- const prevLines = strings[i].split("\n");
571
- const currLine = prevLines[prevLines.length - 1];
572
- const padLen = padLength(currLine);
573
- const padding = " ".repeat(padLen);
574
- const value = `${values[i]}`;
575
- let pad$1 = "";
576
- const valueLines = [];
577
- for (const line of value.split("\n")) {
578
- valueLines.push(pad$1 + line);
579
- pad$1 = padding;
580
- }
581
- adjValues.push(valueLines.join("\n"));
582
- }
583
- return _unindent(String.raw({ raw: strings }, ...adjValues));
584
- }
585
- /**
586
- * Calculate the padding at the start of the string.
587
- * @param {string} s
588
- * @returns {number}
589
- */
590
- function padLength(s) {
591
- return s.length - s.trimStart().length;
592
- }
593
- function unindent(template, ...values) {
594
- if (typeof template === "string") return _unindent(template);
595
- return _inject(template, ...values);
596
- }
597
- /**
598
- * Remove the left padding from a multi-line string.
599
- * @param {string} str
600
- * @returns {string}
601
- */
602
- function _unindent(str) {
603
- const lines = str.split("\n");
604
- let curPad = str.length;
605
- for (const line of lines) {
606
- if (!line.trim()) continue;
607
- curPad = Math.min(curPad, padLength(line));
608
- }
609
- return lines.map((line) => line.slice(curPad)).join("\n");
610
- }
611
-
612
305
  //#endregion
613
306
  //#region src/commandLint.ts
614
307
  const usage = `\
@@ -661,24 +354,28 @@ References:
661
354
  `;
662
355
  function commandLint(prog, opts) {
663
356
  const spellCheckCommand = prog.command("lint", opts);
664
- spellCheckCommand.description("Check spelling").option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").addOption(crOpt("--config-search", "Allow searching for configuration files.", void 0).hideHelp()).option("--no-config-search", "Disable automatic searching for additional configuration files in parent directories. Only the specified config file (if any) will be used.").option("--stop-config-search-at <dir>", "Specify a directory at which to stop searching for configuration files when walking up from the files being checked. Useful for limiting config inheritance.", collect).option("-v, --verbose", "Display more information about the files being checked and the configuration.").option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <file-type>", "Force programming language for unknown extensions. i.e. \"php\" or \"scala\"").addOption(crOpt("--languageId <file-type>", "Alias of \"--language-id\". Force programming language for unknown extensions. i.e. \"php\" or \"scala\"").hideHelp()).option("--words-only", "Only output the words not found in the dictionaries.").addOption(crOpt("--wordsOnly", "Only output the words not found in the dictionaries.").hideHelp()).option("-u, --unique", "Only output the first instance of a word not found in the dictionaries.").option("-e, --exclude <glob>", "Exclude files matching the glob pattern. This option can be used multiple times to add multiple globs. ", collect).option("--file-list <path or stdin>", "Specify a list of files to be spell checked. The list is filtered against the glob file patterns. Note: the format is 1 file path per line.", collect).option("--file [file...]", "Specify files to spell check. They are filtered by the [globs...].", collect).addOption(crOpt("--files [file...]", "Alias of \"--file\". Files to spell check.", collect).hideHelp()).option("--no-issues", "Do not show the spelling errors.").option("--no-progress", "Turn off progress messages").option("--no-summary", "Turn off summary message in console.").option("-s, --silent", "Silent mode, suppress error messages.").option("--no-exit-code", "Do not return an exit code if issues are found.").addOption(crOpt("--quiet", "Only show spelling issues or errors.").implies({
357
+ spellCheckCommand.description("Check spelling").option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").addOption(crOpt("--config-search", "Allow searching for configuration files.", void 0).hideHelp()).option("--no-config-search", "Disable automatic searching for additional configuration files in parent directories. Only the specified config file (if any) will be used.").option("--stop-config-search-at <dir>", "Specify a directory at which to stop searching for configuration files when walking up from the files being checked. Useful for limiting config inheritance.", collect$1).option("-v, --verbose", "Display more information about the files being checked. Add more than one -v for increased verbosity.", increaseVerbosity, 0).option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <file-type>", "Force programming language for unknown extensions. i.e. \"php\" or \"scala\"").addOption(crOpt("--languageId <file-type>", "Alias of \"--language-id\". Force programming language for unknown extensions. i.e. \"php\" or \"scala\"").hideHelp()).option("--words-only", "Only output the words not found in the dictionaries.").addOption(crOpt("--wordsOnly", "Only output the words not found in the dictionaries.").hideHelp()).option("-u, --unique", "Only output the first instance of a word not found in the dictionaries.").option("-e, --exclude <glob>", "Exclude files matching the glob pattern. This option can be used multiple times to add multiple globs. ", collect$1).option("--file-list <path or stdin>", "Specify a list of files to be spell checked. The list is filtered against the glob file patterns. Note: the format is 1 file path per line.", collect$1).option("--file [file...]", "Specify files to spell check. They are filtered by the [globs...].", collect$1).addOption(crOpt("--files [file...]", "Alias of \"--file\". Files to spell check.", collect$1).hideHelp()).option("--no-issues", "Do not show the spelling errors.").option("--no-progress", "Turn off progress messages").option("--no-summary", "Turn off summary message in console.").option("-s, --silent", "Silent mode, suppress error messages.").option("--no-exit-code", "Do not return an exit code if issues are found.").addOption(crOpt("--quiet", "Only show spelling issues or errors.").implies({
665
358
  summary: false,
666
359
  progress: false
667
- })).option("--fail-fast", "Exit after first file with an issue or error.").addOption(crOpt("--no-fail-fast", "Process all files even if there is an error.").hideHelp()).option("--continue-on-error", "Continue processing files even if there is a configuration error.").option("-r, --root <root folder>", "Root directory, defaults to current directory.").addOption(crOpt("--relative", "Issues are displayed relative to the root.").default(true).hideHelp()).option("--no-relative", "Issues are displayed with absolute path instead of relative to the root.").option("--show-context", "Show the surrounding text around an issue.").option("--show-suggestions", "Show spelling suggestions.").addOption(crOpt("--no-show-suggestions", "Do not show spelling suggestions or fixes.").default(void 0)).addOption(crOpt("--must-find-files", "Error if no files are found.").default(true).hideHelp()).option("--no-must-find-files", "Do not error if no files are found.").addOption(crOpt("--legacy", "Legacy output").hideHelp()).addOption(crOpt("--local <local>", "Deprecated -- Use: --locale").hideHelp()).option("--cache", "Use cache to only check changed files.").option("--no-cache", "Do not use cache.").option("--cache-reset", "Reset the cache file.").addOption(crOpt("--cache-strategy <strategy>", "Strategy to use for detecting changed files.").choices(["content", "metadata"]).default("content")).option("--cache-location <path>", `Path to the cache file or directory. (default: "${DEFAULT_CACHE_LOCATION}")`).option("--dot", "Include files and directories starting with `.` (period) when matching globs.").option("--gitignore", "Ignore files matching glob patterns found in .gitignore files.").option("--no-gitignore", "Do NOT use .gitignore files.").option("--gitignore-root <path>", "Prevent searching for .gitignore files past root.", collect).option("--validate-directives", "Validate in-document CSpell directives.").addOption(crOpt("--no-validate-directives", "Do not validate in-document CSpell directives.").hideHelp()).addOption(crOpt("--color", "Force color.").default(void 0)).addOption(crOpt("--no-color", "Turn off color.").default(void 0)).addOption(crOpt("--default-configuration", "Load the default configuration and dictionaries.").hideHelp()).addOption(crOpt("--no-default-configuration", "Do not load the default configuration and dictionaries.")).option("--dictionary <name>", "Enable a dictionary by name.", collect).option("--disable-dictionary <name>", "Disable a dictionary by name.", collect).option("--reporter <module|path>", "Specify one or more reporters to use.", collect).addOption(crOpt("--report <level>", "Set how unknown words are reported").choices(ReportChoicesAll)).addOption(crOpt("--skip-validation", "Collect and process documents, but do not spell check.").implies({ cache: false }).hideHelp()).addOption(crOpt("--issues-summary-report", "Output a summary of issues found.").hideHelp()).addOption(crOpt("--show-perf-summary", "Output a performance summary report.").hideHelp()).option("--issue-template [template]", "Use a custom issue template. See --help --issue-template for details.").addOption(crOpt("--debug", "Output information useful for debugging cspell.json files.").hideHelp()).usage(usage).addHelpText("after", augmentCommandHelp).arguments("[globs...]").action(async (fileGlobs, options) => {
668
- const useExitCode = options.exitCode ?? true;
669
- if (options.skipValidation) options.cache = false;
670
- options.color ??= canUseColor(options.color);
671
- const { mustFindFiles, fileList, files, file } = options;
672
- const result = await lint(fileGlobs, options);
673
- if (!fileGlobs.length && !result.files && !result.errors && !fileList && !files?.length && !file?.length) {
674
- spellCheckCommand.outputHelp();
675
- throw new CheckFailed("outputHelp", 1);
676
- }
677
- if (result.errors || mustFindFiles && !result.files) throw new CheckFailed("check failed", 1);
678
- if (result.issues) throw new CheckFailed("check failed", useExitCode ? 1 : 0);
679
- });
360
+ })).option("--fail-fast", "Exit after first file with an issue or error.").addOption(crOpt("--no-fail-fast", "Process all files even if there is an error.").hideHelp()).option("--continue-on-error", "Continue processing files even if there is a configuration error.").option("-r, --root <root folder>", "Root directory, defaults to current directory.").addOption(crOpt("--relative", "Issues are displayed relative to the root.").default(true).hideHelp()).option("--no-relative", "Issues are displayed with absolute path instead of relative to the root.").option("--show-context", "Show the surrounding text around an issue.").option("--show-suggestions", "Show spelling suggestions.").addOption(crOpt("--no-show-suggestions", "Do not show spelling suggestions or fixes.").default(void 0)).addOption(crOpt("--must-find-files", "Error if no files are found.").default(true).hideHelp()).option("--no-must-find-files", "Do not error if no files are found.").addOption(crOpt("--legacy", "Legacy output").hideHelp()).addOption(crOpt("--local <local>", "Deprecated -- Use: --locale").hideHelp()).option("--cache", "Use cache to only check changed files.").option("--no-cache", "Do not use cache.").option("--cache-reset", "Reset the cache file.").addOption(crOpt("--cache-strategy <strategy>", "Strategy to use for detecting changed files.").choices(["content", "metadata"]).default("content")).option("--cache-location <path>", `Path to the cache file or directory. (default: "${DEFAULT_CACHE_LOCATION}")`).option("--dot", "Include files and directories starting with `.` (period) when matching globs.").option("--gitignore", "Ignore files matching glob patterns found in .gitignore files.").option("--no-gitignore", "Do NOT use .gitignore files.").option("--gitignore-root <path>", "Prevent searching for .gitignore files past root.", collect$1).option("--validate-directives", "Validate in-document CSpell directives.").addOption(crOpt("--no-validate-directives", "Do not validate in-document CSpell directives.").hideHelp()).option("--max-file-size <size>", "Prevent checking large files. i.e 1MB, 50KB, 1GB").addOption(crOpt("--color", "Force color.").default(void 0)).addOption(crOpt("--no-color", "Turn off color.").default(void 0)).addOption(crOpt("--default-configuration", "Load the default configuration and dictionaries.").hideHelp()).addOption(crOpt("--no-default-configuration", "Do not load the default configuration and dictionaries.")).option("--dictionary <name>", "Enable a dictionary by name.", collect$1).option("--disable-dictionary <name>", "Disable a dictionary by name.", collect$1).option("--reporter <module|path>", "Specify one or more reporters to use.", collect$1).addOption(crOpt("--report <level>", "Set how unknown words are reported").choices(ReportChoicesAll)).addOption(crOpt("--skip-validation", "Collect and process documents, but do not spell check.").implies({ cache: false }).hideHelp()).addOption(crOpt("--issues-summary-report", "Output a summary of issues found.").hideHelp()).addOption(crOpt("--show-perf-summary", "Output a performance summary report.").hideHelp()).option("--issue-template [template]", "Use a custom issue template. See --help --issue-template for details.").addOption(crOpt("--debug", "Output information useful for debugging cspell.json files.").hideHelp()).usage(usage).addHelpText("after", augmentCommandHelp).arguments("[globs...]").action(action);
680
361
  return spellCheckCommand;
681
362
  }
363
+ async function action(fileGlobs, cliOptions) {
364
+ const options = cvtLinterCliCommandOptionsToLinterCliOptions(cliOptions);
365
+ const useExitCode = options.exitCode ?? true;
366
+ if (options.skipValidation) options.cache = false;
367
+ options.color ??= canUseColor(options.color);
368
+ const maxFileSizeErr = validateMaxFileSize(options.maxFileSize);
369
+ if (maxFileSizeErr) this.error(`error: invalid option value for --max-file-size: ${maxFileSizeErr}`);
370
+ const { mustFindFiles, fileList, files, file } = options;
371
+ const result = await lint(fileGlobs, options);
372
+ if (!fileGlobs.length && !result.files && !result.errors && !fileList && !files?.length && !file?.length) {
373
+ this.outputHelp();
374
+ throw new CheckFailed("outputHelp", 1);
375
+ }
376
+ if (result.errors || mustFindFiles && !result.files) throw new CheckFailed("check failed", 1);
377
+ if (result.issues) throw new CheckFailed("check failed", useExitCode ? 1 : 0);
378
+ }
682
379
  function helpIssueTemplate(opts) {
683
380
  if (!("issueTemplate" in opts)) return "";
684
381
  return unindent`
@@ -733,6 +430,13 @@ function augmentCommandHelp(context) {
733
430
  output.push(...hiddenHelp, advanced);
734
431
  return helpIssueTemplate(opts) + output.join("\n");
735
432
  }
433
+ function validateMaxFileSize(size) {
434
+ if (!size) return void 0;
435
+ return validateUnitSize(size);
436
+ }
437
+ function increaseVerbosity(_dummyValue, previous) {
438
+ return previous + 1;
439
+ }
736
440
 
737
441
  //#endregion
738
442
  //#region src/emitters/suggestionsEmitter.ts
@@ -802,7 +506,7 @@ function formatWordSingle(s) {
802
506
 
803
507
  //#endregion
804
508
  //#region src/commandSuggestion.ts
805
- function collect$1(value, previous) {
509
+ function collect(value, previous) {
806
510
  value = value.replace(/^=/, "");
807
511
  if (!previous) return [value];
808
512
  return [...previous, value];
@@ -815,7 +519,7 @@ function asNumber(value, prev) {
815
519
  }
816
520
  function commandSuggestion(prog) {
817
521
  const suggestionCommand = prog.command("suggestions");
818
- suggestionCommand.aliases(["sug", "suggest"]).description("Spelling Suggestions for words.").option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <language>", "Use programming language. i.e. \"php\" or \"scala\".").addOption(new Option("--languageId <language>", "Use programming language. i.e. \"php\" or \"scala\".").hideHelp()).option("-s, --no-strict", "Ignore case and accents when searching for words.").option("--ignore-case", "Alias of --no-strict.").option("--num-changes <number>", "Number of changes allowed to a word", asNumber, 4).option("--num-suggestions <number>", "Number of suggestions", asNumber, 8).option("--no-include-ties", "Force the number of suggested to be limited, by not including suggestions that have the same edit cost.").option("--stdin", "Use stdin for input.").addOption(new Option("--repl", "REPL interface for looking up suggestions.")).option("-v, --verbose", "Show detailed output.", count, 0).option("-d, --dictionary <dictionary name>", "Use the dictionary specified. Only dictionaries specified will be used.", collect$1).option("--dictionaries <dictionary names...>", "Use the dictionaries specified. Only dictionaries specified will be used.").option("--no-color", "Turn off color.").option("--color", "Force color").arguments("[words...]").action(async (words, options) => {
522
+ suggestionCommand.aliases(["sug", "suggest"]).description("Spelling Suggestions for words.").option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <language>", "Use programming language. i.e. \"php\" or \"scala\".").addOption(new Option("--languageId <language>", "Use programming language. i.e. \"php\" or \"scala\".").hideHelp()).option("-s, --no-strict", "Ignore case and accents when searching for words.").option("--ignore-case", "Alias of --no-strict.").option("--num-changes <number>", "Number of changes allowed to a word", asNumber, 4).option("--num-suggestions <number>", "Number of suggestions", asNumber, 8).option("--no-include-ties", "Force the number of suggested to be limited, by not including suggestions that have the same edit cost.").option("--stdin", "Use stdin for input.").addOption(new Option("--repl", "REPL interface for looking up suggestions.")).option("-v, --verbose", "Show detailed output.", count, 0).option("-d, --dictionary <dictionary name>", "Use the dictionary specified. Only dictionaries specified will be used.", collect).option("--dictionaries <dictionary names...>", "Use the dictionaries specified. Only dictionaries specified will be used.").option("--no-color", "Turn off color.").option("--color", "Force color").arguments("[words...]").action(async (words, options) => {
819
523
  parseApplicationFeatureFlags(options.flag);
820
524
  options.useStdin = options.stdin;
821
525
  options.dictionaries = mergeArrays(options.dictionaries, options.dictionary);
@@ -917,7 +621,7 @@ function colorize(fn) {
917
621
  //#endregion
918
622
  //#region src/commandTrace.ts
919
623
  function commandTrace(prog) {
920
- return prog.command("trace").description(`Trace words -- Search for words in the configuration and dictionaries.`).option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <language>", "Use programming language. i.e. \"php\" or \"scala\".").addOption(new Option("--languageId <language>", "Use programming language. i.e. \"php\" or \"scala\".").hideHelp()).option("--allow-compound-words", "Turn on allowCompoundWords").addOption(new Option("--allowCompoundWords", "Turn on allowCompoundWords.").hideHelp()).option("--no-allow-compound-words", "Turn off allowCompoundWords").option("--ignore-case", "Ignore case and accents when searching for words.").option("--no-ignore-case", "Do not ignore case and accents when searching for words.").option("--dictionary <name>", "Enable a dictionary by name. Can be used multiple times.", collect).addOption(new Option("--dictionary-path <format>", "Configure how to display the dictionary path.").choices([
624
+ return prog.command("trace").description(`Trace words -- Search for words in the configuration and dictionaries.`).option("-c, --config <cspell.json>", "Configuration file to use. By default cspell looks for cspell.json in the current directory.").option("--locale <locale>", "Set language locales. i.e. \"en,fr\" for English and French, or \"en-GB\" for British English.").option("--language-id <language>", "Use programming language. i.e. \"php\" or \"scala\".").addOption(new Option("--languageId <language>", "Use programming language. i.e. \"php\" or \"scala\".").hideHelp()).option("--allow-compound-words", "Turn on allowCompoundWords").addOption(new Option("--allowCompoundWords", "Turn on allowCompoundWords.").hideHelp()).option("--no-allow-compound-words", "Turn off allowCompoundWords").option("--ignore-case", "Ignore case and accents when searching for words.").option("--no-ignore-case", "Do not ignore case and accents when searching for words.").option("--dictionary <name>", "Enable a dictionary by name. Can be used multiple times.", collect$1).addOption(new Option("--dictionary-path <format>", "Configure how to display the dictionary path.").choices([
921
625
  "hide",
922
626
  "short",
923
627
  "long",
@@ -974,7 +678,7 @@ function groupBy(items, key) {
974
678
  //#endregion
975
679
  //#region src/globalOptions.ts
976
680
  function addGlobalOptionsToAction(command) {
977
- command = command.addOption(new Option("-f,--flag <flag:value>", "Declare an execution flag value").hideHelp().argParser(collect));
681
+ command = command.addOption(new Option("-f,--flag <flag:value>", "Declare an execution flag value").hideHelp().argParser(collect$1));
978
682
  return command;
979
683
  }
980
684
  function addGlobalOptionsAndHooks(command) {