cspell-lib 6.1.3-alpha.1 → 6.2.0-alpha.1
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/dist/Models/CSpellSettingsInternalDef.d.ts +2 -1
- package/dist/Settings/CSpellSettingsServer.js +1 -1
- package/dist/Settings/DictionarySettings.js +6 -3
- package/dist/SpellingDictionary/DictionaryLoader.d.ts +1 -31
- package/dist/SpellingDictionary/DictionaryLoader.js +5 -24
- package/dist/SpellingDictionary/SpellingDictionary.d.ts +2 -2
- package/dist/SpellingDictionary/SpellingDictionaryMethods.d.ts +2 -2
- package/dist/SpellingDictionary/SpellingDictionaryMethods.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -2
- package/dist/textValidation/ValidationTypes.d.ts +41 -0
- package/dist/textValidation/ValidationTypes.js +3 -0
- package/dist/textValidation/docValidator.d.ts +5 -4
- package/dist/textValidation/docValidator.js +26 -23
- package/dist/textValidation/index.d.ts +1 -1
- package/dist/textValidation/isWordValid.d.ts +12 -0
- package/dist/textValidation/isWordValid.js +19 -0
- package/dist/textValidation/lineValidatorFactory.d.ts +5 -0
- package/dist/textValidation/lineValidatorFactory.js +145 -0
- package/dist/textValidation/parsedText.d.ts +11 -3
- package/dist/textValidation/parsedText.js +74 -9
- package/dist/textValidation/textValidator.d.ts +5 -42
- package/dist/textValidation/textValidator.js +7 -113
- package/dist/textValidation/validator.d.ts +5 -1
- package/dist/textValidation/validator.js +4 -0
- package/dist/util/Memorizer.d.ts +8 -1
- package/dist/util/Memorizer.js +8 -2
- package/dist/util/TextMap.d.ts +15 -0
- package/dist/util/TextMap.js +62 -0
- package/dist/util/resolveFile.js +22 -4
- package/package.json +12 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSpellSettingsWithSourceTrace, DictionaryDefinitionAugmented, DictionaryDefinitionCustom, DictionaryDefinitionPreferred } from '@cspell/cspell-types';
|
|
1
|
+
import { CSpellSettingsWithSourceTrace, DictionaryDefinitionAugmented, DictionaryDefinitionCustom, DictionaryDefinitionPreferred, Parser } from '@cspell/cspell-types';
|
|
2
2
|
import { WeightMap } from 'cspell-trie-lib';
|
|
3
3
|
import { OptionalOrUndefined } from '../util/types';
|
|
4
4
|
export declare const SymbolCSpellSettingsInternal: unique symbol;
|
|
@@ -7,6 +7,7 @@ export interface CSpellSettingsInternal extends Omit<CSpellSettingsWithSourceTra
|
|
|
7
7
|
dictionaryDefinitions?: DictionaryDefinitionInternal[];
|
|
8
8
|
}
|
|
9
9
|
export interface CSpellSettingsInternalFinalized extends CSpellSettingsInternal {
|
|
10
|
+
parserFn: Parser | undefined;
|
|
10
11
|
finalized: true;
|
|
11
12
|
ignoreRegExpList: RegExp[];
|
|
12
13
|
includeRegExpList: RegExp[];
|
|
@@ -228,7 +228,7 @@ function _finalizeSettings(settings) {
|
|
|
228
228
|
finalized: true,
|
|
229
229
|
ignoreRegExpList: (0, patterns_1.resolvePatterns)(settings.ignoreRegExpList, settings.patterns),
|
|
230
230
|
includeRegExpList: (0, patterns_1.resolvePatterns)(settings.includeRegExpList, settings.patterns),
|
|
231
|
-
|
|
231
|
+
parserFn: resolveParser(settings),
|
|
232
232
|
};
|
|
233
233
|
finalized.name = 'Finalized ' + (finalized.name || '');
|
|
234
234
|
finalized.source = { name: settings.name || 'src', sources: [settings] };
|
|
@@ -50,14 +50,17 @@ function fixPath(def) {
|
|
|
50
50
|
if (def instanceof _DictionaryDefinitionInternalWithSource) {
|
|
51
51
|
return def;
|
|
52
52
|
}
|
|
53
|
-
const
|
|
54
|
-
const newPath = !filePath && !file ? '' : path.join(filePath, file);
|
|
53
|
+
const newPath = fixDicPath(def.path, def.file);
|
|
55
54
|
return {
|
|
56
55
|
...def,
|
|
57
56
|
file: undefined,
|
|
58
57
|
path: newPath,
|
|
59
58
|
};
|
|
60
59
|
}
|
|
60
|
+
function fixDicPath(defPath, defFile) {
|
|
61
|
+
const parts = [defPath || '', defFile || ''].filter((p) => !!p);
|
|
62
|
+
return parts.length > 1 ? path.join(...parts) : parts[0] || '';
|
|
63
|
+
}
|
|
61
64
|
function mapDictDefsToInternal(defs, pathToSettingsFile) {
|
|
62
65
|
return defs?.map((def) => mapDictDefToInternal(def, pathToSettingsFile));
|
|
63
66
|
}
|
|
@@ -103,7 +106,7 @@ class _DictionaryDefinitionInternalWithSource {
|
|
|
103
106
|
const defAll = def;
|
|
104
107
|
const { path: relPath = '', file = '', addWords, description, dictionaryInformation, type, repMap, noSuggest, scope, useCompounds, } = defAll;
|
|
105
108
|
const defaultPath = path.dirname(__source);
|
|
106
|
-
const filePath =
|
|
109
|
+
const filePath = fixDicPath(relPath, file);
|
|
107
110
|
const name = determineName(filePath, def);
|
|
108
111
|
const r = (0, resolveFile_1.resolveFile)(filePath, defaultPath);
|
|
109
112
|
const ddi = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Stats } from 'cspell-io';
|
|
1
2
|
import { DictionaryDefinitionInternal } from '../Models/CSpellSettingsInternalDef';
|
|
2
3
|
import { SpellingDictionary } from './SpellingDictionary';
|
|
3
4
|
export declare type LoadOptions = DictionaryDefinitionInternal;
|
|
@@ -49,37 +50,6 @@ export declare const testing: {
|
|
|
49
50
|
loadEntry: typeof loadEntry;
|
|
50
51
|
load: typeof load;
|
|
51
52
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Copied from the Node definition to avoid a dependency upon a specific version of Node
|
|
54
|
-
*/
|
|
55
|
-
interface StatsBase<T> {
|
|
56
|
-
isFile(): boolean;
|
|
57
|
-
isDirectory(): boolean;
|
|
58
|
-
isBlockDevice(): boolean;
|
|
59
|
-
isCharacterDevice(): boolean;
|
|
60
|
-
isSymbolicLink(): boolean;
|
|
61
|
-
isFIFO(): boolean;
|
|
62
|
-
isSocket(): boolean;
|
|
63
|
-
dev: T;
|
|
64
|
-
ino: T;
|
|
65
|
-
mode: T;
|
|
66
|
-
nlink: T;
|
|
67
|
-
uid: T;
|
|
68
|
-
gid: T;
|
|
69
|
-
rdev: T;
|
|
70
|
-
size: T;
|
|
71
|
-
blksize: T;
|
|
72
|
-
blocks: T;
|
|
73
|
-
atimeMs: T;
|
|
74
|
-
mtimeMs: T;
|
|
75
|
-
ctimeMs: T;
|
|
76
|
-
birthtimeMs: T;
|
|
77
|
-
atime: Date;
|
|
78
|
-
mtime: Date;
|
|
79
|
-
ctime: Date;
|
|
80
|
-
birthtime: Date;
|
|
81
|
-
}
|
|
82
|
-
export declare type Stats = StatsBase<number>;
|
|
83
53
|
export declare const __testing__: {
|
|
84
54
|
debugLog: string[];
|
|
85
55
|
};
|
|
@@ -24,11 +24,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.__testing__ = exports.testing = exports.refreshCacheEntries = exports.loadDictionarySync = exports.loadDictionary = void 0;
|
|
27
|
-
const
|
|
27
|
+
const cspell_io_1 = require("cspell-io");
|
|
28
28
|
const gensequence_1 = require("gensequence");
|
|
29
29
|
const path = __importStar(require("path"));
|
|
30
30
|
const util_1 = require("util");
|
|
31
|
-
const errors_1 = require("../util/errors");
|
|
32
31
|
const fileReader_1 = require("../util/fileReader");
|
|
33
32
|
const createSpellingDictionary_1 = require("./createSpellingDictionary");
|
|
34
33
|
const SpellingDictionaryError_1 = require("./SpellingDictionaryError");
|
|
@@ -120,7 +119,7 @@ async function refreshEntry(entry, maxAge, now) {
|
|
|
120
119
|
// Write to the ts, so the next one will not do it.
|
|
121
120
|
entry.sig = sig;
|
|
122
121
|
entry.ts = now;
|
|
123
|
-
const pStat = getStat(entry.uri);
|
|
122
|
+
const pStat = (0, cspell_io_1.getStat)(entry.uri);
|
|
124
123
|
const [newStat] = await Promise.all([pStat, entry.pending]);
|
|
125
124
|
const hasChanged = !isEqual(newStat, entry.stat);
|
|
126
125
|
const sigMatches = entry.sig === sig;
|
|
@@ -150,7 +149,7 @@ function isEqual(a, b) {
|
|
|
150
149
|
if (isError(a)) {
|
|
151
150
|
return isError(b) && a.message === b.message && a.name === b.name;
|
|
152
151
|
}
|
|
153
|
-
return !isError(b) &&
|
|
152
|
+
return !isError(b) && a.mtimeMs === b.mtimeMs && a.size === b.size && a.eTag === b.eTag;
|
|
154
153
|
}
|
|
155
154
|
function isError(e) {
|
|
156
155
|
const err = e;
|
|
@@ -158,7 +157,7 @@ function isError(e) {
|
|
|
158
157
|
}
|
|
159
158
|
function loadEntry(uri, options, now = Date.now()) {
|
|
160
159
|
const pDictionary = load(uri, options).catch((e) => (0, createSpellingDictionary_1.createFailedToLoadDictionary)(new SpellingDictionaryError_1.SpellingDictionaryLoadError(uri, options, e, 'failed to load')));
|
|
161
|
-
const pStat = getStat(uri);
|
|
160
|
+
const pStat = (0, cspell_io_1.getStat)(uri);
|
|
162
161
|
const pending = Promise.all([pDictionary, pStat]);
|
|
163
162
|
const sig = now + Math.random();
|
|
164
163
|
const entry = {
|
|
@@ -181,7 +180,7 @@ function loadEntry(uri, options, now = Date.now()) {
|
|
|
181
180
|
return entry;
|
|
182
181
|
}
|
|
183
182
|
function loadEntrySync(uri, options, now = Date.now()) {
|
|
184
|
-
const stat = getStatSync(uri);
|
|
183
|
+
const stat = (0, cspell_io_1.getStatSync)(uri);
|
|
185
184
|
const sig = now + Math.random();
|
|
186
185
|
try {
|
|
187
186
|
const dictionary = loadSync(uri, options);
|
|
@@ -289,24 +288,6 @@ exports.testing = {
|
|
|
289
288
|
loadEntry,
|
|
290
289
|
load,
|
|
291
290
|
};
|
|
292
|
-
function toError(e) {
|
|
293
|
-
if ((0, errors_1.isErrnoException)(e))
|
|
294
|
-
return e;
|
|
295
|
-
if (e instanceof Error)
|
|
296
|
-
return e;
|
|
297
|
-
return new Error((0, util_1.format)(e));
|
|
298
|
-
}
|
|
299
|
-
function getStat(uri) {
|
|
300
|
-
return fs_1.promises.stat(uri).catch((e) => toError(e));
|
|
301
|
-
}
|
|
302
|
-
function getStatSync(uri) {
|
|
303
|
-
try {
|
|
304
|
-
return (0, fs_1.statSync)(uri);
|
|
305
|
-
}
|
|
306
|
-
catch (e) {
|
|
307
|
-
return toError(e);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
291
|
exports.__testing__ = {
|
|
311
292
|
debugLog,
|
|
312
293
|
};
|
|
@@ -2,8 +2,8 @@ import type { ReplaceMap, DictionaryInformation } from '@cspell/cspell-types';
|
|
|
2
2
|
import { CompoundWordsMethod, SuggestionCollector, SuggestionResult, WeightMap } from 'cspell-trie-lib';
|
|
3
3
|
export { CompoundWordsMethod, SuggestionCollector, SuggestionResult } from 'cspell-trie-lib';
|
|
4
4
|
export interface SearchOptions {
|
|
5
|
-
useCompounds?: boolean | number;
|
|
6
|
-
ignoreCase?: boolean;
|
|
5
|
+
useCompounds?: boolean | number | undefined;
|
|
6
|
+
ignoreCase?: boolean | undefined;
|
|
7
7
|
}
|
|
8
8
|
export interface SuggestOptions {
|
|
9
9
|
/**
|
|
@@ -5,7 +5,7 @@ export { impersonateCollector, suggestionCollector } from 'cspell-trie-lib';
|
|
|
5
5
|
export declare type FilterSuggestionsPredicate = (word: SuggestionResult) => boolean;
|
|
6
6
|
export declare type SuggestArgs = Parameters<SpellingDictionary['suggest']> | Parameters<(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean) => SuggestionResult[]>;
|
|
7
7
|
export declare const defaultNumSuggestions = 10;
|
|
8
|
-
|
|
8
|
+
declare function wordSearchFormsArray(word: string, isDictionaryCaseSensitive: boolean, ignoreCase: boolean): string[];
|
|
9
9
|
export declare function wordSearchForms(word: string, isDictionaryCaseSensitive: boolean, ignoreCase: boolean): Set<string>;
|
|
10
10
|
export declare function wordSuggestFormsArray(word: string): string[];
|
|
11
11
|
export declare function wordSuggestForms(word: string): Set<string>;
|
|
@@ -20,7 +20,7 @@ export declare function suggestArgsToSuggestOptions(args: SuggestArgs): SuggestO
|
|
|
20
20
|
export declare function createWeightMapFromDictionaryInformation(di: undefined): undefined;
|
|
21
21
|
export declare function createWeightMapFromDictionaryInformation(di: DictionaryInformation): WeightMap;
|
|
22
22
|
export declare function createWeightMapFromDictionaryInformation(di: DictionaryInformation | undefined): WeightMap | undefined;
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const __testMethods__: {
|
|
24
24
|
wordSearchForms: typeof wordSearchForms;
|
|
25
25
|
wordSearchFormsArray: typeof wordSearchFormsArray;
|
|
26
26
|
wordDictionaryForms: typeof wordDictionaryForms;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.__testMethods__ = exports.createWeightMapFromDictionaryInformation = exports.suggestArgsToSuggestOptions = exports.hasOptionToSearchOption = exports.wordDictionaryFormsCollector = exports.wordSuggestForms = exports.wordSuggestFormsArray = exports.wordSearchForms = exports.defaultNumSuggestions = exports.suggestionCollector = exports.impersonateCollector = void 0;
|
|
4
4
|
const cspell_trie_lib_1 = require("cspell-trie-lib");
|
|
5
5
|
const trie_util_1 = require("cspell-trie-lib/dist/lib/trie-util");
|
|
6
6
|
const gensequence_1 = require("gensequence");
|
|
@@ -12,7 +12,6 @@ exports.defaultNumSuggestions = 10;
|
|
|
12
12
|
function wordSearchFormsArray(word, isDictionaryCaseSensitive, ignoreCase) {
|
|
13
13
|
return [...wordSearchForms(word, isDictionaryCaseSensitive, ignoreCase)];
|
|
14
14
|
}
|
|
15
|
-
exports.wordSearchFormsArray = wordSearchFormsArray;
|
|
16
15
|
function wordSearchForms(word, isDictionaryCaseSensitive, ignoreCase) {
|
|
17
16
|
const forms = new Set();
|
|
18
17
|
word = word.normalize('NFC');
|
|
@@ -82,8 +81,9 @@ function wordDictionaryFormsCollector(prefixNoCase) {
|
|
|
82
81
|
};
|
|
83
82
|
}
|
|
84
83
|
exports.wordDictionaryFormsCollector = wordDictionaryFormsCollector;
|
|
84
|
+
const DEFAULT_HAS_OPTIONS = Object.freeze({});
|
|
85
85
|
function hasOptionToSearchOption(opt) {
|
|
86
|
-
return !opt ?
|
|
86
|
+
return !opt ? DEFAULT_HAS_OPTIONS : opt;
|
|
87
87
|
}
|
|
88
88
|
exports.hasOptionToSearchOption = hasOptionToSearchOption;
|
|
89
89
|
function suggestArgsToSuggestOptions(args) {
|
|
@@ -105,7 +105,7 @@ function createWeightMapFromDictionaryInformation(di) {
|
|
|
105
105
|
return di ? (0, cspell_trie_lib_1.mapDictionaryInformationToWeightMap)(di) : undefined;
|
|
106
106
|
}
|
|
107
107
|
exports.createWeightMapFromDictionaryInformation = createWeightMapFromDictionaryInformation;
|
|
108
|
-
exports.
|
|
108
|
+
exports.__testMethods__ = {
|
|
109
109
|
wordSearchForms,
|
|
110
110
|
wordSearchFormsArray,
|
|
111
111
|
wordDictionaryForms,
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as Link from './Settings/index.link';
|
|
|
4
4
|
import { SpellingDictionaryCollection } from './SpellingDictionary';
|
|
5
5
|
import * as Text from './util/text';
|
|
6
6
|
export * from '@cspell/cspell-types';
|
|
7
|
-
export
|
|
7
|
+
export { asyncIterableToArray, readFile, readFileSync, writeToFile, writeToFileIterable, writeToFileIterableP, } from 'cspell-io';
|
|
8
8
|
export { ExcludeFilesGlobMap, ExclusionFunction } from './exclusionHelper';
|
|
9
9
|
export { getLanguagesForExt } from './LanguageIds';
|
|
10
10
|
export { createTextDocument, updateTextDocument } from './Models/TextDocument';
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
26
26
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getDictionary = exports.clearCachedFiles = exports.ExclusionHelper = exports.Link = exports.Text = exports.validateText = exports.IncludeExcludeFlag = exports.checkText = exports.resolveFile = exports.setLogger = exports.getLogger = exports.traceWordsAsync = exports.traceWords = exports.DocumentValidator = exports.suggestionsForWords = exports.suggestionsForWord = exports.SuggestionError = exports.SpellingDictionaryLoadError = exports.SpellingDictionaryCollection = exports.refreshDictionaryCache = exports.isSpellingDictionaryLoadError = exports.createSpellingDictionary = exports.CompoundWordsMethod = exports.spellCheckFile = exports.spellCheckDocument = exports.isBinaryFile = exports.fileToDocument = exports.determineFinalDocumentSettings = exports.constructSettingsForText = exports.combineTextAndLanguageSettings = exports.defaultSettingsFilename = exports.updateTextDocument = exports.createTextDocument = exports.getLanguagesForExt = void 0;
|
|
29
|
+
exports.getDictionary = exports.clearCachedFiles = exports.ExclusionHelper = exports.Link = exports.Text = exports.validateText = exports.IncludeExcludeFlag = exports.checkText = exports.resolveFile = exports.setLogger = exports.getLogger = exports.traceWordsAsync = exports.traceWords = exports.DocumentValidator = exports.suggestionsForWords = exports.suggestionsForWord = exports.SuggestionError = exports.SpellingDictionaryLoadError = exports.SpellingDictionaryCollection = exports.refreshDictionaryCache = exports.isSpellingDictionaryLoadError = exports.createSpellingDictionary = exports.CompoundWordsMethod = exports.spellCheckFile = exports.spellCheckDocument = exports.isBinaryFile = exports.fileToDocument = exports.determineFinalDocumentSettings = exports.constructSettingsForText = exports.combineTextAndLanguageSettings = exports.defaultSettingsFilename = exports.updateTextDocument = exports.createTextDocument = exports.getLanguagesForExt = exports.writeToFileIterableP = exports.writeToFileIterable = exports.writeToFile = exports.readFileSync = exports.readFile = exports.asyncIterableToArray = void 0;
|
|
30
30
|
const ExclusionHelper = __importStar(require("./exclusionHelper"));
|
|
31
31
|
exports.ExclusionHelper = ExclusionHelper;
|
|
32
32
|
const Settings_1 = require("./Settings");
|
|
@@ -37,7 +37,13 @@ const SpellingDictionary_1 = require("./SpellingDictionary");
|
|
|
37
37
|
const Text = __importStar(require("./util/text"));
|
|
38
38
|
exports.Text = Text;
|
|
39
39
|
__exportStar(require("@cspell/cspell-types"), exports);
|
|
40
|
-
|
|
40
|
+
var cspell_io_1 = require("cspell-io");
|
|
41
|
+
Object.defineProperty(exports, "asyncIterableToArray", { enumerable: true, get: function () { return cspell_io_1.asyncIterableToArray; } });
|
|
42
|
+
Object.defineProperty(exports, "readFile", { enumerable: true, get: function () { return cspell_io_1.readFile; } });
|
|
43
|
+
Object.defineProperty(exports, "readFileSync", { enumerable: true, get: function () { return cspell_io_1.readFileSync; } });
|
|
44
|
+
Object.defineProperty(exports, "writeToFile", { enumerable: true, get: function () { return cspell_io_1.writeToFile; } });
|
|
45
|
+
Object.defineProperty(exports, "writeToFileIterable", { enumerable: true, get: function () { return cspell_io_1.writeToFileIterable; } });
|
|
46
|
+
Object.defineProperty(exports, "writeToFileIterableP", { enumerable: true, get: function () { return cspell_io_1.writeToFileIterableP; } });
|
|
41
47
|
var LanguageIds_1 = require("./LanguageIds");
|
|
42
48
|
Object.defineProperty(exports, "getLanguagesForExt", { enumerable: true, get: function () { return LanguageIds_1.getLanguagesForExt; } });
|
|
43
49
|
var TextDocument_1 = require("./Models/TextDocument");
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { MappedText, TextOffset as TextOffsetRW } from '@cspell/cspell-types';
|
|
2
|
+
export declare type TextOffsetRO = Readonly<TextOffsetRW>;
|
|
3
|
+
export interface ValidationOptions extends IncludeExcludeOptions {
|
|
4
|
+
maxNumberOfProblems?: number;
|
|
5
|
+
maxDuplicateProblems?: number;
|
|
6
|
+
minWordLength?: number;
|
|
7
|
+
flagWords?: string[];
|
|
8
|
+
allowCompoundWords?: boolean;
|
|
9
|
+
/** ignore case when checking words against dictionary or ignore words list */
|
|
10
|
+
ignoreCase: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface CheckOptions extends ValidationOptions {
|
|
13
|
+
allowCompoundWords: boolean;
|
|
14
|
+
ignoreCase: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface IncludeExcludeOptions {
|
|
17
|
+
ignoreRegExpList?: RegExp[];
|
|
18
|
+
includeRegExpList?: RegExp[];
|
|
19
|
+
}
|
|
20
|
+
export interface WordRangeAcc {
|
|
21
|
+
textOffset: TextOffsetRO;
|
|
22
|
+
isIncluded: boolean;
|
|
23
|
+
rangePos: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ValidationResult extends TextOffsetRW {
|
|
26
|
+
line: TextOffsetRW;
|
|
27
|
+
isFlagged?: boolean | undefined;
|
|
28
|
+
isFound?: boolean | undefined;
|
|
29
|
+
}
|
|
30
|
+
export declare type ValidationResultRO = Readonly<ValidationResult>;
|
|
31
|
+
export declare type LineValidator = (line: LineSegment) => Iterable<ValidationResult>;
|
|
32
|
+
export interface LineSegment {
|
|
33
|
+
line: TextOffsetRO;
|
|
34
|
+
segment: TextOffsetRO;
|
|
35
|
+
}
|
|
36
|
+
export interface MappedTextValidationResult extends MappedText {
|
|
37
|
+
isFlagged?: boolean | undefined;
|
|
38
|
+
isFound?: boolean | undefined;
|
|
39
|
+
}
|
|
40
|
+
export declare type TextValidator = (text: MappedText) => Iterable<MappedTextValidationResult>;
|
|
41
|
+
//# sourceMappingURL=ValidationTypes.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { CSpellUserSettings, ParsedText } from '@cspell/cspell-types';
|
|
1
|
+
import type { CSpellUserSettings, MappedText, ParsedText } from '@cspell/cspell-types';
|
|
2
2
|
import { CSpellSettingsInternal, CSpellSettingsInternalFinalized } from '../Models/CSpellSettingsInternalDef';
|
|
3
3
|
import { TextDocument } from '../Models/TextDocument';
|
|
4
4
|
import { SpellingDictionaryCollection } from '../SpellingDictionary';
|
|
5
5
|
import { MatchRange } from '../util/TextRange';
|
|
6
6
|
import { SimpleRange } from './parsedText';
|
|
7
|
-
import {
|
|
7
|
+
import type { TextValidator } from './ValidationTypes';
|
|
8
|
+
import { ValidationOptions } from './ValidationTypes';
|
|
8
9
|
import { ValidateTextOptions, ValidationIssue } from './validator';
|
|
9
10
|
export interface DocumentValidatorOptions extends ValidateTextOptions {
|
|
10
11
|
/**
|
|
@@ -81,8 +82,8 @@ interface Preparations {
|
|
|
81
82
|
docSettings: CSpellSettingsInternal;
|
|
82
83
|
finalSettings: CSpellSettingsInternalFinalized;
|
|
83
84
|
includeRanges: MatchRange[];
|
|
84
|
-
|
|
85
|
-
segmenter: (
|
|
85
|
+
textValidator: TextValidator;
|
|
86
|
+
segmenter: (texts: MappedText) => Iterable<MappedText>;
|
|
86
87
|
shouldCheck: boolean;
|
|
87
88
|
validateOptions: ValidationOptions;
|
|
88
89
|
localConfig: CSpellUserSettings | undefined;
|
|
@@ -17,6 +17,8 @@ const simpleCache_1 = require("../util/simpleCache");
|
|
|
17
17
|
const timer_1 = require("../util/timer");
|
|
18
18
|
const util_1 = require("../util/util");
|
|
19
19
|
const determineTextDocumentSettings_1 = require("./determineTextDocumentSettings");
|
|
20
|
+
const lineValidatorFactory_1 = require("./lineValidatorFactory");
|
|
21
|
+
const parsedText_1 = require("./parsedText");
|
|
20
22
|
const textValidator_1 = require("./textValidator");
|
|
21
23
|
const validator_1 = require("./validator");
|
|
22
24
|
const ERROR_NOT_PREPARED = 'Validator Must be prepared before calling this function.';
|
|
@@ -64,8 +66,8 @@ class DocumentValidator {
|
|
|
64
66
|
const finalSettings = (0, Settings_1.finalizeSettings)(docSettings);
|
|
65
67
|
const validateOptions = (0, validator_1.settingsToValidateOptions)(finalSettings);
|
|
66
68
|
const includeRanges = (0, textValidator_1.calcTextInclusionRanges)(this._document.text, validateOptions);
|
|
67
|
-
const segmenter = (0,
|
|
68
|
-
const
|
|
69
|
+
const segmenter = (0, parsedText_1.createMappedTextSegmenter)(includeRanges);
|
|
70
|
+
const textValidator = (0, lineValidatorFactory_1.textValidatorFactory)(dict, validateOptions);
|
|
69
71
|
this._preparations = {
|
|
70
72
|
config,
|
|
71
73
|
dictionary: dict,
|
|
@@ -75,7 +77,7 @@ class DocumentValidator {
|
|
|
75
77
|
validateOptions,
|
|
76
78
|
includeRanges,
|
|
77
79
|
segmenter,
|
|
78
|
-
|
|
80
|
+
textValidator,
|
|
79
81
|
localConfig,
|
|
80
82
|
localConfigFilepath: localConfig?.__importRef?.filename,
|
|
81
83
|
};
|
|
@@ -112,8 +114,8 @@ class DocumentValidator {
|
|
|
112
114
|
const finalSettings = (0, Settings_1.finalizeSettings)(docSettings);
|
|
113
115
|
const validateOptions = (0, validator_1.settingsToValidateOptions)(finalSettings);
|
|
114
116
|
const includeRanges = (0, textValidator_1.calcTextInclusionRanges)(this._document.text, validateOptions);
|
|
115
|
-
const segmenter = (0,
|
|
116
|
-
const
|
|
117
|
+
const segmenter = (0, parsedText_1.createMappedTextSegmenter)(includeRanges);
|
|
118
|
+
const textValidator = (0, lineValidatorFactory_1.textValidatorFactory)(dict, validateOptions);
|
|
117
119
|
this._preparations = {
|
|
118
120
|
config,
|
|
119
121
|
dictionary: dict,
|
|
@@ -123,7 +125,7 @@ class DocumentValidator {
|
|
|
123
125
|
validateOptions,
|
|
124
126
|
includeRanges,
|
|
125
127
|
segmenter,
|
|
126
|
-
|
|
128
|
+
textValidator,
|
|
127
129
|
localConfig,
|
|
128
130
|
localConfigFilepath: localConfig?.__importRef?.filename,
|
|
129
131
|
};
|
|
@@ -140,8 +142,8 @@ class DocumentValidator {
|
|
|
140
142
|
const finalSettings = (0, Settings_1.finalizeSettings)(docSettings);
|
|
141
143
|
const validateOptions = (0, validator_1.settingsToValidateOptions)(finalSettings);
|
|
142
144
|
const includeRanges = (0, textValidator_1.calcTextInclusionRanges)(this._document.text, validateOptions);
|
|
143
|
-
const segmenter = (0,
|
|
144
|
-
const
|
|
145
|
+
const segmenter = (0, parsedText_1.createMappedTextSegmenter)(includeRanges);
|
|
146
|
+
const textValidator = (0, lineValidatorFactory_1.textValidatorFactory)(dict, validateOptions);
|
|
145
147
|
this._preparations = {
|
|
146
148
|
...prep,
|
|
147
149
|
dictionary: dict,
|
|
@@ -150,7 +152,7 @@ class DocumentValidator {
|
|
|
150
152
|
validateOptions,
|
|
151
153
|
includeRanges,
|
|
152
154
|
segmenter,
|
|
153
|
-
|
|
155
|
+
textValidator,
|
|
154
156
|
};
|
|
155
157
|
this._preparationTime = timer.elapsed();
|
|
156
158
|
}
|
|
@@ -167,22 +169,23 @@ class DocumentValidator {
|
|
|
167
169
|
check(parsedText) {
|
|
168
170
|
(0, assert_1.default)(this._ready);
|
|
169
171
|
(0, assert_1.default)(this._preparations, ERROR_NOT_PREPARED);
|
|
170
|
-
const {
|
|
171
|
-
const { segmenter, lineValidator } = this._preparations;
|
|
172
|
+
const { segmenter, textValidator } = this._preparations;
|
|
172
173
|
// Determine settings for text range
|
|
173
174
|
// Slice text based upon include ranges
|
|
174
175
|
// Check text against dictionaries.
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
176
|
+
const document = this._document;
|
|
177
|
+
let line = undefined;
|
|
178
|
+
function mapToIssue(issue) {
|
|
179
|
+
const { range, text, isFlagged, isFound } = issue;
|
|
180
|
+
const offset = range[0];
|
|
181
|
+
const length = range[1] - range[0];
|
|
182
|
+
(0, assert_1.default)(!line || line.offset <= offset);
|
|
183
|
+
if (!line || line.offset + line.text.length <= offset) {
|
|
184
|
+
line = document.lineAt(offset);
|
|
185
|
+
}
|
|
186
|
+
return { text, offset, line, length, isFlagged, isFound };
|
|
187
|
+
}
|
|
188
|
+
const issues = [...(0, cspell_pipe_1.pipeSync)(segmenter(parsedText), (0, cspell_pipe_1.opConcatMap)(textValidator), (0, cspell_pipe_1.opMap)(mapToIssue))];
|
|
186
189
|
if (!this.options.generateSuggestions) {
|
|
187
190
|
return issues;
|
|
188
191
|
}
|
|
@@ -253,7 +256,7 @@ class DocumentValidator {
|
|
|
253
256
|
}
|
|
254
257
|
_parse() {
|
|
255
258
|
(0, assert_1.default)(this._preparations, ERROR_NOT_PREPARED);
|
|
256
|
-
const parser = this._preparations.finalSettings.
|
|
259
|
+
const parser = this._preparations.finalSettings.parserFn;
|
|
257
260
|
if (typeof parser !== 'object')
|
|
258
261
|
return this.defaultParser();
|
|
259
262
|
return parser.parse(this.document.text, this.document.uri.path).parsedTexts;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { calcTextInclusionRanges } from './textValidator';
|
|
2
|
-
export type { CheckOptions, IncludeExcludeOptions, ValidationOptions, ValidationResult } from './
|
|
2
|
+
export type { CheckOptions, IncludeExcludeOptions, ValidationOptions, ValidationResult } from './ValidationTypes';
|
|
3
3
|
export { checkText, IncludeExcludeFlag, validateText } from './validator';
|
|
4
4
|
export type { CheckTextInfo, TextInfoItem, ValidateTextOptions, ValidationIssue } from './validator';
|
|
5
5
|
export { DocumentValidator } from './docValidator';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SpellingDictionary } from '../SpellingDictionary/SpellingDictionary';
|
|
2
|
+
import { TextOffsetRO } from './ValidationTypes';
|
|
3
|
+
export interface IsWordValidOptions {
|
|
4
|
+
ignoreCase: boolean;
|
|
5
|
+
useCompounds: boolean | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function hasWordCheck(dict: SpellingDictionary, word: string, options: IsWordValidOptions): boolean;
|
|
8
|
+
export declare function isWordValidWithEscapeRetry(dict: SpellingDictionary, wo: TextOffsetRO, line: TextOffsetRO, options: IsWordValidOptions): boolean;
|
|
9
|
+
export declare const __testing__: {
|
|
10
|
+
hasWordCheck: typeof hasWordCheck;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=isWordValid.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__testing__ = exports.isWordValidWithEscapeRetry = exports.hasWordCheck = void 0;
|
|
4
|
+
function hasWordCheck(dict, word, options) {
|
|
5
|
+
word = word.replace(/\\/g, '');
|
|
6
|
+
return dict.has(word, options);
|
|
7
|
+
}
|
|
8
|
+
exports.hasWordCheck = hasWordCheck;
|
|
9
|
+
function isWordValidWithEscapeRetry(dict, wo, line, options) {
|
|
10
|
+
const firstTry = hasWordCheck(dict, wo.text, options);
|
|
11
|
+
return (firstTry ||
|
|
12
|
+
// Drop the first letter if it is preceded by a '\'.
|
|
13
|
+
(line.text[wo.offset - line.offset - 1] === '\\' && hasWordCheck(dict, wo.text.slice(1), options)));
|
|
14
|
+
}
|
|
15
|
+
exports.isWordValidWithEscapeRetry = isWordValidWithEscapeRetry;
|
|
16
|
+
exports.__testing__ = {
|
|
17
|
+
hasWordCheck,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=isWordValid.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SpellingDictionary } from '../SpellingDictionary/SpellingDictionary';
|
|
2
|
+
import type { LineValidator, TextValidator, ValidationOptions } from './ValidationTypes';
|
|
3
|
+
export declare function lineValidatorFactory(dict: SpellingDictionary, options: ValidationOptions): LineValidator;
|
|
4
|
+
export declare function textValidatorFactory(dict: SpellingDictionary, options: ValidationOptions): TextValidator;
|
|
5
|
+
//# sourceMappingURL=lineValidatorFactory.d.ts.map
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.textValidatorFactory = exports.lineValidatorFactory = void 0;
|
|
27
|
+
const cspell_pipe_1 = require("@cspell/cspell-pipe");
|
|
28
|
+
const gensequence_1 = require("gensequence");
|
|
29
|
+
const RxPat = __importStar(require("../Settings/RegExpPatterns"));
|
|
30
|
+
const Text = __importStar(require("../util/text"));
|
|
31
|
+
const util_1 = require("../util/util");
|
|
32
|
+
const wordSplitter_1 = require("../util/wordSplitter");
|
|
33
|
+
const textValidator_1 = require("./textValidator");
|
|
34
|
+
const isWordValid_1 = require("./isWordValid");
|
|
35
|
+
const parsedText_1 = require("./parsedText");
|
|
36
|
+
function lineValidatorFactory(dict, options) {
|
|
37
|
+
const { minWordLength = textValidator_1.defaultMinWordLength, flagWords = [], allowCompoundWords = false, ignoreCase = true, } = options;
|
|
38
|
+
const hasWordOptions = {
|
|
39
|
+
ignoreCase,
|
|
40
|
+
useCompounds: allowCompoundWords || undefined, // let the dictionaries decide on useCompounds if allow is false
|
|
41
|
+
};
|
|
42
|
+
const dictCol = dict;
|
|
43
|
+
const setOfFlagWords = new Set(flagWords);
|
|
44
|
+
const setOfKnownSuccessfulWords = new Set();
|
|
45
|
+
const rememberFilter = (fn) => (v) => {
|
|
46
|
+
const keep = fn(v);
|
|
47
|
+
if (!keep) {
|
|
48
|
+
setOfKnownSuccessfulWords.add(v.text);
|
|
49
|
+
}
|
|
50
|
+
return keep;
|
|
51
|
+
};
|
|
52
|
+
const filterAlreadyChecked = (wo) => {
|
|
53
|
+
return !setOfKnownSuccessfulWords.has(wo.text);
|
|
54
|
+
};
|
|
55
|
+
function testForFlaggedWord(wo) {
|
|
56
|
+
const text = wo.text;
|
|
57
|
+
return setOfFlagWords.has(text) || setOfFlagWords.has(text.toLowerCase()) || dictCol.isForbidden(text);
|
|
58
|
+
}
|
|
59
|
+
function isWordIgnored(word) {
|
|
60
|
+
return dict.isNoSuggestWord(word, options);
|
|
61
|
+
}
|
|
62
|
+
function isWordFlagged(word) {
|
|
63
|
+
const isIgnored = isWordIgnored(word.text);
|
|
64
|
+
const isFlagged = !isIgnored && testForFlaggedWord(word);
|
|
65
|
+
return isFlagged;
|
|
66
|
+
}
|
|
67
|
+
function checkFlagWords(word) {
|
|
68
|
+
word.isFlagged = isWordFlagged(word);
|
|
69
|
+
return word;
|
|
70
|
+
}
|
|
71
|
+
function checkWord(word, options) {
|
|
72
|
+
const isIgnored = isWordIgnored(word.text);
|
|
73
|
+
const { isFlagged = !isIgnored && testForFlaggedWord(word) } = word;
|
|
74
|
+
const isFound = isFlagged
|
|
75
|
+
? undefined
|
|
76
|
+
: isIgnored || (0, isWordValid_1.isWordValidWithEscapeRetry)(dictCol, word, word.line, options);
|
|
77
|
+
return (0, util_1.clean)({ ...word, isFlagged, isFound });
|
|
78
|
+
}
|
|
79
|
+
const fn = (lineSegment) => {
|
|
80
|
+
function splitterIsValid(word) {
|
|
81
|
+
return (setOfKnownSuccessfulWords.has(word.text) ||
|
|
82
|
+
(!testForFlaggedWord(word) &&
|
|
83
|
+
(0, isWordValid_1.isWordValidWithEscapeRetry)(dictCol, word, lineSegment.line, hasWordOptions)));
|
|
84
|
+
}
|
|
85
|
+
function checkFullWord(vr) {
|
|
86
|
+
if (vr.isFlagged) {
|
|
87
|
+
return [vr];
|
|
88
|
+
}
|
|
89
|
+
const codeWordResults = (0, cspell_pipe_1.toArray)((0, cspell_pipe_1.pipeSync)(Text.extractWordsFromCodeTextOffset(vr), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opMap)((t) => ({ ...t, line: vr.line })), (0, cspell_pipe_1.opMap)(checkFlagWords), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.text.length >= minWordLength || !!wo.isFlagged)), (0, cspell_pipe_1.opMap)((wo) => (wo.isFlagged ? wo : checkWord(wo, hasWordOptions))), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.isFlagged || !wo.isFound)), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => !RxPat.regExRepeatedChar.test(wo.text))),
|
|
90
|
+
// get back the original text.
|
|
91
|
+
(0, cspell_pipe_1.opMap)((wo) => ({
|
|
92
|
+
...wo,
|
|
93
|
+
text: Text.extractText(lineSegment.segment, wo.offset, wo.offset + wo.text.length),
|
|
94
|
+
}))));
|
|
95
|
+
if (!codeWordResults.length || isWordIgnored(vr.text) || checkWord(vr, hasWordOptions).isFound) {
|
|
96
|
+
rememberFilter((_) => false)(vr);
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return codeWordResults;
|
|
100
|
+
}
|
|
101
|
+
function checkPossibleWords(possibleWord) {
|
|
102
|
+
if (isWordFlagged(possibleWord)) {
|
|
103
|
+
const vr = {
|
|
104
|
+
...possibleWord,
|
|
105
|
+
line: lineSegment.line,
|
|
106
|
+
isFlagged: true,
|
|
107
|
+
};
|
|
108
|
+
return [vr];
|
|
109
|
+
}
|
|
110
|
+
const mismatches = (0, cspell_pipe_1.toArray)((0, cspell_pipe_1.pipeSync)(Text.extractWordsFromTextOffset(possibleWord), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opMap)((wo) => ({ ...wo, line: lineSegment.line })), (0, cspell_pipe_1.opMap)(checkFlagWords), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.text.length >= minWordLength || !!wo.isFlagged)), (0, cspell_pipe_1.opConcatMap)(checkFullWord)));
|
|
111
|
+
if (mismatches.length) {
|
|
112
|
+
// Try the more expensive word splitter
|
|
113
|
+
const splitResult = (0, wordSplitter_1.split)(lineSegment.segment, possibleWord.offset, splitterIsValid);
|
|
114
|
+
const nonMatching = splitResult.words.filter((w) => !w.isFound);
|
|
115
|
+
if (nonMatching.length < mismatches.length) {
|
|
116
|
+
return nonMatching.map((w) => ({ ...w, line: lineSegment.line })).map(checkFlagWords);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return mismatches;
|
|
120
|
+
}
|
|
121
|
+
const checkedPossibleWords = (0, gensequence_1.genSequence)((0, cspell_pipe_1.pipeSync)(Text.extractPossibleWordsFromTextOffset(lineSegment.segment), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opConcatMap)(checkPossibleWords)));
|
|
122
|
+
return checkedPossibleWords;
|
|
123
|
+
};
|
|
124
|
+
return fn;
|
|
125
|
+
}
|
|
126
|
+
exports.lineValidatorFactory = lineValidatorFactory;
|
|
127
|
+
function textValidatorFactory(dict, options) {
|
|
128
|
+
const lineValidator = lineValidatorFactory(dict, options);
|
|
129
|
+
function validator(pText) {
|
|
130
|
+
const { text, range: srcRange, map } = pText;
|
|
131
|
+
const srcOffset = srcRange[0];
|
|
132
|
+
const segment = { text, offset: 0 };
|
|
133
|
+
const lineSegment = { line: segment, segment };
|
|
134
|
+
function mapBackToOriginSimple(vr) {
|
|
135
|
+
const { text, offset, isFlagged, isFound } = vr;
|
|
136
|
+
const r = (0, parsedText_1.mapRangeBackToOriginalPos)([offset, offset + text.length], map);
|
|
137
|
+
const range = [r[0] + srcOffset, r[1] + srcOffset];
|
|
138
|
+
return { text, range, isFlagged, isFound };
|
|
139
|
+
}
|
|
140
|
+
return [...lineValidator(lineSegment)].map(mapBackToOriginSimple);
|
|
141
|
+
}
|
|
142
|
+
return validator;
|
|
143
|
+
}
|
|
144
|
+
exports.textValidatorFactory = textValidatorFactory;
|
|
145
|
+
//# sourceMappingURL=lineValidatorFactory.js.map
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MappedText } from '@cspell/cspell-types';
|
|
2
2
|
import { ValidationIssue } from './validator';
|
|
3
|
+
import * as TextRange from '../util/TextRange';
|
|
3
4
|
export declare type Offset = number;
|
|
4
5
|
export declare type SimpleRange = readonly [Offset, Offset];
|
|
5
|
-
export declare function mapIssueBackToOriginalPos(
|
|
6
|
-
export declare function mapRangeBackToOriginalPos(offRange: SimpleRange, map: number[]): SimpleRange;
|
|
6
|
+
export declare function mapIssueBackToOriginalPos(mappedText: MappedText, issue: ValidationIssue): ValidationIssue;
|
|
7
|
+
export declare function mapRangeBackToOriginalPos(offRange: SimpleRange, map: number[] | undefined): SimpleRange;
|
|
8
|
+
export declare function mapRangeToLocal(rangeOrig: SimpleRange, map: number[] | undefined): SimpleRange;
|
|
9
|
+
/**
|
|
10
|
+
* Factory to create a segmentation function that will segment MappedText against a set of includeRanges.
|
|
11
|
+
* The function produced is optimized for forward scanning. It will perform poorly for randomly ordered offsets.
|
|
12
|
+
* @param includeRanges Allowed ranges for words.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createMappedTextSegmenter(includeRanges: TextRange.MatchRange[]): (text: MappedText) => Iterable<MappedText>;
|
|
7
15
|
//# sourceMappingURL=parsedText.d.ts.map
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mapRangeBackToOriginalPos = exports.mapIssueBackToOriginalPos = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.createMappedTextSegmenter = exports.mapRangeToLocal = exports.mapRangeBackToOriginalPos = exports.mapIssueBackToOriginalPos = void 0;
|
|
4
|
+
const TextMap_1 = require("../util/TextMap");
|
|
5
|
+
function mapIssueBackToOriginalPos(mappedText, issue) {
|
|
6
|
+
if (!mappedText.map || mappedText.map.length === 0)
|
|
6
7
|
return issue;
|
|
7
|
-
const textOff = mapTextOffsetBackToOriginalPos(
|
|
8
|
+
const textOff = mapTextOffsetBackToOriginalPos(mappedText, issue);
|
|
8
9
|
return {
|
|
9
10
|
...issue,
|
|
10
11
|
...textOff,
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
exports.mapIssueBackToOriginalPos = mapIssueBackToOriginalPos;
|
|
14
|
-
function mapTextOffsetBackToOriginalPos(
|
|
15
|
-
if (!
|
|
15
|
+
function mapTextOffsetBackToOriginalPos(mappedText, textOff) {
|
|
16
|
+
if (!mappedText.map || !mappedText.map.length)
|
|
16
17
|
return textOff;
|
|
17
|
-
const off = textOff.offset -
|
|
18
|
-
const range = mapRangeBackToOriginalPos([off, off + (textOff.length ?? textOff.text.length)],
|
|
18
|
+
const off = textOff.offset - mappedText.range[0];
|
|
19
|
+
const range = mapRangeBackToOriginalPos([off, off + (textOff.length ?? textOff.text.length)], mappedText.map);
|
|
19
20
|
return {
|
|
20
21
|
text: textOff.text,
|
|
21
|
-
offset:
|
|
22
|
+
offset: mappedText.range[0] + range[0],
|
|
22
23
|
length: range[1] - range[0],
|
|
23
24
|
};
|
|
24
25
|
}
|
|
@@ -42,4 +43,68 @@ function mapRangeBackToOriginalPos(offRange, map) {
|
|
|
42
43
|
return [iA, iB];
|
|
43
44
|
}
|
|
44
45
|
exports.mapRangeBackToOriginalPos = mapRangeBackToOriginalPos;
|
|
46
|
+
function mapRangeToLocal(rangeOrig, map) {
|
|
47
|
+
if (!map || !map.length)
|
|
48
|
+
return rangeOrig;
|
|
49
|
+
const [start, end] = rangeOrig;
|
|
50
|
+
let i = 0, j = 0, p = 0;
|
|
51
|
+
while (p < map.length && map[p] < start) {
|
|
52
|
+
i = map[p];
|
|
53
|
+
j = map[p + 1];
|
|
54
|
+
p += 2;
|
|
55
|
+
}
|
|
56
|
+
const jA = start - i + j;
|
|
57
|
+
while (p < map.length && map[p] < end) {
|
|
58
|
+
i = map[p];
|
|
59
|
+
j = map[p + 1];
|
|
60
|
+
p += 2;
|
|
61
|
+
}
|
|
62
|
+
const jB = end - i + j;
|
|
63
|
+
return [jA, jB];
|
|
64
|
+
}
|
|
65
|
+
exports.mapRangeToLocal = mapRangeToLocal;
|
|
66
|
+
/**
|
|
67
|
+
* Factory to create a segmentation function that will segment MappedText against a set of includeRanges.
|
|
68
|
+
* The function produced is optimized for forward scanning. It will perform poorly for randomly ordered offsets.
|
|
69
|
+
* @param includeRanges Allowed ranges for words.
|
|
70
|
+
*/
|
|
71
|
+
function createMappedTextSegmenter(includeRanges) {
|
|
72
|
+
let rangePos = 0;
|
|
73
|
+
function* segmenter(pText) {
|
|
74
|
+
if (!includeRanges.length) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const range = pText.range;
|
|
78
|
+
const textEndPos = range[1];
|
|
79
|
+
let textStartPos = range[0];
|
|
80
|
+
while (rangePos && (rangePos >= includeRanges.length || includeRanges[rangePos].startPos > textStartPos)) {
|
|
81
|
+
rangePos -= 1;
|
|
82
|
+
}
|
|
83
|
+
const cur = includeRanges[rangePos];
|
|
84
|
+
if (textEndPos <= cur.endPos && textStartPos >= cur.startPos) {
|
|
85
|
+
yield pText;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
while (textStartPos < textEndPos) {
|
|
89
|
+
while (includeRanges[rangePos] && includeRanges[rangePos].endPos <= textStartPos) {
|
|
90
|
+
rangePos += 1;
|
|
91
|
+
}
|
|
92
|
+
if (!includeRanges[rangePos]) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
const { startPos, endPos } = includeRanges[rangePos];
|
|
96
|
+
if (textEndPos < startPos) {
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
const a = Math.max(textStartPos, startPos);
|
|
100
|
+
const b = Math.min(textEndPos, endPos);
|
|
101
|
+
if (a !== b) {
|
|
102
|
+
yield (0, TextMap_1.extractTextMapRangeOrigin)(pText, [a, b]);
|
|
103
|
+
}
|
|
104
|
+
textStartPos = b;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return segmenter;
|
|
108
|
+
}
|
|
109
|
+
exports.createMappedTextSegmenter = createMappedTextSegmenter;
|
|
45
110
|
//# sourceMappingURL=parsedText.js.map
|
|
@@ -1,53 +1,17 @@
|
|
|
1
|
-
import type { TextOffset as TextOffsetRW } from '@cspell/cspell-types';
|
|
2
1
|
import { Sequence } from 'gensequence';
|
|
3
2
|
import { SpellingDictionary } from '../SpellingDictionary/SpellingDictionary';
|
|
4
3
|
import * as TextRange from '../util/TextRange';
|
|
5
|
-
|
|
6
|
-
export interface ValidationOptions extends IncludeExcludeOptions {
|
|
7
|
-
maxNumberOfProblems?: number;
|
|
8
|
-
maxDuplicateProblems?: number;
|
|
9
|
-
minWordLength?: number;
|
|
10
|
-
flagWords?: string[];
|
|
11
|
-
allowCompoundWords?: boolean;
|
|
12
|
-
/** ignore case when checking words against dictionary or ignore words list */
|
|
13
|
-
ignoreCase: boolean;
|
|
14
|
-
}
|
|
15
|
-
export interface CheckOptions extends ValidationOptions {
|
|
16
|
-
allowCompoundWords: boolean;
|
|
17
|
-
ignoreCase: boolean;
|
|
18
|
-
}
|
|
19
|
-
export interface IncludeExcludeOptions {
|
|
20
|
-
ignoreRegExpList?: RegExp[];
|
|
21
|
-
includeRegExpList?: RegExp[];
|
|
22
|
-
}
|
|
23
|
-
export interface WordRangeAcc {
|
|
24
|
-
textOffset: TextOffsetRO;
|
|
25
|
-
isIncluded: boolean;
|
|
26
|
-
rangePos: number;
|
|
27
|
-
}
|
|
28
|
-
export interface ValidationResult extends TextOffsetRW {
|
|
29
|
-
line: TextOffsetRW;
|
|
30
|
-
isFlagged?: boolean;
|
|
31
|
-
isFound?: boolean;
|
|
32
|
-
}
|
|
4
|
+
import { IncludeExcludeOptions, LineSegment, ValidationOptions, ValidationResult } from './ValidationTypes';
|
|
33
5
|
export declare const defaultMaxNumberOfProblems = 200;
|
|
34
6
|
export declare const defaultMaxDuplicateProblems = 5;
|
|
35
7
|
export declare const defaultMinWordLength = 4;
|
|
36
8
|
export declare const minWordSplitLen = 3;
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated
|
|
11
|
+
* @deprecation Use spellCheckDocument
|
|
12
|
+
*/
|
|
37
13
|
export declare function validateText(text: string, dict: SpellingDictionary, options: ValidationOptions): Sequence<ValidationResult>;
|
|
38
14
|
export declare function calcTextInclusionRanges(text: string, options: IncludeExcludeOptions): TextRange.MatchRange[];
|
|
39
|
-
export interface LineSegment {
|
|
40
|
-
line: TextOffsetRO;
|
|
41
|
-
segment: TextOffsetRO;
|
|
42
|
-
}
|
|
43
|
-
export declare type LineValidator = (line: LineSegment) => Iterable<ValidationResult>;
|
|
44
|
-
export declare function lineValidatorFactory(dict: SpellingDictionary, options: ValidationOptions): LineValidator;
|
|
45
|
-
export declare function isWordValid(dict: SpellingDictionary, wo: TextOffsetRO, line: TextOffsetRO, options: HasWordOptions): boolean;
|
|
46
|
-
export interface HasWordOptions {
|
|
47
|
-
ignoreCase: boolean;
|
|
48
|
-
useCompounds: boolean | undefined;
|
|
49
|
-
}
|
|
50
|
-
export declare function hasWordCheck(dict: SpellingDictionary, word: string, options: HasWordOptions): boolean;
|
|
51
15
|
/**
|
|
52
16
|
* Returns a mapper function that will segment a TextOffset based upon the includeRanges.
|
|
53
17
|
* This function is optimized for forward scanning. It will perform poorly for randomly ordered offsets.
|
|
@@ -57,5 +21,4 @@ export declare function mapLineSegmentAgainstRangesFactory(includeRanges: TextRa
|
|
|
57
21
|
export declare const _testMethods: {
|
|
58
22
|
mapWordsAgainstRanges: typeof mapLineSegmentAgainstRangesFactory;
|
|
59
23
|
};
|
|
60
|
-
export {};
|
|
61
24
|
//# sourceMappingURL=textValidator.d.ts.map
|
|
@@ -23,23 +23,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports._testMethods = exports.mapLineSegmentAgainstRangesFactory = exports.
|
|
26
|
+
exports._testMethods = exports.mapLineSegmentAgainstRangesFactory = exports.calcTextInclusionRanges = exports.validateText = exports.minWordSplitLen = exports.defaultMinWordLength = exports.defaultMaxDuplicateProblems = exports.defaultMaxNumberOfProblems = void 0;
|
|
27
27
|
const cspell_pipe_1 = require("@cspell/cspell-pipe");
|
|
28
28
|
const gensequence_1 = require("gensequence");
|
|
29
|
-
const RxPat = __importStar(require("../Settings/RegExpPatterns"));
|
|
30
29
|
const Text = __importStar(require("../util/text"));
|
|
31
30
|
const TextRange = __importStar(require("../util/TextRange"));
|
|
32
|
-
const
|
|
33
|
-
const wordSplitter_1 = require("../util/wordSplitter");
|
|
31
|
+
const lineValidatorFactory_1 = require("./lineValidatorFactory");
|
|
34
32
|
exports.defaultMaxNumberOfProblems = 200;
|
|
35
33
|
exports.defaultMaxDuplicateProblems = 5;
|
|
36
34
|
exports.defaultMinWordLength = 4;
|
|
37
35
|
exports.minWordSplitLen = 3;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated
|
|
38
|
+
* @deprecation Use spellCheckDocument
|
|
39
|
+
*/
|
|
38
40
|
function validateText(text, dict, options) {
|
|
39
41
|
const { maxNumberOfProblems = exports.defaultMaxNumberOfProblems, maxDuplicateProblems = exports.defaultMaxDuplicateProblems } = options;
|
|
40
42
|
const mapOfProblems = new Map();
|
|
41
43
|
const includeRanges = calcTextInclusionRanges(text, options);
|
|
42
|
-
const validator = lineValidatorFactory(dict, options);
|
|
44
|
+
const validator = (0, lineValidatorFactory_1.lineValidatorFactory)(dict, options);
|
|
43
45
|
const iter = (0, cspell_pipe_1.pipeSync)(Text.extractLinesOfText(text), (0, cspell_pipe_1.opConcatMap)(mapLineToLineSegments(includeRanges)), (0, cspell_pipe_1.opConcatMap)(validator), (0, cspell_pipe_1.opFilter)((wo) => {
|
|
44
46
|
const word = wo.text;
|
|
45
47
|
// Keep track of the number of times we have seen the same problem
|
|
@@ -59,114 +61,6 @@ function calcTextInclusionRanges(text, options) {
|
|
|
59
61
|
return includeRanges;
|
|
60
62
|
}
|
|
61
63
|
exports.calcTextInclusionRanges = calcTextInclusionRanges;
|
|
62
|
-
function lineValidatorFactory(dict, options) {
|
|
63
|
-
const { minWordLength = exports.defaultMinWordLength, flagWords = [], allowCompoundWords = false, ignoreCase = true, } = options;
|
|
64
|
-
const hasWordOptions = {
|
|
65
|
-
ignoreCase,
|
|
66
|
-
useCompounds: allowCompoundWords || undefined, // let the dictionaries decide on useCompounds if allow is false
|
|
67
|
-
};
|
|
68
|
-
const dictCol = dict;
|
|
69
|
-
const setOfFlagWords = new Set(flagWords);
|
|
70
|
-
const setOfKnownSuccessfulWords = new Set();
|
|
71
|
-
const rememberFilter = (fn) => (v) => {
|
|
72
|
-
const keep = fn(v);
|
|
73
|
-
if (!keep) {
|
|
74
|
-
setOfKnownSuccessfulWords.add(v.text);
|
|
75
|
-
}
|
|
76
|
-
return keep;
|
|
77
|
-
};
|
|
78
|
-
const filterAlreadyChecked = (wo) => {
|
|
79
|
-
return !setOfKnownSuccessfulWords.has(wo.text);
|
|
80
|
-
};
|
|
81
|
-
function testForFlaggedWord(wo) {
|
|
82
|
-
const text = wo.text;
|
|
83
|
-
return setOfFlagWords.has(text) || setOfFlagWords.has(text.toLowerCase()) || dictCol.isForbidden(text);
|
|
84
|
-
}
|
|
85
|
-
function isWordIgnored(word) {
|
|
86
|
-
return dict.isNoSuggestWord(word, options);
|
|
87
|
-
}
|
|
88
|
-
function isWordFlagged(word) {
|
|
89
|
-
const isIgnored = isWordIgnored(word.text);
|
|
90
|
-
const isFlagged = !isIgnored && testForFlaggedWord(word);
|
|
91
|
-
return isFlagged;
|
|
92
|
-
}
|
|
93
|
-
function checkFlagWords(word) {
|
|
94
|
-
word.isFlagged = isWordFlagged(word);
|
|
95
|
-
return word;
|
|
96
|
-
}
|
|
97
|
-
function checkWord(word, options) {
|
|
98
|
-
const isIgnored = isWordIgnored(word.text);
|
|
99
|
-
const { isFlagged = !isIgnored && testForFlaggedWord(word) } = word;
|
|
100
|
-
const isFound = isFlagged ? undefined : isIgnored || isWordValid(dictCol, word, word.line, options);
|
|
101
|
-
return (0, util_1.clean)({ ...word, isFlagged, isFound });
|
|
102
|
-
}
|
|
103
|
-
const fn = (lineSegment) => {
|
|
104
|
-
function splitterIsValid(word) {
|
|
105
|
-
return (setOfKnownSuccessfulWords.has(word.text) ||
|
|
106
|
-
(!testForFlaggedWord(word) && isWordValid(dictCol, word, lineSegment.line, hasWordOptions)));
|
|
107
|
-
}
|
|
108
|
-
function checkFullWord(vr) {
|
|
109
|
-
if (vr.isFlagged) {
|
|
110
|
-
return [vr];
|
|
111
|
-
}
|
|
112
|
-
const codeWordResults = (0, cspell_pipe_1.toArray)((0, cspell_pipe_1.pipeSync)(Text.extractWordsFromCodeTextOffset(vr), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opMap)((t) => ({ ...t, line: vr.line })), (0, cspell_pipe_1.opMap)(checkFlagWords), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.text.length >= minWordLength || !!wo.isFlagged)), (0, cspell_pipe_1.opMap)((wo) => (wo.isFlagged ? wo : checkWord(wo, hasWordOptions))), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.isFlagged || !wo.isFound)), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => !RxPat.regExRepeatedChar.test(wo.text))), // Filter out any repeated characters like xxxxxxxxxx
|
|
113
|
-
// get back the original text.
|
|
114
|
-
(0, cspell_pipe_1.opMap)((wo) => ({
|
|
115
|
-
...wo,
|
|
116
|
-
text: Text.extractText(lineSegment.segment, wo.offset, wo.offset + wo.text.length),
|
|
117
|
-
}))));
|
|
118
|
-
if (!codeWordResults.length || isWordIgnored(vr.text) || checkWord(vr, hasWordOptions).isFound) {
|
|
119
|
-
rememberFilter((_) => false)(vr);
|
|
120
|
-
return [];
|
|
121
|
-
}
|
|
122
|
-
return codeWordResults;
|
|
123
|
-
}
|
|
124
|
-
function checkPossibleWords(possibleWord) {
|
|
125
|
-
if (isWordFlagged(possibleWord)) {
|
|
126
|
-
const vr = {
|
|
127
|
-
...possibleWord,
|
|
128
|
-
line: lineSegment.line,
|
|
129
|
-
isFlagged: true,
|
|
130
|
-
};
|
|
131
|
-
return [vr];
|
|
132
|
-
}
|
|
133
|
-
const mismatches = (0, cspell_pipe_1.toArray)((0, cspell_pipe_1.pipeSync)(Text.extractWordsFromTextOffset(possibleWord), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opMap)((wo) => ({ ...wo, line: lineSegment.line })), (0, cspell_pipe_1.opMap)(checkFlagWords), (0, cspell_pipe_1.opFilter)(rememberFilter((wo) => wo.text.length >= minWordLength || !!wo.isFlagged)), (0, cspell_pipe_1.opConcatMap)(checkFullWord)));
|
|
134
|
-
if (mismatches.length) {
|
|
135
|
-
// Try the more expensive word splitter
|
|
136
|
-
const splitResult = (0, wordSplitter_1.split)(lineSegment.segment, possibleWord.offset, splitterIsValid);
|
|
137
|
-
const nonMatching = splitResult.words.filter((w) => !w.isFound);
|
|
138
|
-
if (nonMatching.length < mismatches.length) {
|
|
139
|
-
return nonMatching.map((w) => ({ ...w, line: lineSegment.line })).map(checkFlagWords);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return mismatches;
|
|
143
|
-
}
|
|
144
|
-
const checkedPossibleWords = (0, gensequence_1.genSequence)((0, cspell_pipe_1.pipeSync)(Text.extractPossibleWordsFromTextOffset(lineSegment.segment), (0, cspell_pipe_1.opFilter)(filterAlreadyChecked), (0, cspell_pipe_1.opConcatMap)(checkPossibleWords)));
|
|
145
|
-
return checkedPossibleWords;
|
|
146
|
-
};
|
|
147
|
-
return fn;
|
|
148
|
-
}
|
|
149
|
-
exports.lineValidatorFactory = lineValidatorFactory;
|
|
150
|
-
function isWordValid(dict, wo, line, options) {
|
|
151
|
-
const firstTry = hasWordCheck(dict, wo.text, options);
|
|
152
|
-
return (firstTry ||
|
|
153
|
-
// Drop the first letter if it is preceded by a '\'.
|
|
154
|
-
(line.text[wo.offset - line.offset - 1] === '\\' && hasWordCheck(dict, wo.text.slice(1), options)));
|
|
155
|
-
}
|
|
156
|
-
exports.isWordValid = isWordValid;
|
|
157
|
-
function hasWordCheck(dict, word, options) {
|
|
158
|
-
word = word.replace(/\\/g, '');
|
|
159
|
-
// Do not pass allowCompounds down if it is false, that allows for the dictionary to override the value based upon its own settings.
|
|
160
|
-
return dict.has(word, convertCheckOptionsToHasOptions(options));
|
|
161
|
-
}
|
|
162
|
-
exports.hasWordCheck = hasWordCheck;
|
|
163
|
-
function convertCheckOptionsToHasOptions(opt) {
|
|
164
|
-
const { ignoreCase, useCompounds } = opt;
|
|
165
|
-
return (0, util_1.clean)({
|
|
166
|
-
ignoreCase,
|
|
167
|
-
useCompounds,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
64
|
function mapLineToLineSegments(includeRanges) {
|
|
171
65
|
const mapAgainstRanges = mapLineSegmentAgainstRangesFactory(includeRanges);
|
|
172
66
|
return (line) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSpellUserSettings } from '@cspell/cspell-types';
|
|
2
2
|
import { CSpellSettingsInternalFinalized } from '../Models/CSpellSettingsInternalDef';
|
|
3
|
-
import type { ValidationOptions, ValidationResult } from './
|
|
3
|
+
import type { ValidationOptions, ValidationResult } from './ValidationTypes';
|
|
4
4
|
export declare const diagSource = "cSpell Checker";
|
|
5
5
|
export interface ValidationIssue extends ValidationResult {
|
|
6
6
|
suggestions?: string[];
|
|
@@ -11,6 +11,10 @@ export interface ValidateTextOptions {
|
|
|
11
11
|
/** The number of suggestions to generate. The higher the number the longer it takes. */
|
|
12
12
|
numSuggestions?: number;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated
|
|
16
|
+
* @deprecationMessage Use spellCheckDocument
|
|
17
|
+
*/
|
|
14
18
|
export declare function validateText(text: string, settings: CSpellUserSettings, options?: ValidateTextOptions): Promise<ValidationIssue[]>;
|
|
15
19
|
export declare function settingsToValidateOptions(settings: CSpellSettingsInternalFinalized): ValidationOptions;
|
|
16
20
|
export interface CheckTextInfo {
|
|
@@ -30,6 +30,10 @@ const Memorizer_1 = require("../util/Memorizer");
|
|
|
30
30
|
const util_1 = require("../util/util");
|
|
31
31
|
const textValidator_1 = require("./textValidator");
|
|
32
32
|
exports.diagSource = 'cSpell Checker';
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated
|
|
35
|
+
* @deprecationMessage Use spellCheckDocument
|
|
36
|
+
*/
|
|
33
37
|
async function validateText(text, settings, options = {}) {
|
|
34
38
|
const finalSettings = Settings.finalizeSettings(settings);
|
|
35
39
|
const dict = await (0, SpellingDictionary_1.getDictionaryInternal)(finalSettings);
|
package/dist/util/Memorizer.d.ts
CHANGED
|
@@ -48,11 +48,18 @@ export declare function memorizeLastCall<T, K0, K1, K2>(fn: (...p: [K0, K1, K2])
|
|
|
48
48
|
export declare function memorizeLastCall<T, K0, K1, K2, K3>(fn: (...p: [K0, K1, K2, K3]) => T): (...p: [K0, K1, K2, K3]) => T;
|
|
49
49
|
export declare function memorizeLastCall<T, K>(fn: (...p: [...K[]]) => T): (...p: [...K[]]) => T;
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* Creates a function that will call `fn` exactly once when invoked and remember the value returned.
|
|
52
|
+
* All subsequent calls will return exactly same value.
|
|
52
53
|
* @param fn - function to call
|
|
53
54
|
* @returns a new function
|
|
54
55
|
*/
|
|
55
56
|
export declare function callOnce<T>(fn: () => T): () => T;
|
|
57
|
+
/**
|
|
58
|
+
* Create a function that will memorize all calls to `fn` to ensure that `fn` is
|
|
59
|
+
* called exactly once for each unique set of arguments.
|
|
60
|
+
* @param fn - function to memorize
|
|
61
|
+
* @returns a function
|
|
62
|
+
*/
|
|
56
63
|
export declare function memorizerAll<K extends any[], T>(fn: (...p: K) => T): (...p: K) => T;
|
|
57
64
|
export {};
|
|
58
65
|
//# sourceMappingURL=Memorizer.d.ts.map
|
package/dist/util/Memorizer.js
CHANGED
|
@@ -74,7 +74,8 @@ function memorizeLastCall(fn) {
|
|
|
74
74
|
}
|
|
75
75
|
exports.memorizeLastCall = memorizeLastCall;
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* Creates a function that will call `fn` exactly once when invoked and remember the value returned.
|
|
78
|
+
* All subsequent calls will return exactly same value.
|
|
78
79
|
* @param fn - function to call
|
|
79
80
|
* @returns a new function
|
|
80
81
|
*/
|
|
@@ -91,7 +92,12 @@ function callOnce(fn) {
|
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
exports.callOnce = callOnce;
|
|
94
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Create a function that will memorize all calls to `fn` to ensure that `fn` is
|
|
97
|
+
* called exactly once for each unique set of arguments.
|
|
98
|
+
* @param fn - function to memorize
|
|
99
|
+
* @returns a function
|
|
100
|
+
*/
|
|
95
101
|
function memorizerAll(fn) {
|
|
96
102
|
const r = {};
|
|
97
103
|
function find(p) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MappedText } from '@cspell/cspell-types';
|
|
2
|
+
import { Range } from '@cspell/cspell-types/Parser';
|
|
3
|
+
/**
|
|
4
|
+
* Extract a substring from a TextMap.
|
|
5
|
+
* @param textMap - A text range with an optional map
|
|
6
|
+
* @param extractRange - The range in the original document to extract
|
|
7
|
+
* @returns The TextMap covering extractRange
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractTextMapRangeOrigin(textMap: MappedText, extractRange: Range): MappedText;
|
|
10
|
+
interface WithRange {
|
|
11
|
+
readonly range: Range;
|
|
12
|
+
}
|
|
13
|
+
export declare function doesIntersect(textMap: WithRange, rangeOrigin: Range): boolean;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=TextMap.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.doesIntersect = exports.extractTextMapRangeOrigin = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
/**
|
|
9
|
+
* Extract a substring from a TextMap.
|
|
10
|
+
* @param textMap - A text range with an optional map
|
|
11
|
+
* @param extractRange - The range in the original document to extract
|
|
12
|
+
* @returns The TextMap covering extractRange
|
|
13
|
+
*/
|
|
14
|
+
function extractTextMapRangeOrigin(textMap, extractRange) {
|
|
15
|
+
const { text: srcTxt, range: srcRange, map: srcMap } = textMap;
|
|
16
|
+
const [r0, r1] = srcRange;
|
|
17
|
+
const startOrig = Math.min(Math.max(extractRange[0], r0), r1);
|
|
18
|
+
const endOrig = Math.min(Math.max(extractRange[1], r0), r1);
|
|
19
|
+
const a = startOrig - r0;
|
|
20
|
+
const b = endOrig - r0;
|
|
21
|
+
const range = [startOrig, endOrig];
|
|
22
|
+
if (!srcMap || !srcMap.length || a === b) {
|
|
23
|
+
const text = srcTxt.slice(a, b);
|
|
24
|
+
return { text, range };
|
|
25
|
+
}
|
|
26
|
+
(0, assert_1.default)((srcMap.length & 1) === 0, 'Map must be pairs of values.');
|
|
27
|
+
const mapLen = srcMap.length;
|
|
28
|
+
const mapEndSrc = srcMap[mapLen - 2];
|
|
29
|
+
const mapEndDst = srcMap[mapLen - 1];
|
|
30
|
+
const endDiff = srcTxt.length - mapEndDst;
|
|
31
|
+
const head = !srcMap[0] && !srcMap[1] ? [] : [0, 0];
|
|
32
|
+
const tail = [mapEndSrc + endDiff, mapEndDst + endDiff];
|
|
33
|
+
const sMap = head.concat(srcMap).concat(tail);
|
|
34
|
+
let idx = 0;
|
|
35
|
+
for (; idx < sMap.length && a >= sMap[idx]; idx += 2) {
|
|
36
|
+
// empty
|
|
37
|
+
}
|
|
38
|
+
const aIdx = idx;
|
|
39
|
+
idx -= 2;
|
|
40
|
+
const a0 = a - sMap[idx];
|
|
41
|
+
const a1 = a0 + sMap[idx + 1];
|
|
42
|
+
for (; idx < sMap.length && b > sMap[idx]; idx += 2) {
|
|
43
|
+
// empty
|
|
44
|
+
}
|
|
45
|
+
const bIdx = idx;
|
|
46
|
+
const b0 = b - sMap[idx];
|
|
47
|
+
const b1 = b0 + sMap[idx + 1];
|
|
48
|
+
const text = srcTxt.slice(a1, b1);
|
|
49
|
+
if (bIdx === aIdx) {
|
|
50
|
+
return { text, range };
|
|
51
|
+
}
|
|
52
|
+
const ab = [a0, a1];
|
|
53
|
+
const map = sMap.slice(aIdx, bIdx + 2).map((v, i) => v - ab[i & 1]);
|
|
54
|
+
return { text, range, map };
|
|
55
|
+
}
|
|
56
|
+
exports.extractTextMapRangeOrigin = extractTextMapRangeOrigin;
|
|
57
|
+
function doesIntersect(textMap, rangeOrigin) {
|
|
58
|
+
const r = textMap.range;
|
|
59
|
+
return r[0] < rangeOrigin[1] && r[1] > rangeOrigin[0];
|
|
60
|
+
}
|
|
61
|
+
exports.doesIntersect = doesIntersect;
|
|
62
|
+
//# sourceMappingURL=TextMap.js.map
|
package/dist/util/resolveFile.js
CHANGED
|
@@ -42,13 +42,14 @@ const testNodeModules = /^node_modules\//;
|
|
|
42
42
|
function resolveFile(filename, relativeTo) {
|
|
43
43
|
filename = filename.replace(/^~/, os.homedir());
|
|
44
44
|
const steps = [
|
|
45
|
-
{ filename
|
|
45
|
+
{ filename, fn: tryUrl },
|
|
46
|
+
{ filename, fn: tryNodeResolve },
|
|
46
47
|
{ filename: path.resolve(relativeTo, filename), fn: tryResolveExists },
|
|
47
48
|
{ filename: path.resolve(filename), fn: tryResolveExists },
|
|
48
|
-
{ filename
|
|
49
|
-
{ filename
|
|
49
|
+
{ filename, fn: tryNodeResolveDefaultPaths },
|
|
50
|
+
{ filename, fn: tryResolveFrom },
|
|
50
51
|
{ filename: filename.replace(testNodeModules, ''), fn: tryResolveFrom },
|
|
51
|
-
{ filename
|
|
52
|
+
{ filename, fn: tryResolveGlobal },
|
|
52
53
|
];
|
|
53
54
|
for (const step of steps) {
|
|
54
55
|
const r = step.fn(step.filename, relativeTo);
|
|
@@ -58,6 +59,23 @@ function resolveFile(filename, relativeTo) {
|
|
|
58
59
|
return { filename: path.resolve(relativeTo, filename), relativeTo, found: false };
|
|
59
60
|
}
|
|
60
61
|
exports.resolveFile = resolveFile;
|
|
62
|
+
const isUrlRegExp = /^\w+:\/\//i;
|
|
63
|
+
/**
|
|
64
|
+
* Check to see if it is a URL.
|
|
65
|
+
* Note: URLs are absolute!
|
|
66
|
+
* @param filename - url string
|
|
67
|
+
* @returns ResolveFileResult
|
|
68
|
+
*/
|
|
69
|
+
function tryUrl(filename, relativeTo) {
|
|
70
|
+
if (isUrlRegExp.test(filename)) {
|
|
71
|
+
return { filename, relativeTo: undefined, found: true };
|
|
72
|
+
}
|
|
73
|
+
if (isUrlRegExp.test(relativeTo)) {
|
|
74
|
+
const url = new URL(filename, relativeTo);
|
|
75
|
+
return { filename: url.href, relativeTo, found: true };
|
|
76
|
+
}
|
|
77
|
+
return { filename, relativeTo: undefined, found: false };
|
|
78
|
+
}
|
|
61
79
|
function tryNodeResolveDefaultPaths(filename) {
|
|
62
80
|
try {
|
|
63
81
|
const r = require.resolve(filename);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cspell-lib",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0-alpha.1",
|
|
4
4
|
"description": "A library of useful functions used across various cspell tools.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://github.com/streetsidesoftware/cspell#readme",
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@cspell/cspell-bundled-dicts": "^6.
|
|
52
|
-
"@cspell/cspell-pipe": "^6.
|
|
53
|
-
"@cspell/cspell-types": "^6.
|
|
51
|
+
"@cspell/cspell-bundled-dicts": "^6.2.0-alpha.1",
|
|
52
|
+
"@cspell/cspell-pipe": "^6.2.0-alpha.1",
|
|
53
|
+
"@cspell/cspell-types": "^6.2.0-alpha.1",
|
|
54
54
|
"clear-module": "^4.1.2",
|
|
55
55
|
"comment-json": "^4.2.2",
|
|
56
56
|
"configstore": "^5.0.1",
|
|
57
57
|
"cosmiconfig": "^7.0.1",
|
|
58
|
-
"cspell-glob": "^6.
|
|
59
|
-
"cspell-io": "^6.
|
|
60
|
-
"cspell-trie-lib": "^6.
|
|
58
|
+
"cspell-glob": "^6.2.0-alpha.1",
|
|
59
|
+
"cspell-io": "^6.2.0-alpha.1",
|
|
60
|
+
"cspell-trie-lib": "^6.2.0-alpha.1",
|
|
61
61
|
"fast-equals": "^4.0.1",
|
|
62
62
|
"find-up": "^5.0.0",
|
|
63
63
|
"fs-extra": "^10.1.0",
|
|
@@ -82,15 +82,15 @@
|
|
|
82
82
|
"@cspell/dict-python": "^2.0.6",
|
|
83
83
|
"@types/configstore": "^5.0.1",
|
|
84
84
|
"@types/fs-extra": "^9.0.13",
|
|
85
|
-
"@types/jest": "^28.1.
|
|
86
|
-
"@types/node": "^
|
|
85
|
+
"@types/jest": "^28.1.3",
|
|
86
|
+
"@types/node": "^18.0.0",
|
|
87
87
|
"cspell-dict-nl-nl": "^1.1.2",
|
|
88
|
-
"jest": "^28.1.
|
|
88
|
+
"jest": "^28.1.2",
|
|
89
89
|
"lorem-ipsum": "^2.0.8",
|
|
90
90
|
"rimraf": "^3.0.2",
|
|
91
|
-
"rollup": "^2.75.
|
|
91
|
+
"rollup": "^2.75.7",
|
|
92
92
|
"rollup-plugin-dts": "^4.2.2",
|
|
93
93
|
"ts-jest": "^28.0.5"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "bb1862e9d5116b64451e625eb002f835e2873f9b"
|
|
96
96
|
}
|