/
suggestionsEmitter.ts
82 lines (69 loc) · 3.04 KB
/
suggestionsEmitter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import type { SuggestionsForWordResult, SuggestedWord } from 'cspell-lib';
import chalk = require('chalk');
import { padLeft, padWidth, width } from '../util/util';
export interface EmitSuggestionOptions {
verbose?: number;
lineWidth?: number;
output?: {
log: (text: string) => void;
};
}
export interface TimedSuggestionsForWordResult extends SuggestionsForWordResult {
elapsedTimeMs?: number;
}
const regExpRTL = /([\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC י]+)/g;
function reverseRtlText(s: string): string {
return s.replace(regExpRTL, (s) => s.split('').reverse().join(''));
}
export function emitSuggestionResult(result: TimedSuggestionsForWordResult, options: EmitSuggestionOptions): void {
const { word, suggestions } = result;
const { verbose, output = console } = options;
const elapsed = verbose && verbose > 1 && result.elapsedTimeMs ? ` ${result.elapsedTimeMs.toFixed(2)} ms` : '';
const rWord = reverseRtlText(word);
const wordEx = rWord !== word ? ` (${chalk.yellow(rWord)})` : '';
output.log((word ? chalk.yellow(word) + wordEx : chalk.yellow('<empty>')) + ':' + elapsed);
if (!suggestions.length) {
console.log(chalk.yellow(' <no suggestions>'));
return;
}
function handleRtl(word: string): string {
const r = reverseRtlText(word);
return r === word ? word : `${word} (${r})`;
}
if (verbose) {
const mappedSugs = suggestions.map((s) => ({ ...s, w: handleRtl(s.compoundWord || s.word) }));
const sugWidths = mappedSugs.map((s) => width(s.w));
const maxWidth = sugWidths.reduce((max, len) => Math.max(max, len), 0);
for (const sug of mappedSugs) {
const { cost, dictionaries, w } = sug;
const padding = ' '.repeat(padWidth(w, maxWidth));
const forbid =
sug.forbidden && sug.isPreferred
? chalk.red('*')
: sug.forbidden
? chalk.red('X')
: sug.isPreferred
? chalk.yellow('*')
: ' ';
const ignore = sug.noSuggest ? chalk.yellow('N') : ' ';
const strCost = padLeft(cost.toString(10), 4);
const dicts = dictionaries.map((n) => chalk.gray(n)).join(', ');
output.log(` - ${formatWord(w, sug)}${padding} ${forbid}${ignore} - ${chalk.yellow(strCost)} ${dicts}`);
}
} else {
const mappedSugs = suggestions.map((s) => ({ ...s, word: handleRtl(s.word) }));
for (const r of mappedSugs) {
output.log(` - ${formatWordSingle(r)}`);
}
}
}
function formatWord(word: string, r: SuggestedWord): string {
return r.forbidden || r.noSuggest ? chalk.gray(chalk.strikethrough(word)) : word;
}
function formatWordSingle(s: SuggestedWord): string {
let word = formatWord(s.word, s);
word = s.forbidden ? word + chalk.red(' X') : word;
word = s.noSuggest ? word + chalk.yellow(' Not suggested.') : word;
word = s.isPreferred ? chalk.yellow(word + ' *') : word;
return word;
}