1 | import { Option as CommanderOption } from 'commander';
|
2 | import * as App from './application.mjs';
|
3 | import { console } from './console.js';
|
4 | import { isDictionaryPathFormat } from './emitters/DictionaryPathFormat.js';
|
5 | import { emitTraceResults } from './emitters/traceEmitter.js';
|
6 | import { CheckFailed } from './util/errors.js';
|
7 | export function commandTrace(prog) {
|
8 | return prog
|
9 | .command('trace')
|
10 | .description(`Trace words -- Search for words in the configuration and dictionaries.`)
|
11 | .option('-c, --config <cspell.json>', 'Configuration file to use. By default cspell looks for cspell.json in the current directory.')
|
12 | .option('--locale <locale>', 'Set language locales. i.e. "en,fr" for English and French, or "en-GB" for British English.')
|
13 | .option('--language-id <language>', 'Use programming language. i.e. "php" or "scala".')
|
14 | .addOption(new CommanderOption('--languageId <language>', 'Use programming language. i.e. "php" or "scala".').hideHelp())
|
15 | .option('--allow-compound-words', 'Turn on allowCompoundWords')
|
16 | .addOption(new CommanderOption('--allowCompoundWords', 'Turn on allowCompoundWords.').hideHelp())
|
17 | .option('--no-allow-compound-words', 'Turn off allowCompoundWords')
|
18 | .option('--ignore-case', 'Ignore case and accents when searching for words.')
|
19 | .option('--no-ignore-case', 'Do not ignore case and accents when searching for words.')
|
20 | .addOption(new CommanderOption('--dictionary-path <format>', 'Configure how to display the dictionary path.')
|
21 | .choices(['hide', 'short', 'long', 'full'])
|
22 | .default('long', 'Display most of the path.'))
|
23 | .option('--stdin', 'Read words from stdin.')
|
24 | .option('--all', 'Show all dictionaries.')
|
25 | .addOption(new CommanderOption('--only-found', 'Show only dictionaries that have the words.').conflicts('all'))
|
26 | .option('--no-color', 'Turn off color.')
|
27 | .option('--color', 'Force color')
|
28 | .addOption(new CommanderOption('--default-configuration', 'Load the default configuration and dictionaries.').hideHelp())
|
29 | .addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
|
30 | .arguments('[words...]')
|
31 | .action(async (words, options) => {
|
32 | App.parseApplicationFeatureFlags(options.flag);
|
33 | let numFound = 0;
|
34 | const dictionaryPathFormat = isDictionaryPathFormat(options.dictionaryPath)
|
35 | ? options.dictionaryPath
|
36 | : 'long';
|
37 | let prefix = '';
|
38 | for await (const results of App.trace(words, options)) {
|
39 | const byWord = groupBy(results, (r) => r.word);
|
40 | for (const split of results.splits) {
|
41 | const splitResults = byWord.get(split.word) || [];
|
42 | const filtered = filterTraceResults(splitResults, options);
|
43 | emitTraceResults(split.word, split.found, filtered, {
|
44 | cwd: process.cwd(),
|
45 | dictionaryPathFormat,
|
46 | prefix,
|
47 | showWordFound: results.splits.length > 1,
|
48 | });
|
49 | prefix = '\n';
|
50 | numFound += results.reduce((n, r) => n + (r.found ? 1 : 0), 0);
|
51 | const numErrors = results.map((r) => r.errors?.length || 0).reduce((n, r) => n + r, 0);
|
52 | if (numErrors) {
|
53 | console.error('Dictionary Errors.');
|
54 | throw new CheckFailed('dictionary errors', 1);
|
55 | }
|
56 | }
|
57 | }
|
58 | if (!numFound) {
|
59 | console.error('No matches found');
|
60 | throw new CheckFailed('no matches', 1);
|
61 | }
|
62 | });
|
63 | }
|
64 | function filterTraceResults(results, options) {
|
65 | if (options.all)
|
66 | return results;
|
67 | return results.filter((r) => filterTraceResult(r, options.onlyFound));
|
68 | }
|
69 | function filterTraceResult(result, onlyFound) {
|
70 | return (result.found ||
|
71 | result.forbidden ||
|
72 | result.noSuggest ||
|
73 | !!result.preferredSuggestions ||
|
74 | (!onlyFound && result.dictActive));
|
75 | }
|
76 | function groupBy(items, key) {
|
77 | const map = new Map();
|
78 | for (const item of items) {
|
79 | const k = key(item);
|
80 | const a = map.get(k) || [];
|
81 | a.push(item);
|
82 | map.set(k, a);
|
83 | }
|
84 | return map;
|
85 | }
|
86 |
|
\ | No newline at end of file |