cspell 7.0.2 → 7.2.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 +1 -1
- package/dist/esm/app.d.ts +5 -0
- package/dist/esm/app.js +45 -0
- package/dist/esm/app.mjs +1 -0
- package/dist/esm/application.d.ts +16 -0
- package/dist/esm/application.js +88 -0
- package/dist/esm/application.mjs +1 -0
- package/dist/esm/cli-reporter.d.ts +16 -0
- package/dist/esm/cli-reporter.js +218 -0
- package/dist/esm/cli-reporter.mjs +1 -0
- package/dist/esm/commandCheck.d.ts +3 -0
- package/dist/esm/commandCheck.js +48 -0
- package/dist/esm/commandCheck.mjs +1 -0
- package/dist/esm/commandLink.d.ts +3 -0
- package/dist/esm/commandLink.js +47 -0
- package/dist/esm/commandLink.mjs +1 -0
- package/dist/esm/commandLint.d.ts +3 -0
- package/dist/esm/commandLint.js +127 -0
- package/dist/esm/commandLint.mjs +5 -1
- package/dist/esm/commandSuggestion.d.ts +3 -0
- package/dist/esm/commandSuggestion.js +61 -0
- package/dist/esm/commandSuggestion.mjs +1 -0
- package/dist/esm/commandTrace.d.ts +3 -0
- package/dist/esm/commandTrace.js +60 -0
- package/dist/esm/commandTrace.mjs +1 -0
- package/dist/esm/emitters/DictionaryPathFormat.d.ts +3 -0
- package/dist/esm/emitters/DictionaryPathFormat.js +12 -0
- package/dist/esm/emitters/DictionaryPathFormat.mjs +1 -0
- package/dist/esm/emitters/suggestionsEmitter.d.ts +13 -0
- package/dist/esm/emitters/suggestionsEmitter.js +77 -0
- package/dist/esm/emitters/suggestionsEmitter.mjs +1 -0
- package/dist/esm/emitters/traceEmitter.d.ts +21 -0
- package/dist/esm/emitters/traceEmitter.js +141 -0
- package/dist/esm/emitters/traceEmitter.mjs +1 -0
- package/dist/esm/featureFlags/featureFlags.d.ts +4 -0
- package/dist/esm/featureFlags/featureFlags.js +20 -0
- package/dist/esm/featureFlags/featureFlags.mjs +1 -0
- package/dist/esm/featureFlags/index.d.ts +2 -0
- package/dist/esm/featureFlags/index.js +2 -0
- package/dist/esm/featureFlags/index.mjs +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/link.d.ts +8 -0
- package/dist/esm/link.js +39 -0
- package/dist/esm/link.mjs +1 -0
- package/dist/esm/lint/LintRequest.d.ts +23 -0
- package/dist/esm/lint/LintRequest.js +21 -0
- package/dist/esm/lint/LintRequest.mjs +1 -0
- package/dist/esm/lint/index.d.ts +3 -0
- package/dist/esm/lint/index.js +3 -0
- package/dist/esm/lint/index.mjs +1 -0
- package/dist/esm/lint/lint.d.ts +4 -0
- package/dist/esm/lint/lint.js +469 -0
- package/dist/esm/lint/lint.mjs +1 -0
- package/dist/esm/options.d.ts +178 -0
- package/dist/esm/options.js +8 -0
- package/dist/esm/options.mjs +1 -0
- package/dist/esm/repl/index.d.ts +18 -0
- package/dist/esm/repl/index.js +47 -0
- package/dist/esm/repl/index.mjs +1 -0
- package/dist/esm/util/InMemoryReporter.d.ts +28 -0
- package/dist/esm/util/InMemoryReporter.js +43 -0
- package/dist/esm/util/InMemoryReporter.mjs +1 -0
- package/dist/esm/util/async.d.ts +3 -0
- package/dist/esm/util/async.js +4 -0
- package/dist/esm/util/async.mjs +1 -0
- package/dist/esm/util/cache/CSpellLintResultCache.d.ts +20 -0
- package/dist/esm/util/cache/CSpellLintResultCache.js +2 -0
- package/dist/esm/util/cache/CSpellLintResultCache.mjs +1 -0
- package/dist/esm/util/cache/CacheOptions.d.ts +34 -0
- package/dist/esm/util/cache/CacheOptions.js +2 -0
- package/dist/esm/util/cache/CacheOptions.mjs +1 -0
- package/dist/esm/util/cache/DiskCache.d.ts +63 -0
- package/dist/esm/util/cache/DiskCache.js +207 -0
- package/dist/esm/util/cache/DiskCache.mjs +1 -0
- package/dist/esm/util/cache/DummyCache.d.ts +11 -0
- package/dist/esm/util/cache/DummyCache.js +18 -0
- package/dist/esm/util/cache/DummyCache.mjs +1 -0
- package/dist/esm/util/cache/ObjectCollection.d.ts +17 -0
- package/dist/esm/util/cache/ObjectCollection.js +131 -0
- package/dist/esm/util/cache/ObjectCollection.mjs +1 -0
- package/dist/esm/util/cache/createCache.d.ts +31 -0
- package/dist/esm/util/cache/createCache.js +69 -0
- package/dist/esm/util/cache/createCache.mjs +1 -0
- package/dist/esm/util/cache/fileEntryCache.d.ts +9 -0
- package/dist/esm/util/cache/fileEntryCache.js +79 -0
- package/dist/esm/util/cache/fileEntryCache.mjs +1 -0
- package/dist/esm/util/cache/index.d.ts +4 -0
- package/dist/esm/util/cache/index.js +2 -0
- package/dist/esm/util/cache/index.mjs +1 -0
- package/dist/esm/util/constants.d.ts +6 -0
- package/dist/esm/util/constants.js +5 -0
- package/dist/esm/util/constants.mjs +1 -0
- package/dist/esm/util/errors.d.ts +23 -0
- package/dist/esm/util/errors.js +51 -0
- package/dist/esm/util/errors.mjs +1 -0
- package/dist/esm/util/fileHelper.d.ts +63 -0
- package/dist/esm/util/fileHelper.js +182 -0
- package/dist/esm/util/fileHelper.mjs +1 -0
- package/dist/esm/util/glob.d.ts +45 -0
- package/dist/esm/util/glob.js +137 -0
- package/dist/esm/util/glob.mjs +1 -0
- package/dist/esm/util/prefetch.d.ts +2 -0
- package/dist/esm/util/prefetch.js +16 -0
- package/dist/esm/util/prefetch.mjs +1 -0
- package/dist/esm/util/reporters.d.ts +14 -0
- package/dist/esm/util/reporters.js +62 -0
- package/dist/esm/util/reporters.mjs +1 -0
- package/dist/esm/util/stdin.d.ts +2 -0
- package/dist/esm/util/stdin.js +5 -0
- package/dist/esm/util/stdin.mjs +1 -0
- package/dist/esm/util/table.d.ts +10 -0
- package/dist/esm/util/table.js +32 -0
- package/dist/esm/util/table.mjs +1 -0
- package/dist/esm/util/timer.d.ts +8 -0
- package/dist/esm/util/timer.js +11 -0
- package/dist/esm/util/timer.mjs +1 -0
- package/dist/esm/util/types.d.ts +7 -0
- package/dist/esm/util/types.js +5 -0
- package/dist/esm/util/types.mjs +1 -0
- package/dist/esm/util/util.d.ts +13 -0
- package/dist/esm/util/util.js +45 -0
- package/dist/esm/util/util.mjs +1 -0
- package/package.json +11 -13
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Option as CommanderOption } from 'commander';
|
|
2
|
+
import * as App from './application.js';
|
|
3
|
+
import { DEFAULT_CACHE_LOCATION } from './util/cache/index.js';
|
|
4
|
+
import { CheckFailed } from './util/errors.js';
|
|
5
|
+
// interface InitOptions extends Options {}
|
|
6
|
+
const usage = `\
|
|
7
|
+
[options] [globs...] [file://<path> ...] [stdin[://<path>]]
|
|
8
|
+
|
|
9
|
+
Patterns:
|
|
10
|
+
- [globs...] Glob Patterns
|
|
11
|
+
- [stdin] Read from "stdin" assume text file.
|
|
12
|
+
- [stdin://<path>] Read from "stdin", use <path> for file type and config.
|
|
13
|
+
- [file://<path>] Check the file at <path>
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
cspell . Recursively check all files.
|
|
17
|
+
cspell lint . The same as "cspell ."
|
|
18
|
+
cspell "*.js" Check all .js files in the current directory
|
|
19
|
+
cspell "**/*.js" Check all .js files recursively
|
|
20
|
+
cspell "src/**/*.js" Only check .js under src
|
|
21
|
+
cspell "**/*.txt" "**/*.js" Check both .js and .txt files.
|
|
22
|
+
cspell "**/*.{txt,js,md}" Check .txt, .js, and .md files.
|
|
23
|
+
cat LICENSE | cspell stdin Check stdin
|
|
24
|
+
cspell stdin://docs/doc.md Check stdin as if it was "./docs/doc.md"\
|
|
25
|
+
`;
|
|
26
|
+
const advanced = `
|
|
27
|
+
More Examples:
|
|
28
|
+
|
|
29
|
+
cspell "**/*.js" --reporter @cspell/cspell-json-reporter
|
|
30
|
+
This will spell check all ".js" files recursively and use
|
|
31
|
+
"@cspell/cspell-json-reporter".
|
|
32
|
+
|
|
33
|
+
cspell . --reporter default
|
|
34
|
+
This will force the default reporter to be used overriding
|
|
35
|
+
any reporters defined in the configuration.
|
|
36
|
+
|
|
37
|
+
cspell . --reporter ./<path>/reporter.cjs
|
|
38
|
+
Use a custom reporter. See API for details.
|
|
39
|
+
|
|
40
|
+
References:
|
|
41
|
+
https://cspell.org
|
|
42
|
+
https://github.com/streetsidesoftware/cspell
|
|
43
|
+
`;
|
|
44
|
+
function collect(value, previous) {
|
|
45
|
+
if (!previous) {
|
|
46
|
+
return [value];
|
|
47
|
+
}
|
|
48
|
+
return previous.concat([value]);
|
|
49
|
+
}
|
|
50
|
+
export function commandLint(prog) {
|
|
51
|
+
const spellCheckCommand = prog.command('lint', { isDefault: true });
|
|
52
|
+
spellCheckCommand
|
|
53
|
+
.description('Check spelling')
|
|
54
|
+
.option('-c, --config <cspell.json>', 'Configuration file to use. By default cspell looks for cspell.json in the current directory.')
|
|
55
|
+
.option('-v, --verbose', 'Display more information about the files being checked and the configuration.')
|
|
56
|
+
.option('--locale <locale>', 'Set language locales. i.e. "en,fr" for English and French, or "en-GB" for British English.')
|
|
57
|
+
.option('--language-id <language>', 'Force programming language for unknown extensions. i.e. "php" or "scala"')
|
|
58
|
+
.addOption(new CommanderOption('--languageId <language>', 'Force programming language for unknown extensions. i.e. "php" or "scala"').hideHelp())
|
|
59
|
+
.option('--words-only', 'Only output the words not found in the dictionaries.')
|
|
60
|
+
.addOption(new CommanderOption('--wordsOnly', 'Only output the words not found in the dictionaries.').hideHelp())
|
|
61
|
+
.option('-u, --unique', 'Only output the first instance of a word not found in the dictionaries.')
|
|
62
|
+
.option('-e, --exclude <glob>', 'Exclude files matching the glob pattern. This option can be used multiple times to add multiple globs. ', collect)
|
|
63
|
+
.option('--file-list <path or stdin>', 'Specify a list of files to be spell checked.' +
|
|
64
|
+
' The list is filtered against the glob file patterns.' +
|
|
65
|
+
' Note: the format is 1 file path per line.', collect)
|
|
66
|
+
.option('--no-issues', 'Do not show the spelling errors.')
|
|
67
|
+
.option('--no-progress', 'Turn off progress messages')
|
|
68
|
+
.option('--no-summary', 'Turn off summary message in console.')
|
|
69
|
+
.option('-s, --silent', 'Silent mode, suppress error messages.')
|
|
70
|
+
.addOption(new CommanderOption('--quiet', 'Only show spelling issues or errors.').implies({
|
|
71
|
+
summary: false,
|
|
72
|
+
progress: false,
|
|
73
|
+
}))
|
|
74
|
+
.option('--fail-fast', 'Exit after first file with an issue or error.')
|
|
75
|
+
.addOption(new CommanderOption('--no-fail-fast', 'Process all files even if there is an error.').hideHelp())
|
|
76
|
+
.option('-r, --root <root folder>', 'Root directory, defaults to current directory.')
|
|
77
|
+
.option('--relative', 'Issues are displayed relative to root.')
|
|
78
|
+
.option('--show-context', 'Show the surrounding text around an issue.')
|
|
79
|
+
.option('--show-suggestions', 'Show spelling suggestions.')
|
|
80
|
+
.addOption(new CommanderOption('--no-show-suggestions', 'Do not show spelling suggestions or fixes.').default(undefined))
|
|
81
|
+
.addOption(new CommanderOption('--must-find-files', 'Error if no files are found.').default(true).hideHelp())
|
|
82
|
+
.option('--no-must-find-files', 'Do not error if no files are found.')
|
|
83
|
+
// The following options are planned features
|
|
84
|
+
// .option('-w, --watch', 'Watch for any changes to the matching files and report any errors')
|
|
85
|
+
// .option('--force', 'Force the exit value to always be 0')
|
|
86
|
+
.addOption(new CommanderOption('--legacy', 'Legacy output').hideHelp())
|
|
87
|
+
.addOption(new CommanderOption('--local <local>', 'Deprecated -- Use: --locale').hideHelp())
|
|
88
|
+
.option('--cache', 'Use cache to only check changed files.')
|
|
89
|
+
.option('--no-cache', 'Do not use cache.')
|
|
90
|
+
.option('--cache-reset', 'Reset the cache file.')
|
|
91
|
+
.addOption(new CommanderOption('--cache-strategy <strategy>', 'Strategy to use for detecting changed files.').choices([
|
|
92
|
+
'metadata',
|
|
93
|
+
'content',
|
|
94
|
+
]))
|
|
95
|
+
.option('--cache-location <path>', `Path to the cache file or directory. (default: "${DEFAULT_CACHE_LOCATION}")`)
|
|
96
|
+
.option('--dot', 'Include files and directories starting with `.` (period) when matching globs.')
|
|
97
|
+
.option('--gitignore', 'Ignore files matching glob patterns found in .gitignore files.')
|
|
98
|
+
.option('--no-gitignore', 'Do NOT use .gitignore files.')
|
|
99
|
+
.option('--gitignore-root <path>', 'Prevent searching for .gitignore files past root.', collect)
|
|
100
|
+
.option('--validate-directives', 'Validate in-document CSpell directives.')
|
|
101
|
+
.option('--no-validate-directives', 'Do not validate in-document CSpell directives.')
|
|
102
|
+
.option('--no-color', 'Turn off color.')
|
|
103
|
+
.option('--color', 'Force color.')
|
|
104
|
+
.addOption(new CommanderOption('--default-configuration', 'Load the default configuration and dictionaries.').hideHelp())
|
|
105
|
+
.addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
|
|
106
|
+
.option('--debug', 'Output information useful for debugging cspell.json files.')
|
|
107
|
+
.option('--reporter <module|path>', 'Specify one or more reporters to use.', collect)
|
|
108
|
+
.usage(usage)
|
|
109
|
+
.addHelpText('after', advanced)
|
|
110
|
+
.arguments('[globs...]')
|
|
111
|
+
.action((fileGlobs, options) => {
|
|
112
|
+
App.parseApplicationFeatureFlags(options.flag);
|
|
113
|
+
const { mustFindFiles, fileList } = options;
|
|
114
|
+
return App.lint(fileGlobs, options).then((result) => {
|
|
115
|
+
if (!fileGlobs.length && !result.files && !result.errors && !fileList) {
|
|
116
|
+
spellCheckCommand.outputHelp();
|
|
117
|
+
throw new CheckFailed('outputHelp', 1);
|
|
118
|
+
}
|
|
119
|
+
if (result.issues || result.errors || (mustFindFiles && !result.files)) {
|
|
120
|
+
throw new CheckFailed('check failed', 1);
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
return spellCheckCommand;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=commandLint.js.map
|
package/dist/esm/commandLint.mjs
CHANGED
|
@@ -67,7 +67,10 @@ export function commandLint(prog) {
|
|
|
67
67
|
.option('--no-progress', 'Turn off progress messages')
|
|
68
68
|
.option('--no-summary', 'Turn off summary message in console.')
|
|
69
69
|
.option('-s, --silent', 'Silent mode, suppress error messages.')
|
|
70
|
-
.addOption(new CommanderOption('--quiet', '
|
|
70
|
+
.addOption(new CommanderOption('--quiet', 'Only show spelling issues or errors.').implies({
|
|
71
|
+
summary: false,
|
|
72
|
+
progress: false,
|
|
73
|
+
}))
|
|
71
74
|
.option('--fail-fast', 'Exit after first file with an issue or error.')
|
|
72
75
|
.addOption(new CommanderOption('--no-fail-fast', 'Process all files even if there is an error.').hideHelp())
|
|
73
76
|
.option('-r, --root <root folder>', 'Root directory, defaults to current directory.')
|
|
@@ -121,3 +124,4 @@ export function commandLint(prog) {
|
|
|
121
124
|
});
|
|
122
125
|
return spellCheckCommand;
|
|
123
126
|
}
|
|
127
|
+
//# sourceMappingURL=commandLint.mjs.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Option as CommanderOption } from 'commander';
|
|
2
|
+
import * as App from './application.js';
|
|
3
|
+
import { emitSuggestionResult } from './emitters/suggestionsEmitter.js';
|
|
4
|
+
import { CheckFailed } from './util/errors.js';
|
|
5
|
+
function collect(value, previous) {
|
|
6
|
+
value = value.replace(/^=/, '');
|
|
7
|
+
if (!previous) {
|
|
8
|
+
return [value];
|
|
9
|
+
}
|
|
10
|
+
return previous.concat([value]);
|
|
11
|
+
}
|
|
12
|
+
function count(_, previous) {
|
|
13
|
+
return (previous || 0) + 1;
|
|
14
|
+
}
|
|
15
|
+
function asNumber(value, prev) {
|
|
16
|
+
return parseInt(value, 10) ?? prev;
|
|
17
|
+
}
|
|
18
|
+
export function commandSuggestion(prog) {
|
|
19
|
+
const suggestionCommand = prog.command('suggestions');
|
|
20
|
+
suggestionCommand
|
|
21
|
+
.aliases(['sug', 'suggest'])
|
|
22
|
+
.description('Spelling Suggestions for words.')
|
|
23
|
+
.option('-c, --config <cspell.json>', 'Configuration file to use. By default cspell looks for cspell.json in the current directory.')
|
|
24
|
+
.option('--locale <locale>', 'Set language locales. i.e. "en,fr" for English and French, or "en-GB" for British English.')
|
|
25
|
+
.option('--language-id <language>', 'Use programming language. i.e. "php" or "scala".')
|
|
26
|
+
.addOption(new CommanderOption('--languageId <language>', 'Use programming language. i.e. "php" or "scala".').hideHelp())
|
|
27
|
+
.option('-s, --no-strict', 'Ignore case and accents when searching for words.')
|
|
28
|
+
.option('--ignore-case', 'Alias of --no-strict.')
|
|
29
|
+
.option('--num-changes <number>', 'Number of changes allowed to a word', asNumber, 4)
|
|
30
|
+
.option('--num-suggestions <number>', 'Number of suggestions', asNumber, 8)
|
|
31
|
+
.option('--no-include-ties', 'Force the number of suggested to be limited, by not including suggestions that have the same edit cost.')
|
|
32
|
+
.option('--stdin', 'Use stdin for input.')
|
|
33
|
+
.addOption(new CommanderOption('--repl', 'REPL interface for looking up suggestions.'))
|
|
34
|
+
.option('-v, --verbose', 'Show detailed output.', count, 0)
|
|
35
|
+
.option('-d, --dictionary <dictionary name>', 'Use the dictionary specified. Only dictionaries specified will be used.', collect)
|
|
36
|
+
.option('--dictionaries <dictionary names...>', 'Use the dictionaries specified. Only dictionaries specified will be used.')
|
|
37
|
+
.option('--no-color', 'Turn off color.')
|
|
38
|
+
.option('--color', 'Force color')
|
|
39
|
+
.arguments('[words...]')
|
|
40
|
+
.action(async (words, options) => {
|
|
41
|
+
App.parseApplicationFeatureFlags(options.flag);
|
|
42
|
+
options.useStdin = options.stdin;
|
|
43
|
+
options.dictionaries = mergeArrays(options.dictionaries, options.dictionary);
|
|
44
|
+
if (!words.length && !options.useStdin && !options.repl) {
|
|
45
|
+
suggestionCommand.outputHelp();
|
|
46
|
+
throw new CheckFailed('outputHelp', 1);
|
|
47
|
+
}
|
|
48
|
+
for await (const r of App.suggestions(words, options)) {
|
|
49
|
+
emitSuggestionResult(r, options);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return suggestionCommand;
|
|
53
|
+
}
|
|
54
|
+
function mergeArrays(a, b) {
|
|
55
|
+
if (a === undefined)
|
|
56
|
+
return b;
|
|
57
|
+
if (b === undefined)
|
|
58
|
+
return a;
|
|
59
|
+
return a.concat(b);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=commandSuggestion.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Option as CommanderOption } from 'commander';
|
|
2
|
+
import * as App from './application.js';
|
|
3
|
+
import { isDictionaryPathFormat } from './emitters/DictionaryPathFormat.js';
|
|
4
|
+
import { emitTraceResults } from './emitters/traceEmitter.js';
|
|
5
|
+
import { CheckFailed } from './util/errors.js';
|
|
6
|
+
export function commandTrace(prog) {
|
|
7
|
+
return prog
|
|
8
|
+
.command('trace')
|
|
9
|
+
.description(`Trace words -- Search for words in the configuration and dictionaries.`)
|
|
10
|
+
.option('-c, --config <cspell.json>', 'Configuration file to use. By default cspell looks for cspell.json in the current directory.')
|
|
11
|
+
.option('--locale <locale>', 'Set language locales. i.e. "en,fr" for English and French, or "en-GB" for British English.')
|
|
12
|
+
.option('--language-id <language>', 'Use programming language. i.e. "php" or "scala".')
|
|
13
|
+
.addOption(new CommanderOption('--languageId <language>', 'Use programming language. i.e. "php" or "scala".').hideHelp())
|
|
14
|
+
.option('--allow-compound-words', 'Turn on allowCompoundWords')
|
|
15
|
+
.addOption(new CommanderOption('--allowCompoundWords', 'Turn on allowCompoundWords.').hideHelp())
|
|
16
|
+
.option('--no-allow-compound-words', 'Turn off allowCompoundWords')
|
|
17
|
+
.option('--ignore-case', 'Ignore case and accents when searching for words.')
|
|
18
|
+
.option('--no-ignore-case', 'Do not ignore case and accents when searching for words.')
|
|
19
|
+
.addOption(new CommanderOption('--dictionary-path <format>', 'Configure how to display the dictionary path.')
|
|
20
|
+
.choices(['hide', 'short', 'long', 'full'])
|
|
21
|
+
.default('long', 'Display most of the path.'))
|
|
22
|
+
.option('--stdin', 'Read words from stdin.')
|
|
23
|
+
.option('--all', 'Show all dictionaries.')
|
|
24
|
+
.addOption(new CommanderOption('--only-found', 'Show only dictionaries that have the words.').conflicts('all'))
|
|
25
|
+
.option('--no-color', 'Turn off color.')
|
|
26
|
+
.option('--color', 'Force color')
|
|
27
|
+
.addOption(new CommanderOption('--default-configuration', 'Load the default configuration and dictionaries.').hideHelp())
|
|
28
|
+
.addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
|
|
29
|
+
.arguments('[words...]')
|
|
30
|
+
.action(async (words, options) => {
|
|
31
|
+
App.parseApplicationFeatureFlags(options.flag);
|
|
32
|
+
let numFound = 0;
|
|
33
|
+
const dictionaryPathFormat = isDictionaryPathFormat(options.dictionaryPath)
|
|
34
|
+
? options.dictionaryPath
|
|
35
|
+
: 'long';
|
|
36
|
+
for await (const results of App.trace(words, options)) {
|
|
37
|
+
const filtered = filterTraceResults(results, options);
|
|
38
|
+
emitTraceResults(filtered, { cwd: process.cwd(), dictionaryPathFormat });
|
|
39
|
+
numFound += results.reduce((n, r) => n + (r.found ? 1 : 0), 0);
|
|
40
|
+
const numErrors = results.map((r) => r.errors?.length || 0).reduce((n, r) => n + r, 0);
|
|
41
|
+
if (numErrors) {
|
|
42
|
+
console.error('Dictionary Errors.');
|
|
43
|
+
throw new CheckFailed('dictionary errors', 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!numFound) {
|
|
47
|
+
console.error('No matches found');
|
|
48
|
+
throw new CheckFailed('no matches', 1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function filterTraceResults(results, options) {
|
|
53
|
+
if (options.all)
|
|
54
|
+
return results;
|
|
55
|
+
return results.filter((r) => filterTraceResult(r, options.onlyFound));
|
|
56
|
+
}
|
|
57
|
+
function filterTraceResult(result, onlyFound) {
|
|
58
|
+
return result.found || result.forbidden || result.noSuggest || (!onlyFound && result.dictActive);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=commandTrace.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const formats = {
|
|
2
|
+
full: true,
|
|
3
|
+
hide: true,
|
|
4
|
+
long: true,
|
|
5
|
+
short: true,
|
|
6
|
+
};
|
|
7
|
+
export function isDictionaryPathFormat(value) {
|
|
8
|
+
if (!value || typeof value !== 'string')
|
|
9
|
+
return false;
|
|
10
|
+
return value in formats;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=DictionaryPathFormat.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SuggestionsForWordResult } from 'cspell-lib';
|
|
2
|
+
export interface EmitSuggestionOptions {
|
|
3
|
+
verbose?: number;
|
|
4
|
+
lineWidth?: number;
|
|
5
|
+
output?: {
|
|
6
|
+
log: (text: string) => void;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface TimedSuggestionsForWordResult extends SuggestionsForWordResult {
|
|
10
|
+
elapsedTimeMs?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function emitSuggestionResult(result: TimedSuggestionsForWordResult, options: EmitSuggestionOptions): void;
|
|
13
|
+
//# sourceMappingURL=suggestionsEmitter.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { padLeft, padWidth, width } from '../util/util.js';
|
|
3
|
+
const regExpRTL = /([\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC י]+)/g;
|
|
4
|
+
function reverseRtlText(s) {
|
|
5
|
+
return s.replace(regExpRTL, (s) => s.split('').reverse().join(''));
|
|
6
|
+
}
|
|
7
|
+
export function emitSuggestionResult(result, options) {
|
|
8
|
+
const { word, suggestions } = result;
|
|
9
|
+
const { verbose, output = console } = options;
|
|
10
|
+
const elapsed = verbose && verbose > 1 && result.elapsedTimeMs ? ` ${result.elapsedTimeMs.toFixed(2)} ms` : '';
|
|
11
|
+
const rWord = reverseRtlText(word);
|
|
12
|
+
const wordEx = rWord !== word ? ` (${chalk.yellow(rWord)})` : '';
|
|
13
|
+
output.log((word ? chalk.yellow(word) + wordEx : chalk.yellow('<empty>')) + ':' + elapsed);
|
|
14
|
+
if (!suggestions.length) {
|
|
15
|
+
console.log(chalk.yellow(' <no suggestions>'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
function handleRtl(word) {
|
|
19
|
+
const r = reverseRtlText(word);
|
|
20
|
+
return r === word ? word : `${word} (${r})`;
|
|
21
|
+
}
|
|
22
|
+
if (verbose) {
|
|
23
|
+
const mappedSugs = suggestions.map((s) => ({
|
|
24
|
+
...s,
|
|
25
|
+
w: handleRtl(s.compoundWord || s.wordAdjustedToMatchCase || s.word),
|
|
26
|
+
}));
|
|
27
|
+
const sugWidths = mappedSugs.map((s) => width(s.w));
|
|
28
|
+
const maxWidth = sugWidths.reduce((max, len) => Math.max(max, len), 0);
|
|
29
|
+
for (const sug of mappedSugs) {
|
|
30
|
+
const { cost, dictionaries, w } = sug;
|
|
31
|
+
const padding = ' '.repeat(padWidth(w, maxWidth));
|
|
32
|
+
const forbid = sug.forbidden && sug.isPreferred
|
|
33
|
+
? chalk.red('*')
|
|
34
|
+
: sug.forbidden
|
|
35
|
+
? chalk.red('X')
|
|
36
|
+
: sug.isPreferred
|
|
37
|
+
? chalk.yellow('*')
|
|
38
|
+
: ' ';
|
|
39
|
+
const ignore = sug.noSuggest ? chalk.yellow('N') : ' ';
|
|
40
|
+
const strCost = padLeft(cost.toString(10), 4);
|
|
41
|
+
const dicts = dictionaries.map((n) => chalk.gray(n)).join(', ');
|
|
42
|
+
output.log(` - ${formatWord(w, sug)}${padding} ${forbid}${ignore} - ${chalk.yellow(strCost)} ${dicts}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const mappedSugs = suggestions.map((s) => ({ ...s, word: handleRtl(s.wordAdjustedToMatchCase || s.word) }));
|
|
47
|
+
for (const r of mappedSugs) {
|
|
48
|
+
output.log(` - ${formatWordSingle(r)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function formatWord(word, r) {
|
|
53
|
+
return r.forbidden || r.noSuggest
|
|
54
|
+
? chalk.gray(chalk.strikethrough(word))
|
|
55
|
+
: word === r.wordAdjustedToMatchCase
|
|
56
|
+
? diff(word, r.word)
|
|
57
|
+
: word;
|
|
58
|
+
}
|
|
59
|
+
function diff(wordA, wordB) {
|
|
60
|
+
const a = [...wordA];
|
|
61
|
+
const b = [...wordB];
|
|
62
|
+
const parts = [];
|
|
63
|
+
for (let idx = 0; idx < a.length; ++idx) {
|
|
64
|
+
const aa = a[idx];
|
|
65
|
+
const bb = b[idx];
|
|
66
|
+
parts.push(aa === bb ? aa : chalk.yellow(aa));
|
|
67
|
+
}
|
|
68
|
+
return parts.join('');
|
|
69
|
+
}
|
|
70
|
+
function formatWordSingle(s) {
|
|
71
|
+
let word = formatWord(s.word, s);
|
|
72
|
+
word = s.forbidden ? word + chalk.red(' X') : word;
|
|
73
|
+
word = s.noSuggest ? word + chalk.yellow(' Not suggested.') : word;
|
|
74
|
+
word = s.isPreferred ? chalk.yellow(word + ' *') : word;
|
|
75
|
+
return word;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=suggestionsEmitter.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TraceResult } from '../application.js';
|
|
2
|
+
import type { DictionaryPathFormat } from './DictionaryPathFormat.js';
|
|
3
|
+
interface PathInterface {
|
|
4
|
+
relative(from: string, to: string): string;
|
|
5
|
+
basename(path: string): string;
|
|
6
|
+
sep: string;
|
|
7
|
+
}
|
|
8
|
+
export interface EmitTraceOptions {
|
|
9
|
+
/** current working directory */
|
|
10
|
+
cwd: string;
|
|
11
|
+
lineWidth?: number;
|
|
12
|
+
dictionaryPathFormat: DictionaryPathFormat;
|
|
13
|
+
iPath?: PathInterface;
|
|
14
|
+
}
|
|
15
|
+
export declare function emitTraceResults(results: TraceResult[], options: EmitTraceOptions): void;
|
|
16
|
+
declare function trimMidPath(s: string, w: number, sep: string): string;
|
|
17
|
+
export declare const __testing__: {
|
|
18
|
+
trimMidPath: typeof trimMidPath;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=traceEmitter.d.ts.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import * as iPath from 'path';
|
|
3
|
+
import strip from 'strip-ansi';
|
|
4
|
+
import { pad, width } from '../util/util.js';
|
|
5
|
+
const colWidthDictionaryName = 20;
|
|
6
|
+
export function emitTraceResults(results, options) {
|
|
7
|
+
const maxWordLength = results
|
|
8
|
+
.map((r) => r.foundWord || r.word)
|
|
9
|
+
.reduce((a, b) => Math.max(a, width(b)), 'Word'.length);
|
|
10
|
+
const maxDictNameLength = results
|
|
11
|
+
.map((r) => r.dictName.length)
|
|
12
|
+
.reduce((a, b) => Math.max(a, b), colWidthDictionaryName);
|
|
13
|
+
const cols = {
|
|
14
|
+
word: maxWordLength,
|
|
15
|
+
dictName: maxDictNameLength,
|
|
16
|
+
terminalWidth: options.lineWidth ?? (process.stdout.columns || 120),
|
|
17
|
+
location: options.dictionaryPathFormat === 'hide' ? 0 : 30,
|
|
18
|
+
};
|
|
19
|
+
const col = new Intl.Collator();
|
|
20
|
+
results.sort((a, b) => col.compare(a.dictName, b.dictName));
|
|
21
|
+
emitHeader(cols);
|
|
22
|
+
results.forEach((r) => emitTraceResult(r, cols, options));
|
|
23
|
+
}
|
|
24
|
+
function emitHeader(colWidths) {
|
|
25
|
+
const line = [
|
|
26
|
+
pad('Word', colWidths.word),
|
|
27
|
+
'F',
|
|
28
|
+
pad('Dictionary', colWidths.dictName),
|
|
29
|
+
colWidths.location ? pad('Dictionary Location', colWidths.location) : '',
|
|
30
|
+
];
|
|
31
|
+
console.log(chalk.underline(line.join(' ').trim().slice(0, colWidths.terminalWidth)));
|
|
32
|
+
}
|
|
33
|
+
function emitTraceResult(r, colWidths, options) {
|
|
34
|
+
const { word: wordColWidth, terminalWidth, dictName: widthName } = colWidths;
|
|
35
|
+
const errors = r.errors?.map((e) => e.message)?.join('\n\t') || '';
|
|
36
|
+
const word = pad(r.foundWord || r.word, wordColWidth);
|
|
37
|
+
const cWord = word.replace(/[+]/g, chalk.yellow('+'));
|
|
38
|
+
const w = r.forbidden ? chalk.red(cWord) : chalk.green(cWord);
|
|
39
|
+
const f = calcFoundChar(r);
|
|
40
|
+
const a = r.dictActive ? '*' : ' ';
|
|
41
|
+
const dictName = pad(r.dictName.slice(0, widthName - 1) + a, widthName);
|
|
42
|
+
const dictColor = r.dictActive ? chalk.yellowBright : chalk.rgb(200, 128, 50);
|
|
43
|
+
const n = dictColor(dictName);
|
|
44
|
+
const info = [w, f, n].join(' ') + ' ';
|
|
45
|
+
const used = width(strip(info));
|
|
46
|
+
const widthSrc = terminalWidth - used;
|
|
47
|
+
const c = colorize(errors ? chalk.red : chalk.white);
|
|
48
|
+
const s = c(formatDictionaryLocation(r.dictSource, widthSrc, { iPath, ...options }));
|
|
49
|
+
const line = info + s;
|
|
50
|
+
console.log(line.trim());
|
|
51
|
+
if (errors) {
|
|
52
|
+
console.error('\t' + chalk.red(errors));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function trimMid(s, w) {
|
|
56
|
+
s = s.trim();
|
|
57
|
+
if (s.length <= w) {
|
|
58
|
+
return s;
|
|
59
|
+
}
|
|
60
|
+
const l = Math.floor((w - 3) / 2);
|
|
61
|
+
const r = Math.ceil((w - 3) / 2);
|
|
62
|
+
return s.slice(0, l) + '...' + s.slice(-r);
|
|
63
|
+
}
|
|
64
|
+
function calcFoundChar(r) {
|
|
65
|
+
const errors = r.errors?.map((e) => e.message)?.join('\n\t') || '';
|
|
66
|
+
let color = chalk.dim;
|
|
67
|
+
color = r.found ? chalk.whiteBright : color;
|
|
68
|
+
color = r.forbidden ? chalk.red : color;
|
|
69
|
+
color = r.noSuggest ? chalk.yellowBright : color;
|
|
70
|
+
color = errors ? chalk.red : color;
|
|
71
|
+
let char = '-';
|
|
72
|
+
char = r.found ? '*' : char;
|
|
73
|
+
char = r.forbidden ? '!' : char;
|
|
74
|
+
char = r.noSuggest ? 'I' : char;
|
|
75
|
+
char = errors ? 'X' : char;
|
|
76
|
+
return color(char);
|
|
77
|
+
}
|
|
78
|
+
function formatDictionaryLocation(dictSource, maxWidth, { cwd, dictionaryPathFormat: format, iPath, }) {
|
|
79
|
+
let relPath = cwd ? iPath.relative(cwd, dictSource) : dictSource;
|
|
80
|
+
const idxNodeModule = relPath.lastIndexOf('node_modules');
|
|
81
|
+
const isNodeModule = idxNodeModule >= 0;
|
|
82
|
+
if (format === 'hide')
|
|
83
|
+
return '';
|
|
84
|
+
if (format === 'short') {
|
|
85
|
+
const prefix = isNodeModule
|
|
86
|
+
? '[node_modules]/'
|
|
87
|
+
: relPath.startsWith('..' + iPath.sep + '..')
|
|
88
|
+
? '.../'
|
|
89
|
+
: relPath.startsWith('..' + iPath.sep)
|
|
90
|
+
? '../'
|
|
91
|
+
: '';
|
|
92
|
+
return prefix + iPath.basename(dictSource);
|
|
93
|
+
}
|
|
94
|
+
if (format === 'full')
|
|
95
|
+
return dictSource;
|
|
96
|
+
relPath = isNodeModule ? relPath.slice(idxNodeModule) : relPath;
|
|
97
|
+
const usePath = relPath.length < dictSource.length ? relPath : dictSource;
|
|
98
|
+
return trimMidPath(usePath, maxWidth, iPath.sep);
|
|
99
|
+
}
|
|
100
|
+
function colorize(fn) {
|
|
101
|
+
return (s) => (s ? fn(s) : '');
|
|
102
|
+
}
|
|
103
|
+
function trimMidPath(s, w, sep) {
|
|
104
|
+
if (s.length <= w)
|
|
105
|
+
return s;
|
|
106
|
+
const parts = s.split(sep);
|
|
107
|
+
if (parts[parts.length - 1].length > w)
|
|
108
|
+
return trimMid(s, w);
|
|
109
|
+
function join(left, right) {
|
|
110
|
+
// if (left === right) return parts.join(sep);
|
|
111
|
+
return [...parts.slice(0, left), '...', ...parts.slice(right)].join(sep);
|
|
112
|
+
}
|
|
113
|
+
let left = 0, right = parts.length, last = '';
|
|
114
|
+
for (let i = 0; i < parts.length; ++i) {
|
|
115
|
+
const incLeft = i & 1 ? 1 : 0;
|
|
116
|
+
const incRight = incLeft ? 0 : -1;
|
|
117
|
+
const next = join(left + incLeft, right + incRight);
|
|
118
|
+
if (next.length > w)
|
|
119
|
+
break;
|
|
120
|
+
left += incLeft;
|
|
121
|
+
right += incRight;
|
|
122
|
+
last = next;
|
|
123
|
+
}
|
|
124
|
+
for (let i = left + 1; i < right; ++i) {
|
|
125
|
+
const next = join(i, right);
|
|
126
|
+
if (next.length > w)
|
|
127
|
+
break;
|
|
128
|
+
last = next;
|
|
129
|
+
}
|
|
130
|
+
for (let i = right - 1; i > left; --i) {
|
|
131
|
+
const next = join(left, i);
|
|
132
|
+
if (next.length > w)
|
|
133
|
+
break;
|
|
134
|
+
last = next;
|
|
135
|
+
}
|
|
136
|
+
return last || trimMid(s, w);
|
|
137
|
+
}
|
|
138
|
+
export const __testing__ = {
|
|
139
|
+
trimMidPath,
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=traceEmitter.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getSystemFeatureFlags } from 'cspell-lib';
|
|
2
|
+
export function getFeatureFlags() {
|
|
3
|
+
return getSystemFeatureFlags();
|
|
4
|
+
}
|
|
5
|
+
export function parseFeatureFlags(flags, featureFlags = getFeatureFlags()) {
|
|
6
|
+
if (!flags)
|
|
7
|
+
return featureFlags;
|
|
8
|
+
const flagsKvP = flags.map((f) => f.split(':', 2));
|
|
9
|
+
for (const flag of flagsKvP) {
|
|
10
|
+
const [name, value] = flag;
|
|
11
|
+
try {
|
|
12
|
+
featureFlags.setFlag(name, value);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
console.warn(`Unknown flag: "${name}"`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return featureFlags;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=featureFlags.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './application.js';
|
|
2
|
+
export { getReporter as getDefaultReporter } from './cli-reporter.js';
|
|
3
|
+
export type { BaseOptions, LinterCliOptions as CSpellApplicationOptions, TraceOptions } from './options.js';
|
|
4
|
+
export * from '@cspell/cspell-types';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.mjs
CHANGED