cspell-lib 9.6.4 → 9.8.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.
Files changed (39) hide show
  1. package/dist/lib/Models/ValidationIssue.d.ts +8 -1
  2. package/dist/lib/Models/ValidationIssue.js +15 -1
  3. package/dist/lib/Models/ValidationResult.d.ts +24 -3
  4. package/dist/lib/Settings/CSpellSettingsServer.js +2 -2
  5. package/dist/lib/Settings/Controller/configLoader/configLoader.d.ts +2 -2
  6. package/dist/lib/Settings/Controller/configLoader/configLoader.js +27 -6
  7. package/dist/lib/Settings/Controller/configLoader/defaultConfigLoader.d.ts +0 -1
  8. package/dist/lib/Settings/DefaultSettings.d.ts +11 -0
  9. package/dist/lib/Settings/DefaultSettings.js +14 -3
  10. package/dist/lib/Settings/constants.js +1 -0
  11. package/dist/lib/Settings/sanitizeSettings.js +6 -0
  12. package/dist/lib/Transform/SourceMap.d.ts +115 -0
  13. package/dist/lib/Transform/SourceMap.js +469 -0
  14. package/dist/lib/Transform/SubstitutionTransformer.d.ts +32 -0
  15. package/dist/lib/Transform/SubstitutionTransformer.js +121 -0
  16. package/dist/lib/Transform/TextMap.d.ts +35 -0
  17. package/dist/lib/Transform/TextMap.js +86 -0
  18. package/dist/lib/{util → Transform}/TextRange.js +6 -7
  19. package/dist/lib/Transform/index.d.ts +9 -0
  20. package/dist/lib/Transform/index.js +5 -0
  21. package/dist/lib/{textValidation → Transform}/parsedText.d.ts +5 -6
  22. package/dist/lib/{textValidation → Transform}/parsedText.js +6 -34
  23. package/dist/lib/Transform/types.d.ts +5 -0
  24. package/dist/lib/Transform/types.js +2 -0
  25. package/dist/lib/spellCheckFile.d.ts +26 -1
  26. package/dist/lib/spellCheckFile.js +21 -8
  27. package/dist/lib/textValidation/docValidator.d.ts +5 -7
  28. package/dist/lib/textValidation/docValidator.js +14 -5
  29. package/dist/lib/textValidation/index.d.ts +1 -1
  30. package/dist/lib/textValidation/lineValidatorFactory.d.ts +5 -1
  31. package/dist/lib/textValidation/lineValidatorFactory.js +5 -3
  32. package/dist/lib/textValidation/settingsToValidateOptions.js +10 -1
  33. package/dist/lib/textValidation/textValidator.d.ts +1 -1
  34. package/dist/lib/textValidation/textValidator.js +1 -1
  35. package/dist/lib/util/fileReader.d.ts +1 -1
  36. package/package.json +26 -26
  37. package/dist/lib/util/TextMap.d.ts +0 -15
  38. package/dist/lib/util/TextMap.js +0 -54
  39. /package/dist/lib/{util → Transform}/TextRange.d.ts +0 -0
@@ -1,7 +1,14 @@
1
1
  import type { ExtendedSuggestion } from './Suggestion.js';
2
- import type { ValidationResult } from './ValidationResult.js';
2
+ import type { ValidationResult, ValidationResultRPC } from './ValidationResult.js';
3
3
  export interface ValidationIssue extends ValidationResult {
4
4
  suggestions?: string[] | undefined;
5
5
  suggestionsEx?: ExtendedSuggestion[] | undefined;
6
6
  }
7
+ /**
8
+ * The ValidationIssueRPC is used for RPC communication. It is a subset of ValidationIssue that can be serialized.
9
+ */
10
+ export interface ValidationIssueRPC extends ValidationResultRPC {
11
+ suggestionsEx?: ExtendedSuggestion[] | undefined;
12
+ }
13
+ export declare function toValidationIssueRPC(issue: ValidationIssue, index?: number): ValidationIssueRPC;
7
14
  //# sourceMappingURL=ValidationIssue.d.ts.map
