cspell 9.4.0 → 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 +9 -6
- package/dist/cjs/commonJsApi.cjs +8 -0
- package/dist/cjs/commonJsApi.d.cts +2 -0
- package/dist/esm/app.js +9 -120
- package/dist/esm/{application-DCyfKhGm.js → application-BJHh60xM.js} +671 -379
- package/dist/esm/application.js +1 -1
- package/dist/esm/index.js +1 -1
- package/package.json +19 -17
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { isAsyncIterable, opFilter, opMap, opTap, operators, pipeAsync, pipeAsync as asyncPipe, toAsyncIterable, toAsyncIterable as mergeAsyncIterables } from "@cspell/cspell-pipe";
|
|
3
3
|
import * as cspell from "cspell-lib";
|
|
4
|
-
import { ENV_CSPELL_GLOB_ROOT, IncludeExcludeFlag, SuggestionError, Text, checkTextDocument, combineTextAndLanguageSettings, createPerfTimer, extractDependencies, extractImportErrors, fileToDocument, getDefaultSettings, getDictionary, getGlobalSettingsAsync, getSystemFeatureFlags, isBinaryFile, isSpellingDictionaryLoadError, mergeSettings, setLogger, shouldCheckDocument, spellCheckDocument, suggestionsForWords, traceWordsAsync } from "cspell-lib";
|
|
4
|
+
import { ENV_CSPELL_GLOB_ROOT, IncludeExcludeFlag, MessageTypes, SuggestionError, Text, checkTextDocument, combineTextAndLanguageSettings, createPerfTimer, extractDependencies, extractImportErrors, fileToDocument, getDefaultSettings, getDictionary, getGlobalSettingsAsync, getSystemFeatureFlags, isBinaryFile, isSpellingDictionaryLoadError, mergeSettings, setLogger, shouldCheckDocument, spellCheckDocument, suggestionsForWords, traceWordsAsync } from "cspell-lib";
|
|
5
5
|
import assert from "node:assert";
|
|
6
6
|
import { format, formatWithOptions, stripVTControlCharacters } from "node:util";
|
|
7
7
|
import { isUrlLike, toFileDirURL, toFilePathOrHref, toFileURL, urlRelative } from "@cspell/url";
|
|
8
8
|
import chalk, { Chalk } from "chalk";
|
|
9
9
|
import { makeTemplate } from "chalk-template";
|
|
10
|
+
import ansiRegex from "ansi-regex";
|
|
10
11
|
import fs, { stat } from "node:fs/promises";
|
|
11
12
|
import { MutableCSpellConfigFile, createReaderWriter, cspellConfigFileSchema, isCfgArrayNode } from "cspell-config-lib";
|
|
12
13
|
import { promises } from "node:fs";
|
|
@@ -14,8 +15,8 @@ import { fileURLToPath } from "node:url";
|
|
|
14
15
|
import * as path$1 from "node:path";
|
|
15
16
|
import path, { isAbsolute, posix, relative, resolve, sep } from "node:path";
|
|
16
17
|
import { opMap as opMap$1, pipe } from "@cspell/cspell-pipe/sync";
|
|
17
|
-
import { IssueType, MessageTypes, unknownWordsChoices } from "@cspell/cspell-types";
|
|
18
|
-
import {
|
|
18
|
+
import { IssueType, MessageTypes as MessageTypes$1, unknownWordsChoices } from "@cspell/cspell-types";
|
|
19
|
+
import { dictionaryCacheEnableLogging, dictionaryCacheGetLog } from "cspell-dictionary";
|
|
19
20
|
import { GitIgnore, findRepoRoot } from "cspell-gitignore";
|
|
20
21
|
import { GlobMatcher, fileOrGlobToGlob, workaroundPicomatchBug } from "cspell-glob";
|
|
21
22
|
import crypto from "node:crypto";
|
|
@@ -25,7 +26,6 @@ import { glob } from "tinyglobby";
|
|
|
25
26
|
import * as readline from "node:readline";
|
|
26
27
|
import { parse, stringify } from "flatted";
|
|
27
28
|
import { dynamicImport } from "@cspell/dynamic-import";
|
|
28
|
-
import ansiRegex from "ansi-regex";
|
|
29
29
|
|
|
30
30
|
//#region src/console.ts
|
|
31
31
|
var ImplChannel = class {
|
|
@@ -89,7 +89,7 @@ var IOError = class extends ApplicationError {
|
|
|
89
89
|
return this.cause.code === "ENOENT";
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
|
-
function toError(e) {
|
|
92
|
+
function toError$1(e) {
|
|
93
93
|
if (isError(e)) return e;
|
|
94
94
|
if (isErrorLike(e)) {
|
|
95
95
|
const ex = new Error(e.message, { cause: e });
|
|
@@ -109,10 +109,349 @@ function isErrorLike(e) {
|
|
|
109
109
|
}
|
|
110
110
|
function toApplicationError(e, message) {
|
|
111
111
|
if (e instanceof ApplicationError && !message) return e;
|
|
112
|
-
const err = toError(e);
|
|
112
|
+
const err = toError$1(e);
|
|
113
113
|
return new ApplicationError(message ?? err.message, void 0, err);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/util/perfMeasurements.ts
|
|
118
|
+
function getPerfMeasurements() {
|
|
119
|
+
const measurements = performance.getEntriesByType("measure");
|
|
120
|
+
const root = {
|
|
121
|
+
depth: -1,
|
|
122
|
+
totalTimeMs: 0,
|
|
123
|
+
nestedTimeMs: 0,
|
|
124
|
+
children: /* @__PURE__ */ new Map()
|
|
125
|
+
};
|
|
126
|
+
if (!measurements.length) return [];
|
|
127
|
+
const stack = [];
|
|
128
|
+
let depth = 0;
|
|
129
|
+
for (let i = 0; i < measurements.length; i++) {
|
|
130
|
+
const m = measurements[i];
|
|
131
|
+
rollUpStack(m.startTime);
|
|
132
|
+
const s = {
|
|
133
|
+
m,
|
|
134
|
+
p: addToParent(depth === 0 ? root : stack[depth - 1].p, m)
|
|
135
|
+
};
|
|
136
|
+
stack[depth++] = s;
|
|
137
|
+
}
|
|
138
|
+
sortChildren(root);
|
|
139
|
+
return [...root.children.values()].flatMap((r) => [...flattenChildren(r)]);
|
|
140
|
+
function contains(m, t) {
|
|
141
|
+
const stop = m.startTime + m.duration;
|
|
142
|
+
return t >= m.startTime && t < stop;
|
|
143
|
+
}
|
|
144
|
+
function rollUpStack(t) {
|
|
145
|
+
for (; depth > 0 && !contains(stack[depth - 1].m, t); --depth);
|
|
146
|
+
}
|
|
147
|
+
function addToParent(p, m) {
|
|
148
|
+
p.children ??= /* @__PURE__ */ new Map();
|
|
149
|
+
p.nestedTimeMs += m.duration;
|
|
150
|
+
return updateChild(p.children, m, p.depth + 1);
|
|
151
|
+
}
|
|
152
|
+
function updateChild(children, m, depth$1) {
|
|
153
|
+
const p = children.get(m.name);
|
|
154
|
+
if (p) {
|
|
155
|
+
p.totalTimeMs += m.duration;
|
|
156
|
+
p.count += 1;
|
|
157
|
+
p.minTimeMs = Math.min(p.minTimeMs, m.duration);
|
|
158
|
+
p.maxTimeMs = Math.max(p.maxTimeMs, m.duration);
|
|
159
|
+
return p;
|
|
160
|
+
}
|
|
161
|
+
const n = {
|
|
162
|
+
name: m.name,
|
|
163
|
+
depth: depth$1,
|
|
164
|
+
totalTimeMs: m.duration,
|
|
165
|
+
nestedTimeMs: 0,
|
|
166
|
+
count: 1,
|
|
167
|
+
minTimeMs: m.duration,
|
|
168
|
+
maxTimeMs: m.duration
|
|
169
|
+
};
|
|
170
|
+
children.set(m.name, n);
|
|
171
|
+
return n;
|
|
172
|
+
}
|
|
173
|
+
function* flattenChildren(m) {
|
|
174
|
+
yield m;
|
|
175
|
+
if (!m.children) return;
|
|
176
|
+
for (const child of m.children.values()) yield* flattenChildren(child);
|
|
177
|
+
}
|
|
178
|
+
function sortChildren(m) {
|
|
179
|
+
if (!m.children) return;
|
|
180
|
+
m.children = new Map([...m.children.entries()].sort((a, b) => b[1].totalTimeMs - a[1].totalTimeMs));
|
|
181
|
+
m.children.forEach(sortChildren);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region src/util/ansi.ts
|
|
187
|
+
function isAnsiString(s) {
|
|
188
|
+
return s.includes("\x1B") || s.includes("");
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
*
|
|
192
|
+
* @param s - the string to measure - should NOT contains ANSI codes
|
|
193
|
+
* @param tabWidth -
|
|
194
|
+
* @returns
|
|
195
|
+
*/
|
|
196
|
+
function width(s, tabWidth = 1) {
|
|
197
|
+
return s.replaceAll("…", ".").replaceAll(" ", " ".repeat(tabWidth)).replaceAll(/\p{M}/gu, "").replaceAll(/\p{L}/gu, ".").replaceAll(/[\u0000-\u001F\u0300-\u036F]/g, "").replaceAll(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, ".").length;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Measure the width of a string containing ANSI control characters.
|
|
201
|
+
* @param s - string to measure with width in characters.
|
|
202
|
+
* @returns the approximate number of screen characters.
|
|
203
|
+
*/
|
|
204
|
+
function ansiWidth(s) {
|
|
205
|
+
return width(stripVTControlCharacters(s));
|
|
206
|
+
}
|
|
207
|
+
function fragmentString(str, splitOnRegex, sType) {
|
|
208
|
+
const fragments = [];
|
|
209
|
+
let lastIndex = 0;
|
|
210
|
+
for (const match of str.matchAll(new RegExp(splitOnRegex))) {
|
|
211
|
+
if (match.index > lastIndex) fragments.push({
|
|
212
|
+
type: "text",
|
|
213
|
+
text: str.slice(lastIndex, match.index)
|
|
214
|
+
});
|
|
215
|
+
fragments.push({
|
|
216
|
+
type: sType,
|
|
217
|
+
text: match[0]
|
|
218
|
+
});
|
|
219
|
+
lastIndex = match.index + match[0].length;
|
|
220
|
+
}
|
|
221
|
+
if (lastIndex < str.length) fragments.push({
|
|
222
|
+
type: "text",
|
|
223
|
+
text: str.slice(lastIndex)
|
|
224
|
+
});
|
|
225
|
+
return fragments;
|
|
226
|
+
}
|
|
227
|
+
const ansi = ansiRegex();
|
|
228
|
+
function parseAnsiStr(str) {
|
|
229
|
+
return fragmentString(str, ansi, "ansi");
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
233
|
+
* @param str - the text to prune - ANSI is supported
|
|
234
|
+
* @param maxWidth - the maximum width of the text
|
|
235
|
+
* @param pad - the string to use for padding, default is '…'
|
|
236
|
+
* @returns the pruned text
|
|
237
|
+
*/
|
|
238
|
+
function pruneAnsiTextEnd(str, maxWidth, pad$1 = "…") {
|
|
239
|
+
if (!maxWidth || maxWidth <= 0) return str;
|
|
240
|
+
if (str.length <= maxWidth) return str;
|
|
241
|
+
if (ansiWidth(str) <= maxWidth) return str;
|
|
242
|
+
const padWidth$1 = ansiWidth(pad$1);
|
|
243
|
+
const fragments = parseAnsiStr(str);
|
|
244
|
+
let remaining = maxWidth - padWidth$1;
|
|
245
|
+
for (const frag of fragments) {
|
|
246
|
+
if (frag.type !== "text") continue;
|
|
247
|
+
if (remaining <= 0) {
|
|
248
|
+
frag.text = "";
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const pruned = pruneTextEnd(frag.text, remaining, pad$1);
|
|
252
|
+
if (pruned !== frag.text) {
|
|
253
|
+
frag.text = pruned;
|
|
254
|
+
remaining = 0;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
remaining -= width(frag.text);
|
|
258
|
+
}
|
|
259
|
+
return fragments.map((frag) => frag.text).join("");
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
263
|
+
* @param str - the text to prune - ANSI is supported
|
|
264
|
+
* @param maxWidth - the maximum width of the text
|
|
265
|
+
* @param pad - the string to use for padding, default is '…'
|
|
266
|
+
* @returns the pruned text
|
|
267
|
+
*/
|
|
268
|
+
function pruneAnsiTextStart(str, maxWidth, pad$1 = "…") {
|
|
269
|
+
if (!maxWidth || maxWidth <= 0) return str;
|
|
270
|
+
if (str.length <= maxWidth) return str;
|
|
271
|
+
if (ansiWidth(str) <= maxWidth) return str;
|
|
272
|
+
const padWidth$1 = ansiWidth(pad$1);
|
|
273
|
+
const fragments = parseAnsiStr(str);
|
|
274
|
+
let remaining = maxWidth - padWidth$1;
|
|
275
|
+
for (const frag of fragments.reverse()) {
|
|
276
|
+
if (frag.type !== "text") continue;
|
|
277
|
+
if (remaining <= 0) {
|
|
278
|
+
frag.text = "";
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const pruned = pruneTextStart(frag.text, remaining, pad$1);
|
|
282
|
+
if (pruned !== frag.text) {
|
|
283
|
+
frag.text = pruned;
|
|
284
|
+
remaining = 0;
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
remaining -= width(frag.text);
|
|
288
|
+
}
|
|
289
|
+
return fragments.reverse().map((frag) => frag.text).join("");
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
293
|
+
* @param str - the text to prune - ANSI is not supported
|
|
294
|
+
* @param maxWidth - the maximum width of the text
|
|
295
|
+
* @param pad - the string to use for padding, default is '…'
|
|
296
|
+
* @returns the pruned text
|
|
297
|
+
*/
|
|
298
|
+
function pruneTextEnd(str, maxWidth, pad$1 = "…") {
|
|
299
|
+
if (!maxWidth || maxWidth <= 0) return str;
|
|
300
|
+
if (str.length <= maxWidth) return str;
|
|
301
|
+
if (isAnsiString(str)) return pruneAnsiTextEnd(str, maxWidth, pad$1);
|
|
302
|
+
const maxWidthWithPad = maxWidth - width(pad$1);
|
|
303
|
+
const letters = [...str];
|
|
304
|
+
let len = 0;
|
|
305
|
+
for (let i = 0; i < letters.length; i++) {
|
|
306
|
+
const c = letters[i];
|
|
307
|
+
len += width(c);
|
|
308
|
+
if (len > maxWidthWithPad) {
|
|
309
|
+
let j = i + 1;
|
|
310
|
+
while (j < letters.length && width(letters[j]) === 0) ++j;
|
|
311
|
+
return j === letters.length ? str : letters.slice(0, i).join("") + pad$1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return str;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
318
|
+
* @param str - the text to prune - ANSI is not supported
|
|
319
|
+
* @param maxWidth - the maximum width of the text
|
|
320
|
+
* @param pad - the string to use for padding, default is '…'
|
|
321
|
+
* @returns the pruned text
|
|
322
|
+
*/
|
|
323
|
+
function pruneTextStart(str, maxWidth, pad$1 = "…") {
|
|
324
|
+
if (!maxWidth || maxWidth <= 0) return str;
|
|
325
|
+
if (str.length <= maxWidth) return str;
|
|
326
|
+
const maxWidthWithPad = maxWidth - width(pad$1);
|
|
327
|
+
const letters = [...str];
|
|
328
|
+
let len = 0;
|
|
329
|
+
for (let i = letters.length - 1; i >= 1; i--) {
|
|
330
|
+
const c = letters[i];
|
|
331
|
+
len += width(c);
|
|
332
|
+
if (len > maxWidthWithPad) {
|
|
333
|
+
i += 1;
|
|
334
|
+
while (i < letters.length && width(letters[i]) === 0) ++i;
|
|
335
|
+
return pad$1 + letters.slice(i).join("");
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return str;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/util/pad.ts
|
|
343
|
+
function pad(s, w) {
|
|
344
|
+
const p = padWidth(s, w);
|
|
345
|
+
if (!p) return s;
|
|
346
|
+
return s.padEnd(p + s.length);
|
|
347
|
+
}
|
|
348
|
+
function padWidth(s, target) {
|
|
349
|
+
const sWidth = ansiWidth(s);
|
|
350
|
+
return Math.max(target - sWidth, 0);
|
|
351
|
+
}
|
|
352
|
+
function padLeft(s, w) {
|
|
353
|
+
const p = padWidth(s, w);
|
|
354
|
+
if (!p) return s;
|
|
355
|
+
return s.padStart(p + s.length);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
//#endregion
|
|
359
|
+
//#region src/util/table.ts
|
|
360
|
+
function tableToLines(table, deliminator) {
|
|
361
|
+
const del = deliminator || table.deliminator || " | ";
|
|
362
|
+
const columnWidths = [];
|
|
363
|
+
const columnAlignments = table.columnAlignments || [];
|
|
364
|
+
const maxColumnWidthsMap = table.maxColumnWidths || {};
|
|
365
|
+
const tableIndent = table.indent ? typeof table.indent === "number" ? " ".repeat(table.indent) : table.indent : "";
|
|
366
|
+
const { header, rows } = table;
|
|
367
|
+
const simpleHeader = header.map((col) => Array.isArray(col) ? col[1] : col);
|
|
368
|
+
const columnFieldNames = header.map((col) => Array.isArray(col) ? col[0] : col);
|
|
369
|
+
const maxColumnWidths = columnFieldNames.map((field, idx) => maxColumnWidthsMap[field] ?? maxColumnWidthsMap[idx]);
|
|
370
|
+
function getCell(row, col) {
|
|
371
|
+
return getCellFromRow(rows[row], col);
|
|
372
|
+
}
|
|
373
|
+
function getCellFromRow(row, col) {
|
|
374
|
+
if (!row) return void 0;
|
|
375
|
+
if (Array.isArray(row)) return row[col];
|
|
376
|
+
return row[columnFieldNames[col]];
|
|
377
|
+
}
|
|
378
|
+
function rowToCells(row) {
|
|
379
|
+
if (Array.isArray(row)) return row;
|
|
380
|
+
return columnFieldNames.map((fieldName) => row[fieldName]);
|
|
381
|
+
}
|
|
382
|
+
function getText(col, maxWidth) {
|
|
383
|
+
return !col ? "" : typeof col === "string" ? pruneTextEnd(col, maxWidth) : col(maxWidth);
|
|
384
|
+
}
|
|
385
|
+
function getRCText(row, col, maxWidth) {
|
|
386
|
+
return getText(getCell(row, col), maxWidth);
|
|
387
|
+
}
|
|
388
|
+
function recordHeaderWidths(header$1) {
|
|
389
|
+
header$1.forEach((col, idx) => {
|
|
390
|
+
columnWidths[idx] = Math.max(ansiWidth(col), columnWidths[idx] || 0);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function recordColWidths() {
|
|
394
|
+
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);
|
|
395
|
+
}
|
|
396
|
+
function justifyRow(c, i) {
|
|
397
|
+
return columnAlignments[i] === "R" ? padLeft(c, columnWidths[i]) : pad(c, columnWidths[i]);
|
|
398
|
+
}
|
|
399
|
+
function toHeaderLine(header$1) {
|
|
400
|
+
return tableIndent + decorateRowWith(header$1.map((c, i) => getText(c, columnWidths[i])), justifyRow, headerDecorator).join(del);
|
|
401
|
+
}
|
|
402
|
+
function toLine(row) {
|
|
403
|
+
return tableIndent + decorateRowWith(rowToCells(row).map((c, i) => getText(c, columnWidths[i])), justifyRow).join(del);
|
|
404
|
+
}
|
|
405
|
+
function* process$1() {
|
|
406
|
+
if (table.title) yield table.title;
|
|
407
|
+
yield toHeaderLine(simpleHeader);
|
|
408
|
+
yield* rows.map(toLine);
|
|
409
|
+
}
|
|
410
|
+
function sumColumnWidths() {
|
|
411
|
+
return columnWidths.reduce((sum, width$1) => sum + width$1, 0);
|
|
412
|
+
}
|
|
413
|
+
function adjustColWidths() {
|
|
414
|
+
for (let i = 0; i < columnWidths.length; i++) {
|
|
415
|
+
const mw = maxColumnWidths[i];
|
|
416
|
+
if (!mw) continue;
|
|
417
|
+
columnWidths[i] = Math.min(columnWidths[i], mw);
|
|
418
|
+
}
|
|
419
|
+
if (!table.terminalWidth) return;
|
|
420
|
+
const dWidth = (columnWidths.length - 1) * ansiWidth(del);
|
|
421
|
+
const lineWidth = table.terminalWidth - dWidth;
|
|
422
|
+
if (lineWidth <= columnWidths.length * 2) {
|
|
423
|
+
const fixedWidth = Math.max(Math.min(...columnWidths), 5);
|
|
424
|
+
for (let i = 0; i < columnWidths.length; i++) columnWidths[i] = fixedWidth;
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (columnWidths.length === 1) {
|
|
428
|
+
columnWidths[0] = lineWidth;
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
function trimWidestColumn(neededToTrim) {
|
|
432
|
+
let first = 0;
|
|
433
|
+
let second = 0;
|
|
434
|
+
for (let i = 0; i < columnWidths.length; i++) if (columnWidths[i] > columnWidths[first]) {
|
|
435
|
+
second = first;
|
|
436
|
+
first = i;
|
|
437
|
+
} else if (columnWidths[i] > columnWidths[second]) second = i;
|
|
438
|
+
const diff = Math.max(columnWidths[first] - columnWidths[second], 1);
|
|
439
|
+
columnWidths[first] -= Math.min(diff, neededToTrim);
|
|
440
|
+
}
|
|
441
|
+
for (let sum = sumColumnWidths(); sum > lineWidth; sum = sumColumnWidths()) trimWidestColumn(sum - lineWidth);
|
|
442
|
+
}
|
|
443
|
+
recordHeaderWidths(simpleHeader);
|
|
444
|
+
recordColWidths();
|
|
445
|
+
adjustColWidths();
|
|
446
|
+
return [...process$1()];
|
|
447
|
+
}
|
|
448
|
+
function headerDecorator(t) {
|
|
449
|
+
return chalk.bold(chalk.underline(t));
|
|
450
|
+
}
|
|
451
|
+
function decorateRowWith(row, ...decorators) {
|
|
452
|
+
return decorators.reduce((row$1, decorator) => row$1.map(decorator), row);
|
|
453
|
+
}
|
|
454
|
+
|
|
116
455
|
//#endregion
|
|
117
456
|
//#region src/util/util.ts
|
|
118
457
|
const uniqueFn = uniqueFilterFnGenerator;
|
|
@@ -279,6 +618,7 @@ function getReporter(options, config) {
|
|
|
279
618
|
if (!fileGlobs.length && !result.files) return;
|
|
280
619
|
const { files, issues: issues$1, cachedFiles, filesWithIssues, errors, skippedFiles } = result;
|
|
281
620
|
const numFilesWithIssues = filesWithIssues.size;
|
|
621
|
+
const chalk$1 = stderr.chalk;
|
|
282
622
|
if (stderr.getColorLevel() > 0) {
|
|
283
623
|
stderr.write("\r");
|
|
284
624
|
stderr.clearLine(0);
|
|
@@ -305,14 +645,80 @@ function getReporter(options, config) {
|
|
|
305
645
|
consoleError(` Files Skipped : ${perfStats.filesSkipped.toString().padStart(6)}`);
|
|
306
646
|
consoleError(` Files Cached : ${perfStats.filesCached.toString().padStart(6)}`);
|
|
307
647
|
consoleError(` Processing Time: ${perfStats.elapsedTimeMs.toFixed(2).padStart(9)}ms`);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
648
|
+
const tableStats = {
|
|
649
|
+
title: chalk$1.bold("Perf Stats:"),
|
|
650
|
+
header: ["Name", "Time (ms)"],
|
|
651
|
+
columnAlignments: ["L", "R"],
|
|
652
|
+
indent: 2,
|
|
653
|
+
rows: Object.entries(perfStats.perf).filter((p) => !!p[1]).map(([key, value]) => [key, value.toFixed(2)])
|
|
654
|
+
};
|
|
655
|
+
consoleError("");
|
|
656
|
+
for (const line of tableToLines(tableStats)) consoleError(line);
|
|
657
|
+
if (options.verboseLevel) verbosePerfReport();
|
|
314
658
|
}
|
|
315
659
|
};
|
|
660
|
+
function verbosePerfReport() {
|
|
661
|
+
const perfMeasurements = getPerfMeasurements();
|
|
662
|
+
if (!perfMeasurements.length) return;
|
|
663
|
+
const notable = extractNotableBySelfTimeInGroup(perfMeasurements);
|
|
664
|
+
const chalk$1 = stderr.chalk;
|
|
665
|
+
const maxDepth = Math.max(...perfMeasurements.map((m) => m.depth));
|
|
666
|
+
const depthIndicator = (d) => "⋅".repeat(d) + " ".repeat(maxDepth - d);
|
|
667
|
+
const rows = perfMeasurements.map((m) => {
|
|
668
|
+
const cbd = (text) => colorByDepth(chalk$1, m.depth, text);
|
|
669
|
+
const cNotable = (text) => notable.has(m) ? chalk$1.yellow(text) : text;
|
|
670
|
+
return [
|
|
671
|
+
chalk$1.dim("⋅".repeat(m.depth)) + colorByDepthGrayscale(stderr.chalk, m.depth, m.name),
|
|
672
|
+
cbd(m.totalTimeMs.toFixed(2) + chalk$1.dim(depthIndicator(m.depth))),
|
|
673
|
+
cbd(cNotable((m.totalTimeMs - m.nestedTimeMs).toFixed(2))),
|
|
674
|
+
cbd(m.count.toString()),
|
|
675
|
+
cbd(m.minTimeMs.toFixed(2)),
|
|
676
|
+
cbd(m.maxTimeMs.toFixed(2)),
|
|
677
|
+
cbd((m.totalTimeMs / m.count).toFixed(2))
|
|
678
|
+
];
|
|
679
|
+
});
|
|
680
|
+
const table = tableToLines({
|
|
681
|
+
title: chalk$1.bold("Detailed Measurements:"),
|
|
682
|
+
header: [
|
|
683
|
+
"Name",
|
|
684
|
+
"Total Time (ms)",
|
|
685
|
+
"Self (ms)",
|
|
686
|
+
"Count",
|
|
687
|
+
"Min (ms)",
|
|
688
|
+
"Max (ms)",
|
|
689
|
+
"Avg (ms)"
|
|
690
|
+
],
|
|
691
|
+
rows,
|
|
692
|
+
columnAlignments: [
|
|
693
|
+
"L",
|
|
694
|
+
"R",
|
|
695
|
+
"R",
|
|
696
|
+
"R",
|
|
697
|
+
"R",
|
|
698
|
+
"R",
|
|
699
|
+
"R"
|
|
700
|
+
],
|
|
701
|
+
indent: 2
|
|
702
|
+
});
|
|
703
|
+
consoleError("\n-------------------------------------------\n");
|
|
704
|
+
for (const line of table) consoleError(line);
|
|
705
|
+
}
|
|
706
|
+
function colorByDepth(chalk$1, depth, text) {
|
|
707
|
+
const colors = [
|
|
708
|
+
chalk$1.green,
|
|
709
|
+
chalk$1.cyan,
|
|
710
|
+
chalk$1.blue,
|
|
711
|
+
chalk$1.magenta,
|
|
712
|
+
chalk$1.red
|
|
713
|
+
];
|
|
714
|
+
const color = colors[depth % colors.length];
|
|
715
|
+
if (depth / colors.length >= 1) return chalk$1.dim(color(text));
|
|
716
|
+
return color(text);
|
|
717
|
+
}
|
|
718
|
+
function colorByDepthGrayscale(chalk$1, depth, text) {
|
|
719
|
+
const grayLevel = Math.max(32, 255 - depth * 20);
|
|
720
|
+
return chalk$1.rgb(grayLevel, grayLevel, grayLevel)(text);
|
|
721
|
+
}
|
|
316
722
|
function collectPerfStats(p) {
|
|
317
723
|
if (p.cached) {
|
|
318
724
|
perfStats.filesCached++;
|
|
@@ -338,6 +744,27 @@ function getReporter(options, config) {
|
|
|
338
744
|
features: void 0
|
|
339
745
|
};
|
|
340
746
|
}
|
|
747
|
+
function extractNotableBySelfTimeInGroup(measurements) {
|
|
748
|
+
const notable = /* @__PURE__ */ new Set();
|
|
749
|
+
if (!measurements.length) return notable;
|
|
750
|
+
let highest;
|
|
751
|
+
let highestSelfTime = 0;
|
|
752
|
+
for (const m of measurements) {
|
|
753
|
+
if (m.depth === 0 || !highest) {
|
|
754
|
+
if (highest) notable.add(highest);
|
|
755
|
+
highest = m;
|
|
756
|
+
highestSelfTime = m.totalTimeMs - m.nestedTimeMs;
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
const selfTime = m.totalTimeMs - m.nestedTimeMs;
|
|
760
|
+
if (selfTime > highestSelfTime) {
|
|
761
|
+
highest = m;
|
|
762
|
+
highestSelfTime = selfTime;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (highest) notable.add(highest);
|
|
766
|
+
return notable;
|
|
767
|
+
}
|
|
341
768
|
function formatIssue(io, templateStr, issue, maxIssueTextWidth) {
|
|
342
769
|
function clean$1(t$1) {
|
|
343
770
|
return t$1.replace(/\s+/, " ");
|
|
@@ -447,7 +874,7 @@ async function fileExists(url) {
|
|
|
447
874
|
try {
|
|
448
875
|
return (await promises.stat(url)).isFile();
|
|
449
876
|
} catch (e) {
|
|
450
|
-
if (toError(e).code === "ENOENT") return false;
|
|
877
|
+
if (toError$1(e).code === "ENOENT") return false;
|
|
451
878
|
throw e;
|
|
452
879
|
}
|
|
453
880
|
}
|
|
@@ -770,7 +1197,7 @@ const pkgDir = _dirname;
|
|
|
770
1197
|
//#endregion
|
|
771
1198
|
//#region src/pkgInfo.ts
|
|
772
1199
|
const name = "cspell";
|
|
773
|
-
const version$1 = "9.
|
|
1200
|
+
const version$1 = "9.6.0";
|
|
774
1201
|
const engines = { node: ">=20" };
|
|
775
1202
|
const npmPackage = {
|
|
776
1203
|
name,
|
|
@@ -991,7 +1418,7 @@ function readFileInfo(filename, encoding = UTF8, handleNotFound = false) {
|
|
|
991
1418
|
text,
|
|
992
1419
|
filename
|
|
993
1420
|
}), (e) => {
|
|
994
|
-
const error = toError(e);
|
|
1421
|
+
const error = toError$1(e);
|
|
995
1422
|
return handleNotFound && error.code === "EISDIR" ? Promise.resolve({
|
|
996
1423
|
text: "",
|
|
997
1424
|
filename,
|
|
@@ -1181,7 +1608,7 @@ var ImplFileEntryCache = class {
|
|
|
1181
1608
|
return {
|
|
1182
1609
|
key: file,
|
|
1183
1610
|
notFound: true,
|
|
1184
|
-
err: toError
|
|
1611
|
+
err: toError(error)
|
|
1185
1612
|
};
|
|
1186
1613
|
}
|
|
1187
1614
|
if (this.useChecksum) return this.#getFileDescriptorUsingChecksum(file);
|
|
@@ -1296,7 +1723,7 @@ var ImplFileEntryCache = class {
|
|
|
1296
1723
|
function isNodeError(error) {
|
|
1297
1724
|
return typeof error === "object" && error !== null && "code" in error;
|
|
1298
1725
|
}
|
|
1299
|
-
function toError
|
|
1726
|
+
function toError(error) {
|
|
1300
1727
|
if (error instanceof Error) return error;
|
|
1301
1728
|
if (typeof error === "string") return new Error(error);
|
|
1302
1729
|
return new Error("Unknown error", { cause: error });
|
|
@@ -1647,61 +2074,6 @@ async function readConfigHandleError(filename) {
|
|
|
1647
2074
|
}
|
|
1648
2075
|
}
|
|
1649
2076
|
|
|
1650
|
-
//#endregion
|
|
1651
|
-
//#region src/util/extractContext.ts
|
|
1652
|
-
function prefCharIndex(text, offset, count = 1) {
|
|
1653
|
-
if (offset - count < 0) return 0;
|
|
1654
|
-
for (; count > 0 && offset > 0; count--) {
|
|
1655
|
-
let code = text.charCodeAt(--offset) || 0;
|
|
1656
|
-
if (code === 65039) code = text.charCodeAt(--offset) || 0;
|
|
1657
|
-
offset -= (code & 64512) === 56320 ? 1 : 0;
|
|
1658
|
-
}
|
|
1659
|
-
return offset < 0 ? 0 : offset;
|
|
1660
|
-
}
|
|
1661
|
-
function nextCharIndex(text, offset, count = 1) {
|
|
1662
|
-
if (offset + count >= text.length) return text.length;
|
|
1663
|
-
for (; count > 0 && offset < text.length; count--) {
|
|
1664
|
-
const code = text.charCodeAt(offset++) || 0;
|
|
1665
|
-
offset += (code & 64512) === 55296 ? 1 : 0;
|
|
1666
|
-
if (text.charCodeAt(offset) === 65039) offset++;
|
|
1667
|
-
}
|
|
1668
|
-
return offset > text.length ? text.length : offset;
|
|
1669
|
-
}
|
|
1670
|
-
function lineContext(lineText, start, end, contextRange) {
|
|
1671
|
-
let left = prefCharIndex(lineText, start, contextRange);
|
|
1672
|
-
let right = nextCharIndex(lineText, end, contextRange);
|
|
1673
|
-
const isLetter = /^\p{L}$/u;
|
|
1674
|
-
const isMark = /^\p{M}$/u;
|
|
1675
|
-
for (let n = contextRange / 2; n > 0 && left > 0; n--, left--) {
|
|
1676
|
-
const c = lineText[left - 1];
|
|
1677
|
-
if (isMark.test(c)) {
|
|
1678
|
-
if (!isLetter.test(lineText[left - 2])) break;
|
|
1679
|
-
left--;
|
|
1680
|
-
continue;
|
|
1681
|
-
}
|
|
1682
|
-
if (!isLetter.test(lineText[left - 1])) break;
|
|
1683
|
-
}
|
|
1684
|
-
for (let n = contextRange / 2; n > 0 && right < lineText.length; n--, right++) {
|
|
1685
|
-
if (!isLetter.test(lineText[right])) break;
|
|
1686
|
-
if (isMark.test(lineText[right + 1])) right++;
|
|
1687
|
-
}
|
|
1688
|
-
left = left < 0 ? 0 : left;
|
|
1689
|
-
const t0 = lineText.slice(left, right);
|
|
1690
|
-
const tLeft = t0.trimStart();
|
|
1691
|
-
left = Math.min(left + t0.length - tLeft.length, start);
|
|
1692
|
-
return {
|
|
1693
|
-
text: tLeft.trimEnd(),
|
|
1694
|
-
offset: left
|
|
1695
|
-
};
|
|
1696
|
-
}
|
|
1697
|
-
function extractContext(tdo, contextRange) {
|
|
1698
|
-
const { line, offset, text } = tdo;
|
|
1699
|
-
const start = offset - line.offset;
|
|
1700
|
-
const context = lineContext(line.text, start, start + text.length, contextRange);
|
|
1701
|
-
context.offset += line.offset;
|
|
1702
|
-
return context;
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
2077
|
//#endregion
|
|
1706
2078
|
//#region src/util/prefetch.ts
|
|
1707
2079
|
function* prefetchIterable(iterable, size) {
|
|
@@ -1750,7 +2122,7 @@ async function loadReporters(reporters, defaultReporter, config) {
|
|
|
1750
2122
|
const { getReporter: getReporter$1 } = await dynamicImport(moduleName, [process.cwd(), pkgDir]);
|
|
1751
2123
|
return getReporter$1(settings, config);
|
|
1752
2124
|
} catch (e) {
|
|
1753
|
-
throw new ApplicationError(`Failed to load reporter ${moduleName}: ${toError(e).message}`);
|
|
2125
|
+
throw new ApplicationError(`Failed to load reporter ${moduleName}: ${toError$1(e).message}`);
|
|
1754
2126
|
}
|
|
1755
2127
|
}
|
|
1756
2128
|
reporters = !reporters || !reporters.length ? ["default"] : [...reporters];
|
|
@@ -1892,11 +2264,11 @@ function getTimeMeasurer() {
|
|
|
1892
2264
|
* @returns
|
|
1893
2265
|
*/
|
|
1894
2266
|
function indent(str, padding, firstLinePadding = "") {
|
|
1895
|
-
let pad = firstLinePadding;
|
|
2267
|
+
let pad$1 = firstLinePadding;
|
|
1896
2268
|
const lines = [];
|
|
1897
2269
|
for (const line of str.split("\n")) {
|
|
1898
|
-
lines.push(pad + line);
|
|
1899
|
-
pad = padding;
|
|
2270
|
+
lines.push(pad$1 + line);
|
|
2271
|
+
pad$1 = padding;
|
|
1900
2272
|
}
|
|
1901
2273
|
return lines.join("\n");
|
|
1902
2274
|
}
|
|
@@ -1983,162 +2355,6 @@ function sizeToNumber(size) {
|
|
|
1983
2355
|
return Number.parseFloat(p.digits) * (unitSizes[p.units] || 1);
|
|
1984
2356
|
}
|
|
1985
2357
|
|
|
1986
|
-
//#endregion
|
|
1987
|
-
//#region src/util/ansi.ts
|
|
1988
|
-
function isAnsiString(s) {
|
|
1989
|
-
return s.includes("\x1B") || s.includes("");
|
|
1990
|
-
}
|
|
1991
|
-
/**
|
|
1992
|
-
*
|
|
1993
|
-
* @param s - the string to measure - should NOT contains ANSI codes
|
|
1994
|
-
* @param tabWidth -
|
|
1995
|
-
* @returns
|
|
1996
|
-
*/
|
|
1997
|
-
function width(s, tabWidth = 1) {
|
|
1998
|
-
return s.replaceAll("…", ".").replaceAll(" ", " ".repeat(tabWidth)).replaceAll(/\p{M}/gu, "").replaceAll(/\p{L}/gu, ".").replaceAll(/[\u0000-\u001F\u0300-\u036F]/g, "").replaceAll(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, ".").length;
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
* Measure the width of a string containing ANSI control characters.
|
|
2002
|
-
* @param s - string to measure with width in characters.
|
|
2003
|
-
* @returns the approximate number of screen characters.
|
|
2004
|
-
*/
|
|
2005
|
-
function ansiWidth(s) {
|
|
2006
|
-
return width(stripVTControlCharacters(s));
|
|
2007
|
-
}
|
|
2008
|
-
function fragmentString(str, splitOnRegex, sType) {
|
|
2009
|
-
const fragments = [];
|
|
2010
|
-
let lastIndex = 0;
|
|
2011
|
-
for (const match of str.matchAll(new RegExp(splitOnRegex))) {
|
|
2012
|
-
if (match.index > lastIndex) fragments.push({
|
|
2013
|
-
type: "text",
|
|
2014
|
-
text: str.slice(lastIndex, match.index)
|
|
2015
|
-
});
|
|
2016
|
-
fragments.push({
|
|
2017
|
-
type: sType,
|
|
2018
|
-
text: match[0]
|
|
2019
|
-
});
|
|
2020
|
-
lastIndex = match.index + match[0].length;
|
|
2021
|
-
}
|
|
2022
|
-
if (lastIndex < str.length) fragments.push({
|
|
2023
|
-
type: "text",
|
|
2024
|
-
text: str.slice(lastIndex)
|
|
2025
|
-
});
|
|
2026
|
-
return fragments;
|
|
2027
|
-
}
|
|
2028
|
-
const ansi = ansiRegex();
|
|
2029
|
-
function parseAnsiStr(str) {
|
|
2030
|
-
return fragmentString(str, ansi, "ansi");
|
|
2031
|
-
}
|
|
2032
|
-
/**
|
|
2033
|
-
* Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
2034
|
-
* @param str - the text to prune - ANSI is supported
|
|
2035
|
-
* @param maxWidth - the maximum width of the text
|
|
2036
|
-
* @param pad - the string to use for padding, default is '…'
|
|
2037
|
-
* @returns the pruned text
|
|
2038
|
-
*/
|
|
2039
|
-
function pruneAnsiTextEnd(str, maxWidth, pad = "…") {
|
|
2040
|
-
if (!maxWidth || maxWidth <= 0) return str;
|
|
2041
|
-
if (str.length <= maxWidth) return str;
|
|
2042
|
-
if (ansiWidth(str) <= maxWidth) return str;
|
|
2043
|
-
const padWidth = ansiWidth(pad);
|
|
2044
|
-
const fragments = parseAnsiStr(str);
|
|
2045
|
-
let remaining = maxWidth - padWidth;
|
|
2046
|
-
for (const frag of fragments) {
|
|
2047
|
-
if (frag.type !== "text") continue;
|
|
2048
|
-
if (remaining <= 0) {
|
|
2049
|
-
frag.text = "";
|
|
2050
|
-
continue;
|
|
2051
|
-
}
|
|
2052
|
-
const pruned = pruneTextEnd(frag.text, remaining, pad);
|
|
2053
|
-
if (pruned !== frag.text) {
|
|
2054
|
-
frag.text = pruned;
|
|
2055
|
-
remaining = 0;
|
|
2056
|
-
continue;
|
|
2057
|
-
}
|
|
2058
|
-
remaining -= width(frag.text);
|
|
2059
|
-
}
|
|
2060
|
-
return fragments.map((frag) => frag.text).join("");
|
|
2061
|
-
}
|
|
2062
|
-
/**
|
|
2063
|
-
* Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
2064
|
-
* @param str - the text to prune - ANSI is supported
|
|
2065
|
-
* @param maxWidth - the maximum width of the text
|
|
2066
|
-
* @param pad - the string to use for padding, default is '…'
|
|
2067
|
-
* @returns the pruned text
|
|
2068
|
-
*/
|
|
2069
|
-
function pruneAnsiTextStart(str, maxWidth, pad = "…") {
|
|
2070
|
-
if (!maxWidth || maxWidth <= 0) return str;
|
|
2071
|
-
if (str.length <= maxWidth) return str;
|
|
2072
|
-
if (ansiWidth(str) <= maxWidth) return str;
|
|
2073
|
-
const padWidth = ansiWidth(pad);
|
|
2074
|
-
const fragments = parseAnsiStr(str);
|
|
2075
|
-
let remaining = maxWidth - padWidth;
|
|
2076
|
-
for (const frag of fragments.reverse()) {
|
|
2077
|
-
if (frag.type !== "text") continue;
|
|
2078
|
-
if (remaining <= 0) {
|
|
2079
|
-
frag.text = "";
|
|
2080
|
-
continue;
|
|
2081
|
-
}
|
|
2082
|
-
const pruned = pruneTextStart(frag.text, remaining, pad);
|
|
2083
|
-
if (pruned !== frag.text) {
|
|
2084
|
-
frag.text = pruned;
|
|
2085
|
-
remaining = 0;
|
|
2086
|
-
continue;
|
|
2087
|
-
}
|
|
2088
|
-
remaining -= width(frag.text);
|
|
2089
|
-
}
|
|
2090
|
-
return fragments.reverse().map((frag) => frag.text).join("");
|
|
2091
|
-
}
|
|
2092
|
-
/**
|
|
2093
|
-
* Prune the end of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
2094
|
-
* @param str - the text to prune - ANSI is not supported
|
|
2095
|
-
* @param maxWidth - the maximum width of the text
|
|
2096
|
-
* @param pad - the string to use for padding, default is '…'
|
|
2097
|
-
* @returns the pruned text
|
|
2098
|
-
*/
|
|
2099
|
-
function pruneTextEnd(str, maxWidth, pad = "…") {
|
|
2100
|
-
if (!maxWidth || maxWidth <= 0) return str;
|
|
2101
|
-
if (str.length <= maxWidth) return str;
|
|
2102
|
-
if (isAnsiString(str)) return pruneAnsiTextEnd(str, maxWidth, pad);
|
|
2103
|
-
const maxWidthWithPad = maxWidth - width(pad);
|
|
2104
|
-
const letters = [...str];
|
|
2105
|
-
let len = 0;
|
|
2106
|
-
for (let i = 0; i < letters.length; i++) {
|
|
2107
|
-
const c = letters[i];
|
|
2108
|
-
len += width(c);
|
|
2109
|
-
if (len > maxWidthWithPad) {
|
|
2110
|
-
let j = i + 1;
|
|
2111
|
-
while (j < letters.length && width(letters[j]) === 0) ++j;
|
|
2112
|
-
return j === letters.length ? str : letters.slice(0, i).join("") + pad;
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
return str;
|
|
2116
|
-
}
|
|
2117
|
-
/**
|
|
2118
|
-
* Prune the start of a string to fit within a specified width, adding an ellipsis if necessary.
|
|
2119
|
-
* @param str - the text to prune - ANSI is not supported
|
|
2120
|
-
* @param maxWidth - the maximum width of the text
|
|
2121
|
-
* @param pad - the string to use for padding, default is '…'
|
|
2122
|
-
* @returns the pruned text
|
|
2123
|
-
*/
|
|
2124
|
-
function pruneTextStart(str, maxWidth, pad = "…") {
|
|
2125
|
-
if (!maxWidth || maxWidth <= 0) return str;
|
|
2126
|
-
if (str.length <= maxWidth) return str;
|
|
2127
|
-
const maxWidthWithPad = maxWidth - width(pad);
|
|
2128
|
-
const letters = [...str];
|
|
2129
|
-
let len = 0;
|
|
2130
|
-
for (let i = letters.length - 1; i >= 1; i--) {
|
|
2131
|
-
const c = letters[i];
|
|
2132
|
-
len += width(c);
|
|
2133
|
-
if (len > maxWidthWithPad) {
|
|
2134
|
-
i += 1;
|
|
2135
|
-
while (i < letters.length && width(letters[i]) === 0) ++i;
|
|
2136
|
-
return pad + letters.slice(i).join("");
|
|
2137
|
-
}
|
|
2138
|
-
}
|
|
2139
|
-
return str;
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
2358
|
//#endregion
|
|
2143
2359
|
//#region src/util/wrap.ts
|
|
2144
2360
|
const wrapSep = /\s+|(?<=,)|\.(?=\w)/g;
|
|
@@ -2199,6 +2415,206 @@ function writeStream(stream, data) {
|
|
|
2199
2415
|
});
|
|
2200
2416
|
}
|
|
2201
2417
|
|
|
2418
|
+
//#endregion
|
|
2419
|
+
//#region src/util/extractContext.ts
|
|
2420
|
+
function prefCharIndex(text, offset, count = 1) {
|
|
2421
|
+
if (offset - count < 0) return 0;
|
|
2422
|
+
for (; count > 0 && offset > 0; count--) {
|
|
2423
|
+
let code = text.charCodeAt(--offset) || 0;
|
|
2424
|
+
if (code === 65039) code = text.charCodeAt(--offset) || 0;
|
|
2425
|
+
offset -= (code & 64512) === 56320 ? 1 : 0;
|
|
2426
|
+
}
|
|
2427
|
+
return offset < 0 ? 0 : offset;
|
|
2428
|
+
}
|
|
2429
|
+
function nextCharIndex(text, offset, count = 1) {
|
|
2430
|
+
if (offset + count >= text.length) return text.length;
|
|
2431
|
+
for (; count > 0 && offset < text.length; count--) {
|
|
2432
|
+
const code = text.charCodeAt(offset++) || 0;
|
|
2433
|
+
offset += (code & 64512) === 55296 ? 1 : 0;
|
|
2434
|
+
if (text.charCodeAt(offset) === 65039) offset++;
|
|
2435
|
+
}
|
|
2436
|
+
return offset > text.length ? text.length : offset;
|
|
2437
|
+
}
|
|
2438
|
+
function lineContext(lineText, start, end, contextRange) {
|
|
2439
|
+
let left = prefCharIndex(lineText, start, contextRange);
|
|
2440
|
+
let right = nextCharIndex(lineText, end, contextRange);
|
|
2441
|
+
const isLetter = /^\p{L}$/u;
|
|
2442
|
+
const isMark = /^\p{M}$/u;
|
|
2443
|
+
for (let n = contextRange / 2; n > 0 && left > 0; n--, left--) {
|
|
2444
|
+
const c = lineText[left - 1];
|
|
2445
|
+
if (isMark.test(c)) {
|
|
2446
|
+
if (!isLetter.test(lineText[left - 2])) break;
|
|
2447
|
+
left--;
|
|
2448
|
+
continue;
|
|
2449
|
+
}
|
|
2450
|
+
if (!isLetter.test(lineText[left - 1])) break;
|
|
2451
|
+
}
|
|
2452
|
+
for (let n = contextRange / 2; n > 0 && right < lineText.length; n--, right++) {
|
|
2453
|
+
if (!isLetter.test(lineText[right])) break;
|
|
2454
|
+
if (isMark.test(lineText[right + 1])) right++;
|
|
2455
|
+
}
|
|
2456
|
+
left = left < 0 ? 0 : left;
|
|
2457
|
+
const t0 = lineText.slice(left, right);
|
|
2458
|
+
const tLeft = t0.trimStart();
|
|
2459
|
+
left = Math.min(left + t0.length - tLeft.length, start);
|
|
2460
|
+
return {
|
|
2461
|
+
text: tLeft.trimEnd(),
|
|
2462
|
+
offset: left
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
function extractContext(tdo, contextRange) {
|
|
2466
|
+
const { line, offset, text } = tdo;
|
|
2467
|
+
const start = offset - line.offset;
|
|
2468
|
+
const context = lineContext(line.text, start, start + text.length, contextRange);
|
|
2469
|
+
context.offset += line.offset;
|
|
2470
|
+
return context;
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
//#endregion
|
|
2474
|
+
//#region src/lint/LinterError.ts
|
|
2475
|
+
var LinterError = class extends Error {
|
|
2476
|
+
constructor(message) {
|
|
2477
|
+
super(message);
|
|
2478
|
+
}
|
|
2479
|
+
toString() {
|
|
2480
|
+
return this.message;
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2483
|
+
|
|
2484
|
+
//#endregion
|
|
2485
|
+
//#region src/lint/processFile.ts
|
|
2486
|
+
async function processFile(filename, cache, prefetch, processFileOptions) {
|
|
2487
|
+
if (prefetch?.fileResult) return prefetch.fileResult;
|
|
2488
|
+
const { reporter, cfg, configInfo } = processFileOptions;
|
|
2489
|
+
const getElapsedTimeMs = getTimeMeasurer();
|
|
2490
|
+
const reportIssueOptions = prefetch?.reportIssueOptions;
|
|
2491
|
+
const cachedResult = await cache.getCachedLintResults(filename);
|
|
2492
|
+
if (cachedResult) {
|
|
2493
|
+
reporter.debug(`Filename: ${filename}, using cache`);
|
|
2494
|
+
return {
|
|
2495
|
+
...cachedResult,
|
|
2496
|
+
elapsedTimeMs: getElapsedTimeMs(),
|
|
2497
|
+
reportIssueOptions: {
|
|
2498
|
+
...cachedResult.reportIssueOptions,
|
|
2499
|
+
...reportIssueOptions
|
|
2500
|
+
}
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
const result = {
|
|
2504
|
+
fileInfo: { filename },
|
|
2505
|
+
issues: [],
|
|
2506
|
+
processed: false,
|
|
2507
|
+
errors: 0,
|
|
2508
|
+
configErrors: 0,
|
|
2509
|
+
elapsedTimeMs: 0,
|
|
2510
|
+
reportIssueOptions
|
|
2511
|
+
};
|
|
2512
|
+
const fileInfo = prefetch?.fileInfo || await readFileInfo(filename, void 0, true);
|
|
2513
|
+
if (fileInfo.errorCode) {
|
|
2514
|
+
if (fileInfo.errorCode !== "EISDIR" && cfg.options.mustFindFiles) {
|
|
2515
|
+
const err = new LinterError(`File not found: "${filename}"`);
|
|
2516
|
+
reporter.error("Linter:", err);
|
|
2517
|
+
result.errors += 1;
|
|
2518
|
+
}
|
|
2519
|
+
return result;
|
|
2520
|
+
}
|
|
2521
|
+
const doc = fileInfoToDocument(fileInfo, cfg.options.languageId, cfg.locale);
|
|
2522
|
+
const { text } = fileInfo;
|
|
2523
|
+
result.fileInfo = fileInfo;
|
|
2524
|
+
let spellResult = {};
|
|
2525
|
+
try {
|
|
2526
|
+
const { showSuggestions: generateSuggestions, validateDirectives, skipValidation } = cfg.options;
|
|
2527
|
+
const numSuggestions = configInfo.config.numSuggestions ?? 5;
|
|
2528
|
+
const r = await spellCheckDocument(doc, clean({
|
|
2529
|
+
generateSuggestions,
|
|
2530
|
+
numSuggestions,
|
|
2531
|
+
validateDirectives,
|
|
2532
|
+
skipValidation
|
|
2533
|
+
}), configInfo.config);
|
|
2534
|
+
spellResult = r;
|
|
2535
|
+
result.processed = r.checked;
|
|
2536
|
+
result.perf = r.perf ? { ...r.perf } : void 0;
|
|
2537
|
+
result.issues = Text.calculateTextDocumentOffsets(doc.uri, text, r.issues).map(mapIssue);
|
|
2538
|
+
} catch (e) {
|
|
2539
|
+
reporter.error(`Failed to process "${filename}"`, toError$1(e));
|
|
2540
|
+
result.errors += 1;
|
|
2541
|
+
}
|
|
2542
|
+
result.elapsedTimeMs = getElapsedTimeMs();
|
|
2543
|
+
const config = spellResult.settingsUsed ?? {};
|
|
2544
|
+
result.reportIssueOptions = mergeReportIssueOptions(spellResult.settingsUsed || configInfo.config, reportIssueOptions);
|
|
2545
|
+
result.configErrors += await reportConfigurationErrors(config, processFileOptions);
|
|
2546
|
+
reportCheckResult(result, doc, spellResult, config, processFileOptions);
|
|
2547
|
+
const dep = calcDependencies(config);
|
|
2548
|
+
await cache.setCachedLintResults(result, dep.files);
|
|
2549
|
+
return result;
|
|
2550
|
+
function mapIssue({ doc: _, ...tdo }) {
|
|
2551
|
+
const context = cfg.showContext ? extractContext(tdo, cfg.showContext) : void 0;
|
|
2552
|
+
return clean({
|
|
2553
|
+
...tdo,
|
|
2554
|
+
context
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
function reportCheckResult(result, _doc, spellResult, config, processFileOptions) {
|
|
2559
|
+
const { configInfo, reporter, verboseLevel, useColor, cfg, chalk: chalk$1 } = processFileOptions;
|
|
2560
|
+
const elapsed = result.elapsedTimeMs || 0;
|
|
2561
|
+
const dictionaries = config.dictionaries || [];
|
|
2562
|
+
if (verboseLevel > 1) {
|
|
2563
|
+
const dictsUsed = [...dictionaries].sort().map((name$1) => chalk$1.green(name$1)).join(", ");
|
|
2564
|
+
const msg = unindent`
|
|
2565
|
+
File type: ${config.languageId}, Language: ${config.language}, Issues: ${result.issues.length} ${elapsed.toFixed(2)}ms
|
|
2566
|
+
Config file Used: ${relativeToCwd(spellResult.localConfigFilepath || configInfo.source, cfg.root)}
|
|
2567
|
+
Dictionaries Used:
|
|
2568
|
+
${wordWrapAnsiText(dictsUsed, 70)}`;
|
|
2569
|
+
reporter.info(indent(msg, " "), MessageTypes.Info);
|
|
2570
|
+
}
|
|
2571
|
+
if (cfg.options.debug) {
|
|
2572
|
+
const { enabled, language, languageId, dictionaries: dictionaries$1 } = config;
|
|
2573
|
+
const msg = unindent`\
|
|
2574
|
+
Debug Config: ${formatWithOptions({
|
|
2575
|
+
depth: 2,
|
|
2576
|
+
colors: useColor
|
|
2577
|
+
}, {
|
|
2578
|
+
languageId,
|
|
2579
|
+
enabled,
|
|
2580
|
+
language,
|
|
2581
|
+
dictionaries: dictionaries$1
|
|
2582
|
+
})}`;
|
|
2583
|
+
reporter.debug(msg);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
function calcDependencies(config) {
|
|
2587
|
+
const { configFiles, dictionaryFiles } = extractDependencies(config);
|
|
2588
|
+
return { files: [...configFiles, ...dictionaryFiles] };
|
|
2589
|
+
}
|
|
2590
|
+
async function reportConfigurationErrors(config, processFileOptions) {
|
|
2591
|
+
const { reporter, configErrors } = processFileOptions;
|
|
2592
|
+
const errors = extractImportErrors(config);
|
|
2593
|
+
let count = 0;
|
|
2594
|
+
errors.forEach((ref) => {
|
|
2595
|
+
const key = ref.error.toString();
|
|
2596
|
+
if (configErrors.has(key)) return;
|
|
2597
|
+
configErrors.add(key);
|
|
2598
|
+
count += 1;
|
|
2599
|
+
reporter.error("Configuration", ref.error);
|
|
2600
|
+
});
|
|
2601
|
+
(await getDictionary(config)).dictionaries.forEach((dict) => {
|
|
2602
|
+
const dictErrors = dict.getErrors?.() || [];
|
|
2603
|
+
const msg = `Dictionary Error with (${dict.name})`;
|
|
2604
|
+
dictErrors.forEach((error) => {
|
|
2605
|
+
const key = msg + error.toString();
|
|
2606
|
+
if (configErrors.has(key)) return;
|
|
2607
|
+
configErrors.add(key);
|
|
2608
|
+
count += 1;
|
|
2609
|
+
reporter.error(msg, error);
|
|
2610
|
+
});
|
|
2611
|
+
});
|
|
2612
|
+
return count;
|
|
2613
|
+
}
|
|
2614
|
+
function countConfigErrors(configInfo, processFileOptions) {
|
|
2615
|
+
return reportConfigurationErrors(configInfo.config, processFileOptions);
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2202
2618
|
//#endregion
|
|
2203
2619
|
//#region src/lint/lint.ts
|
|
2204
2620
|
const version = npmPackage.version;
|
|
@@ -2211,7 +2627,7 @@ async function runLint(cfg) {
|
|
|
2211
2627
|
const useColor = cfg.options.color ?? true;
|
|
2212
2628
|
const timer = getTimeMeasurer();
|
|
2213
2629
|
const logDictRequests = truthy(getEnvironmentVariable("CSPELL_ENABLE_DICTIONARY_LOGGING"));
|
|
2214
|
-
if (logDictRequests)
|
|
2630
|
+
if (logDictRequests) dictionaryCacheEnableLogging(true);
|
|
2215
2631
|
const lintResult = await run();
|
|
2216
2632
|
if (logDictRequests) await writeDictionaryLog();
|
|
2217
2633
|
await reporter.result(lintResult);
|
|
@@ -2260,104 +2676,6 @@ async function runLint(cfg) {
|
|
|
2260
2676
|
result: fetch$1().catch((e) => toApplicationError(e))
|
|
2261
2677
|
};
|
|
2262
2678
|
}
|
|
2263
|
-
async function processFile(filename, configInfo, cache, prefetch$1) {
|
|
2264
|
-
if (prefetch$1?.fileResult) return prefetch$1.fileResult;
|
|
2265
|
-
const getElapsedTimeMs = getTimeMeasurer();
|
|
2266
|
-
const reportIssueOptions = prefetch$1?.reportIssueOptions;
|
|
2267
|
-
const cachedResult = await cache.getCachedLintResults(filename);
|
|
2268
|
-
if (cachedResult) {
|
|
2269
|
-
reporter.debug(`Filename: ${filename}, using cache`);
|
|
2270
|
-
return {
|
|
2271
|
-
...cachedResult,
|
|
2272
|
-
elapsedTimeMs: getElapsedTimeMs(),
|
|
2273
|
-
reportIssueOptions: {
|
|
2274
|
-
...cachedResult.reportIssueOptions,
|
|
2275
|
-
...reportIssueOptions
|
|
2276
|
-
}
|
|
2277
|
-
};
|
|
2278
|
-
}
|
|
2279
|
-
const result = {
|
|
2280
|
-
fileInfo: { filename },
|
|
2281
|
-
issues: [],
|
|
2282
|
-
processed: false,
|
|
2283
|
-
errors: 0,
|
|
2284
|
-
configErrors: 0,
|
|
2285
|
-
elapsedTimeMs: 0,
|
|
2286
|
-
reportIssueOptions
|
|
2287
|
-
};
|
|
2288
|
-
const fileInfo = prefetch$1?.fileInfo || await readFileInfo(filename, void 0, true);
|
|
2289
|
-
if (fileInfo.errorCode) {
|
|
2290
|
-
if (fileInfo.errorCode !== "EISDIR" && cfg.options.mustFindFiles) {
|
|
2291
|
-
const err = new LinterError(`File not found: "${filename}"`);
|
|
2292
|
-
reporter.error("Linter:", err);
|
|
2293
|
-
result.errors += 1;
|
|
2294
|
-
}
|
|
2295
|
-
return result;
|
|
2296
|
-
}
|
|
2297
|
-
const doc = fileInfoToDocument(fileInfo, cfg.options.languageId, cfg.locale);
|
|
2298
|
-
const { text } = fileInfo;
|
|
2299
|
-
result.fileInfo = fileInfo;
|
|
2300
|
-
let spellResult = {};
|
|
2301
|
-
try {
|
|
2302
|
-
const { showSuggestions: generateSuggestions, validateDirectives, skipValidation } = cfg.options;
|
|
2303
|
-
const numSuggestions = configInfo.config.numSuggestions ?? 5;
|
|
2304
|
-
const r = await spellCheckDocument(doc, clean({
|
|
2305
|
-
generateSuggestions,
|
|
2306
|
-
numSuggestions,
|
|
2307
|
-
validateDirectives,
|
|
2308
|
-
skipValidation
|
|
2309
|
-
}), configInfo.config);
|
|
2310
|
-
spellResult = r;
|
|
2311
|
-
result.processed = r.checked;
|
|
2312
|
-
result.perf = r.perf ? { ...r.perf } : void 0;
|
|
2313
|
-
result.issues = Text.calculateTextDocumentOffsets(doc.uri, text, r.issues).map(mapIssue);
|
|
2314
|
-
} catch (e) {
|
|
2315
|
-
reporter.error(`Failed to process "${filename}"`, toError(e));
|
|
2316
|
-
result.errors += 1;
|
|
2317
|
-
}
|
|
2318
|
-
result.elapsedTimeMs = getElapsedTimeMs();
|
|
2319
|
-
const config = spellResult.settingsUsed ?? {};
|
|
2320
|
-
result.reportIssueOptions = mergeReportIssueOptions(spellResult.settingsUsed || configInfo.config, reportIssueOptions);
|
|
2321
|
-
result.configErrors += await reportConfigurationErrors(config);
|
|
2322
|
-
reportCheckResult(result, doc, spellResult, configInfo, config);
|
|
2323
|
-
const dep = calcDependencies(config);
|
|
2324
|
-
await cache.setCachedLintResults(result, dep.files);
|
|
2325
|
-
return result;
|
|
2326
|
-
}
|
|
2327
|
-
function reportCheckResult(result, _doc, spellResult, configInfo, config) {
|
|
2328
|
-
const elapsed$1 = result.elapsedTimeMs || 0;
|
|
2329
|
-
const dictionaries = config.dictionaries || [];
|
|
2330
|
-
if (verboseLevel > 1) {
|
|
2331
|
-
const dictsUsed = [...dictionaries].sort().map((name$1) => chalk.green(name$1)).join(", ");
|
|
2332
|
-
const msg = unindent`
|
|
2333
|
-
File type: ${config.languageId}, Language: ${config.language}, Issues: ${result.issues.length} ${elapsed$1.toFixed(2)}ms
|
|
2334
|
-
Config file Used: ${relativeToCwd(spellResult.localConfigFilepath || configInfo.source, cfg.root)}
|
|
2335
|
-
Dictionaries Used:
|
|
2336
|
-
${wordWrapAnsiText(dictsUsed, 70)}`;
|
|
2337
|
-
reporter.info(indent(msg, " "), MessageTypes.Info);
|
|
2338
|
-
}
|
|
2339
|
-
if (cfg.options.debug) {
|
|
2340
|
-
const { enabled, language, languageId, dictionaries: dictionaries$1 } = config;
|
|
2341
|
-
const msg = unindent`\
|
|
2342
|
-
Debug Config: ${formatWithOptions({
|
|
2343
|
-
depth: 2,
|
|
2344
|
-
colors: useColor
|
|
2345
|
-
}, {
|
|
2346
|
-
languageId,
|
|
2347
|
-
enabled,
|
|
2348
|
-
language,
|
|
2349
|
-
dictionaries: dictionaries$1
|
|
2350
|
-
})}`;
|
|
2351
|
-
reporter.debug(msg);
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
function mapIssue({ doc: _, ...tdo }) {
|
|
2355
|
-
const context = cfg.showContext ? extractContext(tdo, cfg.showContext) : void 0;
|
|
2356
|
-
return clean({
|
|
2357
|
-
...tdo,
|
|
2358
|
-
context
|
|
2359
|
-
});
|
|
2360
|
-
}
|
|
2361
2679
|
async function processFiles(files, configInfo, cacheSettings) {
|
|
2362
2680
|
const fileCount = Array.isArray(files) ? files.length : void 0;
|
|
2363
2681
|
const status = runResult();
|
|
@@ -2398,7 +2716,7 @@ async function runLint(cfg) {
|
|
|
2398
2716
|
return {
|
|
2399
2717
|
filename,
|
|
2400
2718
|
fileNum: index,
|
|
2401
|
-
result: await processFile(filename,
|
|
2719
|
+
result: await processFile(filename, cache, fetchResult, getProcessFileOptions(configInfo))
|
|
2402
2720
|
};
|
|
2403
2721
|
}
|
|
2404
2722
|
async function* loadAndProcessFiles() {
|
|
@@ -2426,39 +2744,10 @@ async function runLint(cfg) {
|
|
|
2426
2744
|
await cache.reconcile();
|
|
2427
2745
|
return status;
|
|
2428
2746
|
}
|
|
2429
|
-
function calcDependencies(config) {
|
|
2430
|
-
const { configFiles, dictionaryFiles } = extractDependencies(config);
|
|
2431
|
-
return { files: [...configFiles, ...dictionaryFiles] };
|
|
2432
|
-
}
|
|
2433
|
-
async function reportConfigurationErrors(config) {
|
|
2434
|
-
const errors = extractImportErrors(config);
|
|
2435
|
-
let count = 0;
|
|
2436
|
-
errors.forEach((ref) => {
|
|
2437
|
-
const key = ref.error.toString();
|
|
2438
|
-
if (configErrors.has(key)) return;
|
|
2439
|
-
configErrors.add(key);
|
|
2440
|
-
count += 1;
|
|
2441
|
-
reporter.error("Configuration", ref.error);
|
|
2442
|
-
});
|
|
2443
|
-
(await getDictionary(config)).dictionaries.forEach((dict) => {
|
|
2444
|
-
const dictErrors = dict.getErrors?.() || [];
|
|
2445
|
-
const msg = `Dictionary Error with (${dict.name})`;
|
|
2446
|
-
dictErrors.forEach((error) => {
|
|
2447
|
-
const key = msg + error.toString();
|
|
2448
|
-
if (configErrors.has(key)) return;
|
|
2449
|
-
configErrors.add(key);
|
|
2450
|
-
count += 1;
|
|
2451
|
-
reporter.error(msg, error);
|
|
2452
|
-
});
|
|
2453
|
-
});
|
|
2454
|
-
return count;
|
|
2455
|
-
}
|
|
2456
|
-
function countConfigErrors(configInfo) {
|
|
2457
|
-
return reportConfigurationErrors(configInfo.config);
|
|
2458
|
-
}
|
|
2459
2747
|
async function run() {
|
|
2460
2748
|
if (cfg.options.root) setEnvironmentVariable(ENV_CSPELL_GLOB_ROOT, cfg.root);
|
|
2461
2749
|
const configInfo = await readConfig(cfg.configFile, cfg.root, cfg.options.stopConfigSearchAt);
|
|
2750
|
+
const processFileOptions = getProcessFileOptions(configInfo);
|
|
2462
2751
|
if (cfg.options.defaultConfiguration !== void 0) configInfo.config.loadDefaultConfiguration = cfg.options.defaultConfiguration;
|
|
2463
2752
|
configInfo.config = mergeSettings(configInfo.config, cfg.cspellSettingsFromCliOptions);
|
|
2464
2753
|
const reporterConfig = clean({
|
|
@@ -2478,8 +2767,8 @@ async function runLint(cfg) {
|
|
|
2478
2767
|
if (!fileGlobs.length && !hasFileLists && !cfg.files?.length) return runResult();
|
|
2479
2768
|
header(fileGlobs, excludeGlobs);
|
|
2480
2769
|
checkGlobs(fileGlobs, reporter);
|
|
2481
|
-
if (verboseLevel > 1) reporter.info(`Config Files Found:\n ${relativeToCwd(configInfo.source)}\n`, MessageTypes.Info);
|
|
2482
|
-
const configErrors$1 = await countConfigErrors(configInfo);
|
|
2770
|
+
if (verboseLevel > 1) reporter.info(`Config Files Found:\n ${relativeToCwd(configInfo.source)}\n`, MessageTypes$1.Info);
|
|
2771
|
+
const configErrors$1 = await countConfigErrors(configInfo, processFileOptions);
|
|
2483
2772
|
if (configErrors$1 && cfg.options.exitCode !== false && !cfg.options.continueOnError) return runResult({ errors: configErrors$1 });
|
|
2484
2773
|
const { root } = cfg;
|
|
2485
2774
|
try {
|
|
@@ -2509,7 +2798,18 @@ async function runLint(cfg) {
|
|
|
2509
2798
|
files: ${formattedFiles}
|
|
2510
2799
|
wordsOnly: ${yesNo(!!cfg.options.wordsOnly)}
|
|
2511
2800
|
unique: ${yesNo(!!cfg.options.unique)}
|
|
2512
|
-
`, MessageTypes.Info);
|
|
2801
|
+
`, MessageTypes$1.Info);
|
|
2802
|
+
}
|
|
2803
|
+
function getProcessFileOptions(configInfo) {
|
|
2804
|
+
return {
|
|
2805
|
+
reporter,
|
|
2806
|
+
chalk,
|
|
2807
|
+
configInfo,
|
|
2808
|
+
cfg,
|
|
2809
|
+
verboseLevel,
|
|
2810
|
+
useColor,
|
|
2811
|
+
configErrors
|
|
2812
|
+
};
|
|
2513
2813
|
}
|
|
2514
2814
|
}
|
|
2515
2815
|
function checkGlobs(globs, reporter) {
|
|
@@ -2541,7 +2841,7 @@ async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
|
|
|
2541
2841
|
const globsToExclude = globsToExcludeRaw.filter((g) => !globPattern(g).startsWith("!"));
|
|
2542
2842
|
if (globsToExclude.length !== globsToExcludeRaw.length) {
|
|
2543
2843
|
const msg = `Negative glob exclusions are not supported: ${globsToExcludeRaw.map((g) => globPattern(g)).filter((g) => g.startsWith("!")).join(", ")}`;
|
|
2544
|
-
reporter.info(msg, MessageTypes.Warning);
|
|
2844
|
+
reporter.info(msg, MessageTypes$1.Warning);
|
|
2545
2845
|
}
|
|
2546
2846
|
const globMatcher = buildGlobMatcher(globsToExclude, root, true);
|
|
2547
2847
|
const globOptions = {
|
|
@@ -2567,13 +2867,13 @@ async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
|
|
|
2567
2867
|
const r = globMatcherExclude.matchEx(absFilename);
|
|
2568
2868
|
if (r.matched) {
|
|
2569
2869
|
const { glob: glob$2, source } = extractGlobSource(r.pattern);
|
|
2570
|
-
if (calcVerboseLevel(cfg.options) > 1) reporter.info(`Excluded File: ${path$1.relative(root, absFilename)}; Excluded by ${glob$2} from ${source}`, MessageTypes.Info);
|
|
2870
|
+
if (calcVerboseLevel(cfg.options) > 1) reporter.info(`Excluded File: ${path$1.relative(root, absFilename)}; Excluded by ${glob$2} from ${source}`, MessageTypes$1.Info);
|
|
2571
2871
|
}
|
|
2572
2872
|
return r.matched;
|
|
2573
2873
|
}
|
|
2574
2874
|
function filterOutExcludedFilesFn(globMatcherExclude) {
|
|
2575
2875
|
const excludeInfo = globMatcherExclude.patterns.map(extractGlobSource).map(({ glob: glob$2, source }) => `Glob: ${glob$2} from ${source}`).filter(uniqueFn());
|
|
2576
|
-
if (calcVerboseLevel(cfg.options) > 1) reporter.info(`Exclusion Globs: \n ${excludeInfo.join("\n ")}\n`, MessageTypes.Info);
|
|
2876
|
+
if (calcVerboseLevel(cfg.options) > 1) reporter.info(`Exclusion Globs: \n ${excludeInfo.join("\n ")}\n`, MessageTypes$1.Info);
|
|
2577
2877
|
return (filename) => !isExcluded(filename, globMatcherExclude);
|
|
2578
2878
|
}
|
|
2579
2879
|
return _determineFilesToCheck();
|
|
@@ -2653,20 +2953,12 @@ async function* concatAsyncIterables(...iterables) {
|
|
|
2653
2953
|
}
|
|
2654
2954
|
async function writeDictionaryLog() {
|
|
2655
2955
|
const fields = (getEnvironmentVariable("CSPELL_ENABLE_DICTIONARY_LOG_FIELDS") || "time, word, value").split(",").map((f) => f.trim());
|
|
2656
|
-
const data = fields.join(", ") + "\n" +
|
|
2956
|
+
const data = fields.join(", ") + "\n" + dictionaryCacheGetLog().filter((d) => d.method === "has").map((d) => fields.map((f) => f in d ? `${d[f]}` : "").join(", ")).join("\n") + "\n";
|
|
2657
2957
|
await writeFileOrStream(getEnvironmentVariable("CSPELL_ENABLE_DICTIONARY_LOG_FILE") || "cspell-dictionary-log.csv", data);
|
|
2658
2958
|
}
|
|
2659
2959
|
function globPattern(g) {
|
|
2660
2960
|
return typeof g === "string" ? g : g.glob;
|
|
2661
2961
|
}
|
|
2662
|
-
var LinterError = class extends Error {
|
|
2663
|
-
constructor(message) {
|
|
2664
|
-
super(message);
|
|
2665
|
-
}
|
|
2666
|
-
toString() {
|
|
2667
|
-
return this.message;
|
|
2668
|
-
}
|
|
2669
|
-
};
|
|
2670
2962
|
function calcVerboseLevel(options) {
|
|
2671
2963
|
return options.verboseLevel ?? (options.verbose ? 1 : 0);
|
|
2672
2964
|
}
|
|
@@ -3010,5 +3302,5 @@ function parseApplicationFeatureFlags(flags) {
|
|
|
3010
3302
|
}
|
|
3011
3303
|
|
|
3012
3304
|
//#endregion
|
|
3013
|
-
export {
|
|
3014
|
-
//# sourceMappingURL=application-
|
|
3305
|
+
export { CheckFailed as C, ApplicationError as S, padLeft as _, parseApplicationFeatureFlags as a, pruneAnsiTextStart as b, listDictionaries as c, validateUnitSize as d, unindent as f, tableToLines as g, getReporter as h, lint as i, ReportChoicesAll as l, npmPackage as m, checkText as n, suggestions as o, DEFAULT_CACHE_LOCATION as p, createInit as r, trace as s, IncludeExcludeFlag as t, cvtLinterCliCommandOptionsToLinterCliOptions as u, padWidth as v, console as w, width as x, pruneAnsiTextEnd as y };
|
|
3306
|
+
//# sourceMappingURL=application-BJHh60xM.js.map
|