@@ -1,2 +1,16 @@
1
- export {};
1
+ export function toValidationIssueRPC(issue) {
2
+ const { text, length, offset, message, issueType, hasPreferredSuggestions, hasSimpleSuggestions, isFlagged, isFound, suggestionsEx, } = issue;
3
+ return {
4
+ text,
5
+ offset,
6
+ length,
7
+ message,
8
+ issueType,
9
+ hasPreferredSuggestions,
10
+ hasSimpleSuggestions,
11
+ isFlagged,
12
+ isFound,
13
+ suggestionsEx,
14
+ };
15
+ }
2
16
  //# sourceMappingURL=ValidationIssue.js.map
@@ -1,7 +1,28 @@
1
- import type { Issue, TextOffset as TextOffsetRW } from '@cspell/cspell-types';
2
- export interface ValidationResult extends TextOffsetRW, Pick<Issue, 'message' | 'issueType' | 'hasPreferredSuggestions' | 'hasSimpleSuggestions'> {
3
- line: TextOffsetRW;
1
+ import type { Issue, TextOffset as TextOffset } from '@cspell/cspell-types';
2
+ export interface ValidationResult extends Omit<TextOffset, 'length'>, Pick<Issue, 'message' | 'issueType' | 'hasPreferredSuggestions' | 'hasSimpleSuggestions'> {
3
+ length?: number | undefined;
4
+ line: TextOffset;
4
5
  isFlagged?: boolean | undefined;
5
6
  isFound?: boolean | undefined;
6
7
  }
8
+ /**
9
+ * The ValidationResultRPC is used for RPC communication. It is a subset of ValidationResult that can be serialized.
10
+ *
11
+ * The URI, document, row, and column information are not included in the RPC version of ValidationResult
12
+ * because they can be calculated from the offset and the document text.
13
+ */
14
+ export interface ValidationResultRPC extends Pick<ValidationResult, 'text' | 'length' | 'offset' | 'message' | 'issueType' | 'hasPreferredSuggestions' | 'hasSimpleSuggestions' | 'isFlagged' | 'isFound'> {
15
+ /**
16
+ * The line information is not included in the RPC version of ValidationResult because it can be calculated from the offset and the document text.
17
+ */
18
+ line?: undefined;
19
+ /**
20
+ * The context information is not included in the RPC version of ValidationResult because it can be calculated from the offset and the document text.
21
+ */
22
+ context?: undefined;
23
+ uri?: undefined;
24
+ doc?: undefined;
25
+ row?: undefined;
26
+ col?: undefined;
27
+ }
7
28
  //# sourceMappingURL=ValidationResult.d.ts.map
@@ -4,8 +4,7 @@ import { autoResolveWeak, AutoResolveWeakCache } from '../util/AutoResolve.js';
4
4
  import { toFileUrl } from '../util/url.js';
5
5
  import * as util from '../util/util.js';
6
6
  import { configSettingsFileVersion0_1, ENV_CSPELL_GLOB_ROOT } from './constants.js';
7
- import { calcDictionaryDefsToLoad, mapDictDefsToInternal } from './internal/index.js';
8
- import { cleanCSpellSettingsInternal as csi, isCSpellSettingsInternal } from './internal/index.js';
7
+ import { calcDictionaryDefsToLoad, cleanCSpellSettingsInternal as csi, isCSpellSettingsInternal, mapDictDefsToInternal, } from './internal/index.js';
9
8
  import { mergeList, mergeListUnique } from './mergeList.js';
10
9
  import { resolvePatterns } from './patterns.js';
11
10
  import { CwdUrlResolver } from './resolveCwd.js';
@@ -129,6 +128,7 @@ function _merge(left, right) {
129
128
  features: mergeObjects(_left.features, _right.features),
130
129
  source: mergeSources(_left, _right),
131
130
  plugins: mergeList(_left.plugins, _right.plugins),
131
+ vfs: mergeObjects(_left.vfs, _right.vfs),
132
132
  __imports: mergeImportRefs(_left, _right),
133
133
  });
134
134
  return settings;
@@ -7,10 +7,10 @@ import { AutoResolveCache } from '../../../util/AutoResolve.js';
7
7
  import { FileResolver } from '../../../util/resolveFile.js';
8
8
  import type { LoaderResult } from '../pnpLoader.js';
9
9
  import { ConfigSearch } from './configSearch.js';
10
- import type { StopSearchAt } from './defaultConfigLoader.js';
11
10
  import { normalizeCacheSettings } from './normalizeRawSettings.js';
12
11
  import type { PnPSettingsOptional } from './PnPSettings.js';
13
12
  import type { CSpellSettingsI, CSpellSettingsWST } from './types.js';
13
+ export type StopSearchAt = URL | string | (URL | string)[] | undefined;
14
14
  export declare const sectionCSpell = "cSpell";
15
15
  export declare const defaultFileName = "cspell.json";
16
16
  interface ImportedConfigEntry {
@@ -103,7 +103,6 @@ export declare class ConfigLoader implements IConfigLoader {
103
103
  readonly templateVariables: Record<string, string>;
104
104
  onReady: Promise<void>;
105
105
  readonly fileResolver: FileResolver;
106
- private _isTrusted;
107
106
  /**
108
107
  * Use `createConfigLoader`
109
108
  * @param virtualFs - virtual file system to use.
@@ -155,6 +154,7 @@ export declare class ConfigLoader implements IConfigLoader {
155
154
  * @param pathToSettingsFile - path to the source file of the configuration settings.
156
155
  */
157
156
  protected mergeImports(cfgFile: CSpellConfigFile, importedSettings: CSpellUserSettings[]): Promise<CSpellSettingsI>;
157
+ registerVirtualFiles(settings: CSpellSettings): Promise<void>;
158
158
  createCSpellConfigFile(filename: URL | string, settings: CSpellUserSettings): CSpellConfigFile;
159
159
  toCSpellConfigFile(cfg: ICSpellConfigFile): CSpellConfigFile;
160
160
  dispose(): void;
@@ -1,9 +1,8 @@
1
1
  import assert from 'node:assert';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { CSpellConfigFile, CSpellConfigFileWithErrors } from 'cspell-config-lib';
5
- import { createReaderWriter } from 'cspell-config-lib';
6
- import { isUrlLike, toFileURL } from 'cspell-io';
4
+ import { createReaderWriter, CSpellConfigFile, CSpellConfigFileWithErrors } from 'cspell-config-lib';
5
+ import { CSPELL_VFS_PROTOCOL, isUrlLike, toFileURL } from 'cspell-io';
7
6
  import { URI, Utils as UriUtils } from 'vscode-uri';
8
7
  import { onClearCache } from '../../../events/index.js';
9
8
  import { getVirtualFS } from '../../../fileSystem.js';
@@ -43,7 +42,9 @@ export class ConfigLoader {
43
42
  templateVariables;
44
43
  onReady;
45
44
  fileResolver;
46
- _isTrusted = true;
45
+ #isTrusted = true;
46
+ /** the href of known dictionary files that have been added to the cspell-vfs:// */
47
+ #knownVirtualFiles = new Set();
47
48
  /**
48
49
  * Use `createConfigLoader`
49
50
  * @param virtualFs - virtual file system to use.
@@ -154,6 +155,7 @@ export class ConfigLoader {
154
155
  this.cachedMergedConfig = new WeakMap();
155
156
  this.cachedCSpellConfigFileInMemory = new WeakMap();
156
157
  this.prefetchGlobalSettingsAsync();
158
+ this.#knownVirtualFiles.clear();
157
159
  }
158
160
  /**
159
161
  * Resolve and merge the settings from the imports.
@@ -292,6 +294,7 @@ export class ConfigLoader {
292
294
  });
293
295
  const importSettings = await Promise.all(pendingImports);
294
296
  const cfg = await this.mergeImports(cfgFile, importSettings);
297
+ await this.registerVirtualFiles(cfg);
295
298
  return cfg;
296
299
  }
297
300
  /**
@@ -340,6 +343,24 @@ export class ConfigLoader {
340
343
  }
341
344
  return finalizeSettings;
342
345
  }
346
+ registerVirtualFiles(settings) {
347
+ if (!settings.vfs)
348
+ return Promise.resolve();
349
+ const entries = Object.entries(settings.vfs);
350
+ const waitFor = [];
351
+ for (const [href, entry] of entries) {
352
+ if (this.#knownVirtualFiles.has(href))
353
+ continue;
354
+ assert(href.startsWith(CSPELL_VFS_PROTOCOL + '///'), `Invalid virtual file URL: ${href}`);
355
+ const url = toFileURL(href);
356
+ let content = entry.data;
357
+ if (typeof content === 'string' && entry.encoding === 'base64') {
358
+ content = Buffer.from(content, 'base64');
359
+ }
360
+ waitFor.push(this.fs.writeFile({ url, content }).then(() => this.#knownVirtualFiles.add(href)));
361
+ }
362
+ return Promise.all(waitFor).then(() => undefined);
363
+ }
343
364
  createCSpellConfigFile(filename, settings) {
344
365
  const map = autoResolveWeak(this.cachedCSpellConfigFileInMemory, settings, () => new Map());
345
366
  return autoResolve(map, filename, () => this.cspellConfigFileReaderWriter.toCSpellConfigFile({ url: toFileURL(filename), settings }));
@@ -381,10 +402,10 @@ export class ConfigLoader {
381
402
  };
382
403
  }
383
404
  get isTrusted() {
384
- return this._isTrusted;
405
+ return this.#isTrusted;
385
406
  }
386
407
  setIsTrusted(isTrusted) {
387
- this._isTrusted = isTrusted;
408
+ this.#isTrusted = isTrusted;
388
409
  this.clearCachedSettingsFiles();
389
410
  this.configSearch = new ConfigSearch(searchPlaces, isTrusted ? trustedSearch : unTrustedSearch, this.fs);
390
411
  this.cspellConfigFileReaderWriter.setUntrustedExtensions(isTrusted ? [] : defaultJsExtensions);
@@ -4,7 +4,6 @@ import type { IConfigLoader, SearchForConfigOptions } from './configLoader.js';
4
4
  import type { PnPSettingsOptional } from './PnPSettings.js';
5
5
  import type { CSpellSettingsI, CSpellSettingsWST } from './types.js';
6
6
  export type { CSpellConfigFile, ICSpellConfigFile } from 'cspell-config-lib';
7
- export type StopSearchAt = URL | string | (URL | string)[] | undefined;
8
7
  /**
9
8
  *
10
9
  * @param searchFrom the directory / file to start searching from.
@@ -1,4 +1,15 @@
1
1
  import type { CSpellSettingsInternal } from './internal/index.js';
2
+ export declare const STATIC_DEFAULTS: {
3
+ readonly id: "static_defaults";
4
+ readonly language: "en";
5
+ readonly name: "Static Defaults";
6
+ readonly enabled: true;
7
+ readonly maxNumberOfProblems: 100;
8
+ readonly numSuggestions: 10;
9
+ readonly suggestionsTimeout: 500;
10
+ readonly suggestionNumChanges: 3;
11
+ readonly allowCompoundWords: false;
12
+ };
2
13
  export declare const _defaultSettingsBasis: Readonly<CSpellSettingsInternal>;
3
14
  export declare const _defaultSettings: Readonly<CSpellSettingsInternal>;
4
15
  declare class DefaultSettingsLoader {
@@ -69,20 +69,31 @@ const definedDefaultRegExpExcludeList = [
69
69
  ];
70
70
  // This bit of copying is done to have the compiler ensure that the defaults exist.
71
71
  const defaultRegExpExcludeList = definedDefaultRegExpExcludeList;
72
- export const _defaultSettingsBasis = Object.freeze(createCSpellSettingsInternal({
72
+ export const STATIC_DEFAULTS = {
73
73
  id: 'static_defaults',
74
74
  language: 'en',
75
75
  name: 'Static Defaults',
76
76
  enabled: true,
77
- enabledLanguageIds: [],
78
77
  maxNumberOfProblems: 100,
79
78
  numSuggestions: 10,
80
79
  suggestionsTimeout: 500,
81
80
  suggestionNumChanges: 3,
81
+ allowCompoundWords: false,
82
+ };
83
+ export const _defaultSettingsBasis = Object.freeze(createCSpellSettingsInternal({
84
+ id: STATIC_DEFAULTS.id,
85
+ language: STATIC_DEFAULTS.language,
86
+ name: STATIC_DEFAULTS.name,
87
+ enabled: STATIC_DEFAULTS.enabled,
88
+ enabledLanguageIds: [],
89
+ maxNumberOfProblems: STATIC_DEFAULTS.maxNumberOfProblems,
90
+ numSuggestions: STATIC_DEFAULTS.numSuggestions,
91
+ suggestionsTimeout: STATIC_DEFAULTS.suggestionsTimeout,
92
+ suggestionNumChanges: STATIC_DEFAULTS.suggestionNumChanges,
82
93
  words: [],
83
94
  userWords: [],
84
95
  ignorePaths: [],
85
- allowCompoundWords: false,
96
+ allowCompoundWords: STATIC_DEFAULTS.allowCompoundWords,
86
97
  patterns: defaultRegExpPatterns,
87
98
  ignoreRegExpList: [],
88
99
  languageSettings: [],
@@ -3,4 +3,5 @@ export const configSettingsFileVersion0_2 = '0.2';
3
3
  export const currentSettingsFileVersion = configSettingsFileVersion0_2;
4
4
  export const ENV_CSPELL_GLOB_ROOT = 'CSPELL_GLOB_ROOT';
5
5
  export const defaultConfigFileModuleRef = '@cspell/cspell-bundled-dicts/cspell-default.json';
6
+ // export const defaultConfigFileModuleRef = '@cspell/cspell-bundled-dicts/cspell-bundled.js';
6
7
  //# sourceMappingURL=constants.js.map
@@ -61,6 +61,8 @@ const handlers = {
61
61
  reporters: skip,
62
62
  showStatus: copy1,
63
63
  spellCheckDelayMs: copy1,
64
+ substitutionDefinitions: copy1,
65
+ substitutions: copy1,
64
66
  suggestionNumChanges: copy1,
65
67
  suggestionsTimeout: copy1,
66
68
  suggestWords: copy1,
@@ -177,6 +179,8 @@ const LanguageSettingsHandlers = {
177
179
  name: skip,
178
180
  noSuggestDictionaries: copy1,
179
181
  patterns: copyPatternsField,
182
+ substitutionDefinitions: copy1,
183
+ substitutions: copy1,
180
184
  suggestWords: copy1,
181
185
  unknownWords: copy1,
182
186
  words: copy1,
@@ -235,6 +239,8 @@ const OverridesHandlers = {
235
239
  numSuggestions: copy1,
236
240
  patterns: copyPatternsField,
237
241
  pnpFiles: skip,
242
+ substitutionDefinitions: copy1,
243
+ substitutions: copy1,
238
244
  suggestionNumChanges: copy1,
239
245
  suggestionsTimeout: copy1,
240
246
  suggestWords: copy1,
@@ -0,0 +1,115 @@
1
+ import type { Range, SourceMap } from '@cspell/cspell-types';
2
+ export interface SourceMapCursor {
3
+ /**
4
+ * The source map being traversed.
5
+ */
6
+ readonly sourceMap: SourceMap;
7
+ /**
8
+ * The current index in the source map.
9
+ */
10
+ readonly idx: number;
11
+ /**
12
+ * The base offset in the source text.
13
+ */
14
+ readonly begin0: number;
15
+ /**
16
+ * The base offset in the transformed text.
17
+ */
18
+ readonly begin1: number;
19
+ reset(): void;
20
+ mapOffsetToDest(offsetInSrc: number): number;
21
+ mapOffsetToSrc(offsetInDst: number): number;
22
+ mapRangeToSrc(rangeInDst: Range): Range;
23
+ }
24
+ declare class SourceMapCursorImpl implements SourceMapCursor {
25
+ sourceMap: SourceMap;
26
+ idx: number;
27
+ begin0: number;
28
+ begin1: number;
29
+ /**
30
+ * The delta in the source
31
+ */
32
+ d0: number;
33
+ /**
34
+ * The delta in the transformed text.
35
+ */
36
+ d1: number;
37
+ /**
38
+ * Indicates whether the current segment is linear (1:1) or non-linear.
39
+ * A linear segment has equal deltas in the source and transformed text,
40
+ * while a non-linear segment has different deltas.
41
+ * It is possible that a non-linear segment has the same deltas,
42
+ * but it is not possible for a linear segment to have different deltas.
43
+ */
44
+ linear: boolean;
45
+ /**
46
+ * indicates that the cursor has reached the end of the source map.
47
+ */
48
+ done: boolean;
49
+ constructor(sourceMap: SourceMap);
50
+ next(): boolean;
51
+ mapOffsetToDest(offsetInSrc: number): number;
52
+ mapOffsetToSrc(offsetInDst: number): number;
53
+ mapRangeToSrc(rangeInDst: Range): Range;
54
+ reset(): void;
55
+ }
56
+ /**
57
+ * Create a cursor for traversing a source map.
58
+ * @param sourceMap - The source map to create the cursor for. The map must be pairs of values (even, odd).
59
+ * @returns A cursor initialized to the start of the source map. The cursor can be used to traverse the source map and
60
+ * calculate offsets in the transformed text based on offsets in the source text.
61
+ */
62
+ export declare function createSourceMapCursor(sourceMap: SourceMap): SourceMapCursorImpl;
63
+ export declare function createSourceMapCursor(sourceMap: SourceMap | undefined): SourceMapCursorImpl | undefined;
64
+ /**
65
+ * Calculated the transformed offset in the destination text based on the source map and the offset in the source text.
66
+ * @param cursor - The cursor to use for the mapping. If undefined or empty, the input offset is returned, assuming it is a 1:1 mapping.
67
+ * @param offsetInSrc - the offset in the source text to map to the transformed text. The offset is relative to the start of the text range.
68
+ * @returns The offset in the transformed text corresponding to the input offset in the source text. The offset is relative to the start of the text range.
69
+ */
70
+ export declare function calcOffsetInDst(cursor: SourceMapCursor | undefined, offsetInSrc: number): number;
71
+ /**
72
+ * Calculated the transformed offset in the source text based on the source map and the offset in the transformed text.
73
+ * @param cursor - The cursor to use for the mapping. If undefined or empty, the input offset is returned, assuming it is a 1:1 mapping.
74
+ * @param offsetInDst - the offset in the transformed text to map to the source text. The offset is relative to the start of the text range.
75
+ * @returns The offset in the source text corresponding to the input offset in the transformed text. The offset is relative to the start of the text range.
76
+ */
77
+ export declare function calcOffsetInSrc(cursor: SourceMapCursor | undefined, offsetInDst: number): number;
78
+ /**
79
+ * Map offset pairs to a source map. The input map is expected to be pairs of absolute offsets in the source and transformed text.
80
+ * The output map is pairs of lengths.
81
+ * @param map - The input map to convert. The map must be pairs of values (even, odd) where the even values are offsets in the source
82
+ * text and the odd values are offsets in the transformed text. The offsets are absolute offsets from the start of the text range.
83
+ * @returns a SourceMap
84
+ */
85
+ export declare function mapOffsetPairsToSourceMap(map: number[] | undefined): SourceMap | undefined;
86
+ /**
87
+ * Merge two source maps into a single source map. The first map transforms from the
88
+ * original text to an intermediate text, and the second map transforms from the intermediate
89
+ * text to the final text. The resulting map represents the transformation directly from the
90
+ * original text to the final text.
91
+ *
92
+ * Concept:
93
+ * [markdown codeblock] -> <first map> -> [JavaScript code] -> <second map> -> [string value]
94
+ *
95
+ * Some kinds of transforms:
96
+ * - markdown code block extraction
97
+ * - unicode normalization
98
+ * - html entity substitution
99
+ * - url decoding
100
+ * - etc.
101
+ *
102
+ * The result of each transform is a {@link SourceMap}. When multiple transforms are applied,
103
+ * the source maps can be merged to create a single map that represents the cumulative effect
104
+ * of all transforms. This is useful for accurately mapping positions in the final transformed
105
+ * text back to their corresponding positions in the original text, which is essential for
106
+ * reporting spelling issues in the correct context.
107
+ *
108
+ * @param first - The first transformation map from the original text to the intermediate.
109
+ * @param second - The second transformation map from the intermediate, to the final text.
110
+ */
111
+ export declare function mergeSourceMaps(first: SourceMap | undefined, second: SourceMap | undefined): SourceMap | undefined;
112
+ export declare function sliceSourceMapToSourceRange(map: SourceMap | undefined, range: Range): SourceMap | undefined;
113
+ export declare function reverseSourceMap(map: SourceMap | undefined): SourceMap | undefined;
114
+ export {};
115
+ //# sourceMappingURL=SourceMap.d.ts.map