cspell-lib 9.4.0 → 9.6.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.
Files changed (115) hide show
  1. package/README.md +6 -6
  2. package/dist/cspell-rpc/api.d.ts +28 -0
  3. package/dist/cspell-rpc/api.js +6 -0
  4. package/dist/cspell-rpc/client.d.ts +17 -0
  5. package/dist/cspell-rpc/client.js +20 -0
  6. package/dist/cspell-rpc/index.d.ts +7 -0
  7. package/dist/cspell-rpc/index.js +4 -0
  8. package/dist/cspell-rpc/server.d.ts +16 -0
  9. package/dist/cspell-rpc/server.js +37 -0
  10. package/dist/cspell-rpc/spellCheckFile.d.ts +2 -0
  11. package/dist/cspell-rpc/spellCheckFile.js +2 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +2 -0
  14. package/dist/lib/Settings/CSpellSettingsServer.d.ts +4 -2
  15. package/dist/lib/Settings/CSpellSettingsServer.js +10 -2
  16. package/dist/lib/Settings/Controller/ImportError.js +3 -0
  17. package/dist/lib/Settings/Controller/configLoader/configLoader.d.ts +6 -4
  18. package/dist/lib/Settings/Controller/configLoader/configLoader.js +12 -6
  19. package/dist/lib/Settings/Controller/configLoader/configLocations.js +1 -0
  20. package/dist/lib/Settings/Controller/configLoader/defaultSettings.js +1 -1
  21. package/dist/lib/Settings/Controller/configLoader/normalizeRawSettings.js +1 -1
  22. package/dist/lib/Settings/Controller/configLoader/types.d.ts +1 -1
  23. package/dist/lib/Settings/DefaultSettings.d.ts +1 -1
  24. package/dist/lib/Settings/DefaultSettings.js +1 -1
  25. package/dist/lib/Settings/InDocSettings.d.ts +0 -3
  26. package/dist/lib/Settings/InDocSettings.js +2 -3
  27. package/dist/lib/Settings/LanguageSettings.js +3 -3
  28. package/dist/lib/Settings/RegExpPatterns.js +2 -2
  29. package/dist/lib/Settings/TextDocumentSettings.d.ts +1 -1
  30. package/dist/lib/Settings/cfgStore.d.ts +1 -1
  31. package/dist/lib/Settings/index.d.ts +3 -1
  32. package/dist/lib/Settings/index.js +2 -1
  33. package/dist/lib/Settings/internal/CSpellSettingsInternalDef.d.ts +18 -0
  34. package/dist/lib/{Models → Settings/internal}/CSpellSettingsInternalDef.js +1 -10
  35. package/dist/lib/Settings/{DictionarySettings.d.ts → internal/DictionarySettings.d.ts} +3 -2
  36. package/dist/lib/Settings/{DictionarySettings.js → internal/DictionarySettings.js} +20 -10
  37. package/dist/lib/{Models/CSpellSettingsInternalDef.d.ts → Settings/internal/InternalDictionaryDef.d.ts} +2 -17
  38. package/dist/lib/Settings/internal/InternalDictionaryDef.js +10 -0
  39. package/dist/lib/Settings/internal/index.d.ts +6 -0
  40. package/dist/lib/Settings/internal/index.js +4 -0
  41. package/dist/lib/Settings/link.js +1 -1
  42. package/dist/lib/Settings/mergeCache.d.ts +1 -1
  43. package/dist/lib/Settings/mergeList.d.ts +1 -1
  44. package/dist/lib/Settings/sanitizeSettings.d.ts +11 -0
  45. package/dist/lib/Settings/sanitizeSettings.js +254 -0
  46. package/dist/lib/Settings/util/settingsToJson.d.ts +28 -0
  47. package/dist/lib/Settings/util/settingsToJson.js +125 -0
  48. package/dist/lib/SpellingDictionary/Dictionaries.d.ts +1 -1
  49. package/dist/lib/SpellingDictionary/Dictionaries.js +1 -1
  50. package/dist/lib/SpellingDictionary/DictionaryController/DictionaryLoader.d.ts +1 -1
  51. package/dist/lib/SpellingDictionary/DictionaryController/DictionaryLoader.js +115 -28
  52. package/dist/lib/SpellingDictionary/DictionaryLoader.d.ts +1 -1
  53. package/dist/lib/index.d.ts +2 -2
  54. package/dist/lib/index.js +2 -2
  55. package/dist/lib/perf/index.d.ts +1 -0
  56. package/dist/lib/perf/index.js +1 -0
  57. package/dist/lib/spellCheckFile.d.ts +11 -1
  58. package/dist/lib/spellCheckFile.js +24 -4
  59. package/dist/lib/suggestions.d.ts +1 -1
  60. package/dist/lib/suggestions.js +3 -3
  61. package/dist/lib/textValidation/cleanValidationIssue.d.ts +3 -0
  62. package/dist/lib/textValidation/cleanValidationIssue.js +21 -0
  63. package/dist/lib/textValidation/determineTextDocumentSettings.d.ts +1 -1
  64. package/dist/lib/textValidation/docValidator.d.ts +6 -3
  65. package/dist/lib/textValidation/docValidator.js +29 -6
  66. package/dist/lib/textValidation/isRandomString.d.ts +1 -1
  67. package/dist/lib/textValidation/lineValidatorFactory.js +13 -5
  68. package/dist/lib/textValidation/settingsToValidateOptions.d.ts +1 -1
  69. package/dist/lib/textValidation/traceWord.d.ts +1 -0
  70. package/dist/lib/textValidation/traceWord.js +1 -0
  71. package/dist/lib/trace.d.ts +2 -1
  72. package/dist/lib/trace.js +2 -2
  73. package/dist/lib/util/clone.d.ts +35 -0
  74. package/dist/lib/util/clone.js +76 -0
  75. package/dist/lib/util/errors.js +1 -1
  76. package/dist/lib/util/memoizeLastCall.d.ts +13 -0
  77. package/dist/lib/util/{memorizeLastCall.js → memoizeLastCall.js} +2 -2
  78. package/dist/lib/util/memoizeWeak.d.ts +6 -0
  79. package/dist/lib/util/{memorizerWeak.js → memoizeWeak.js} +2 -2
  80. package/dist/lib/util/text.js +6 -4
  81. package/dist/lib/util/textRegex.d.ts +2 -2
  82. package/dist/lib/util/textRegex.js +2 -2
  83. package/dist/rpc/Future.d.ts +18 -0
  84. package/dist/rpc/Future.js +49 -0
  85. package/dist/rpc/MessagePortEvents.d.ts +56 -0
  86. package/dist/rpc/MessagePortEvents.js +94 -0
  87. package/dist/rpc/assert.d.ts +14 -0
  88. package/dist/rpc/assert.js +21 -0
  89. package/dist/rpc/client.d.ts +186 -0
  90. package/dist/rpc/client.js +364 -0
  91. package/dist/rpc/errors.d.ts +24 -0
  92. package/dist/rpc/errors.js +47 -0
  93. package/dist/rpc/index.d.ts +11 -0
  94. package/dist/rpc/index.js +6 -0
  95. package/dist/rpc/messagePort.d.ts +34 -0
  96. package/dist/rpc/messagePort.js +2 -0
  97. package/dist/rpc/models.d.ts +134 -0
  98. package/dist/rpc/models.js +2 -0
  99. package/dist/rpc/modelsHelpers.d.ts +56 -0
  100. package/dist/rpc/modelsHelpers.js +117 -0
  101. package/dist/rpc/notify.d.ts +79 -0
  102. package/dist/rpc/notify.js +135 -0
  103. package/dist/rpc/protocol.d.ts +21 -0
  104. package/dist/rpc/protocol.js +17 -0
  105. package/dist/rpc/server.d.ts +39 -0
  106. package/dist/rpc/server.js +146 -0
  107. package/dist/rpc/types.d.ts +9 -0
  108. package/dist/rpc/types.js +2 -0
  109. package/dist/rpc.d.ts +2 -0
  110. package/dist/rpc.js +2 -0
  111. package/package.json +41 -26
  112. package/dist/lib/perf/perf.d.ts +0 -20
  113. package/dist/lib/perf/perf.js +0 -32
  114. package/dist/lib/util/memorizeLastCall.d.ts +0 -13
  115. package/dist/lib/util/memorizerWeak.d.ts +0 -6
@@ -1,8 +1,61 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
1
53
  import { opConcatMap, opFilter, opMap, pipe } from '@cspell/cspell-pipe/sync';
2
54
  import { StrongWeakMap } from '@cspell/strong-weak-map';
3
55
  import { createFailedToLoadDictionary, createInlineSpellingDictionary, createSpellingDictionary, createSpellingDictionaryFromTrieFile, } from 'cspell-dictionary';
4
56
  import { compareStats, toFileURL, urlBasename } from 'cspell-io';
5
- import { isDictionaryDefinitionInlineInternal, isDictionaryFileDefinitionInternal, } from '../../Models/CSpellSettingsInternalDef.js';
57
+ import { measurePerf } from '../../perf/index.js';
58
+ import { isDictionaryDefinitionInlineInternal, isDictionaryFileDefinitionInternal } from '../../Settings/index.js';
6
59
  import { AutoResolveWeakCache, AutoResolveWeakWeakCache } from '../../util/AutoResolve.js';
7
60
  import { toError } from '../../util/errors.js';
8
61
  import { SimpleCache } from '../../util/simpleCache.js';
@@ -42,7 +95,7 @@ export class DictionaryLoader {
42
95
  if (entry) {
43
96
  return entry.pending.then(([dictionary]) => dictionary);
44
97
  }
45
- const loadedEntry = this.loadEntry(def.path, def);
98
+ const loadedEntry = this.loadEntry(def.btrie || def.path, def);
46
99
  this.setCacheEntry(key, loadedEntry, def);
47
100
  this.keepAliveCache.set(def, loadedEntry);
48
101
  return loadedEntry.pending.then(([dictionary]) => dictionary);
@@ -98,8 +151,8 @@ export class DictionaryLoader {
98
151
  loadEntry(fileOrUri, options, now = Date.now()) {
99
152
  const url = toFileURL(fileOrUri);
100
153
  options = this.normalizeOptions(url, options);
101
- const pDictionary = load(this.reader, toFileURL(fileOrUri), options).catch((e) => createFailedToLoadDictionary(options.name, fileOrUri, new SpellingDictionaryLoadError(url.href, options, e, 'failed to load'), options));
102
- const pStat = this.getStat(fileOrUri);
154
+ const pDictionary = load(this.reader, url, options).catch((e) => createFailedToLoadDictionary(options.name, fileOrUri, new SpellingDictionaryLoadError(url.href, options, e, 'failed to load'), options));
155
+ const pStat = this.getStat(url);
103
156
  const pending = Promise.all([pDictionary, pStat]);
104
157
  const sig = now + Math.random();
105
158
  const entry = {
@@ -153,12 +206,19 @@ export class DictionaryLoader {
153
206
  }
154
207
  }
155
208
  function toReader(fs) {
156
- async function readFile(url) {
157
- return (await fs.readFile(url)).getText();
209
+ function readResource(url) {
210
+ return fs.readFile(url);
211
+ }
212
+ async function readText(url) {
213
+ return (await readResource(url)).getText();
214
+ }
215
+ async function read(url) {
216
+ return (await readResource(url)).getBytes();
158
217
  }
159
218
  return {
160
- read: readFile,
161
- readLines: async (filename) => toLines(await readFile(filename)),
219
+ read,
220
+ readText,
221
+ readLines: async (filename) => toLines(await readText(filename)),
162
222
  };
163
223
  }
164
224
  const importantOptionKeys = ['name', 'noSuggest', 'useCompounds', 'type'];
@@ -170,45 +230,72 @@ function determineType(uri, opts) {
170
230
  const t = (opts.type && opts.type in loaders && opts.type) || 'S';
171
231
  const defLoaderType = t;
172
232
  const defType = uri.pathname.endsWith('.trie.gz') ? 'T' : defLoaderType;
173
- const regTrieTest = /\.trie\b/i;
233
+ const regTrieTest = /\.b?trie\b/i;
174
234
  return regTrieTest.test(uri.pathname) ? 'T' : defType;
175
235
  }
176
- function load(reader, uri, options) {
236
+ async function load(reader, uri, options) {
177
237
  const type = determineType(uri, options);
178
238
  const loader = loaders[type] || loaders.default;
179
239
  return loader(reader, uri, options);
180
240
  }
181
241
  async function legacyWordList(reader, filename, options) {
182
- const lines = await reader.readLines(filename);
183
- return _legacyWordListSync(lines, filename, options);
184
- }
185
- function _legacyWordListSync(lines, filename, options) {
186
- const words = pipe(lines,
187
- // Remove comments
188
- opMap((line) => line.replaceAll(/#.*/g, '')),
189
- // Split on everything else
190
- opConcatMap((line) => line.split(/[^\w\p{L}\p{M}'’]+/gu)), opFilter((word) => !!word));
191
- return createSpellingDictionary(words, options.name, filename.toString(), options);
242
+ const env_1 = { stack: [], error: void 0, hasError: false };
243
+ try {
244
+ const lines = await reader.readLines(filename);
245
+ const _ = __addDisposableResource(env_1, measurePerf('legacyWords'), false);
246
+ const words = pipe(lines,
247
+ // Remove comments
248
+ opMap((line) => line.replaceAll(/#.*/g, '')),
249
+ // Split on everything else
250
+ opConcatMap((line) => line.split(/[^\w\p{L}\p{M}'’]+/gu)), opFilter((word) => !!word));
251
+ return createSpellingDictionary(words, options.name, filename.toString(), options, true);
252
+ }
253
+ catch (e_1) {
254
+ env_1.error = e_1;
255
+ env_1.hasError = true;
256
+ }
257
+ finally {
258
+ __disposeResources(env_1);
259
+ }
192
260
  }
193
261
  async function wordsPerLineWordList(reader, filename, options) {
194
262
  const lines = await reader.readLines(filename);
195
- return _wordsPerLineWordList(lines, filename.toString(), options);
196
- }
197
- function _wordsPerLineWordList(lines, filename, options) {
198
263
  const words = pipe(lines,
199
264
  // Remove comments
200
265
  opMap((line) => line.replaceAll(/#.*/g, '')),
201
266
  // Split on everything else
202
267
  opConcatMap((line) => line.split(/\s+/gu)), opFilter((word) => !!word));
203
- return createSpellingDictionary(words, options.name, filename, options);
268
+ return createSpellingDictionary(words, options.name, filename.href, options, true);
204
269
  }
205
270
  async function loadSimpleWordList(reader, filename, options) {
206
- const lines = await reader.readLines(filename);
207
- return createSpellingDictionary(lines, options.name, filename.href, options);
271
+ const env_2 = { stack: [], error: void 0, hasError: false };
272
+ try {
273
+ const lines = await reader.readLines(filename);
274
+ const _ = __addDisposableResource(env_2, measurePerf('loadSimpleWordList'), false);
275
+ return createSpellingDictionary(lines, options.name, filename.href, options);
276
+ }
277
+ catch (e_2) {
278
+ env_2.error = e_2;
279
+ env_2.hasError = true;
280
+ }
281
+ finally {
282
+ __disposeResources(env_2);
283
+ }
208
284
  }
209
285
  async function loadTrie(reader, filename, options) {
210
- const content = await reader.read(filename);
211
- return createSpellingDictionaryFromTrieFile(content, options.name, filename.href, options);
286
+ const env_3 = { stack: [], error: void 0, hasError: false };
287
+ try {
288
+ const content = await reader.read(filename);
289
+ const _ = __addDisposableResource(env_3, measurePerf('loadTrie'), false);
290
+ return createSpellingDictionaryFromTrieFile(content, options.name, filename.href, options);
291
+ }
292
+ catch (e_3) {
293
+ env_3.error = e_3;
294
+ env_3.hasError = true;
295
+ }
296
+ finally {
297
+ __disposeResources(env_3);
298
+ }
212
299
  }
213
300
  function toLines(content) {
214
301
  return content.split(/\n|\r\n|\r/);
@@ -1,6 +1,6 @@
1
1
  import type { SpellingDictionary } from 'cspell-dictionary';
2
2
  import type { VFileSystem } from '../fileSystem.js';
3
- import type { DictionaryDefinitionInternal } from '../Models/CSpellSettingsInternalDef.js';
3
+ import type { DictionaryDefinitionInternal } from '../Settings/index.js';
4
4
  import { DictionaryLoader } from './DictionaryController/index.js';
5
5
  export type { LoadOptions } from './DictionaryController/index.js';
6
6
  export declare function getDictionaryLoader(vfs?: VFileSystem): DictionaryLoader;
@@ -13,11 +13,11 @@ export { createTextDocument, updateTextDocument } from './Models/TextDocument.js
13
13
  export type { PerfTimer } from './perf/index.js';
14
14
  export { createPerfTimer } from './perf/index.js';
15
15
  export type { ConfigurationDependencies, CSpellConfigFile, ICSpellConfigFile, ImportFileRefWithError, } from './Settings/index.js';
16
- export { calcOverrideSettings, checkFilenameMatchesGlob, createConfigLoader, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getGlobalSettings, getGlobalSettingsAsync, getSources, ImportError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readConfigFile, readRawSettings, readSettings, readSettingsFiles, resolveConfigFileImports, searchForConfig, sectionCSpell, } from './Settings/index.js';
16
+ export { calcOverrideSettings, checkFilenameMatchesGlob, createConfigLoader, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getGlobalSettings, getGlobalSettingsAsync, getSources, ImportError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readConfigFile, readRawSettings, readSettings, readSettingsFiles, resolveConfigFileImports, searchForConfig, sectionCSpell, toCSpellSettingsWithOutSourceTrace, } from './Settings/index.js';
17
17
  export { defaultFileName as defaultSettingsFilename } from './Settings/index.js';
18
18
  export * as Link from './Settings/index.link.js';
19
19
  export { combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, } from './Settings/TextDocumentSettings.js';
20
- export { determineFinalDocumentSettings, type DetermineFinalDocumentSettingsResult, spellCheckDocument, spellCheckFile, type SpellCheckFileOptions, type SpellCheckFilePerf, type SpellCheckFileResult, } from './spellCheckFile.js';
20
+ export { determineFinalDocumentSettings, type DetermineFinalDocumentSettingsResult, spellCheckDocument, spellCheckDocumentRPC, spellCheckFile, type SpellCheckFileOptions, type SpellCheckFilePerf, type SpellCheckFileResult, } from './spellCheckFile.js';
21
21
  export { CompoundWordsMethod, createSpellingDictionary, createCollection as createSpellingDictionaryCollection, isSpellingDictionaryLoadError, refreshDictionaryCache, type SpellingDictionary, type SpellingDictionaryCollection, SpellingDictionaryLoadError, type SuggestionCollector, type SuggestionResult, type SuggestOptions, } from './SpellingDictionary/index.js';
22
22
  export type { SuggestedWord, SuggestionOptions, SuggestionsForWordResult } from './suggestions.js';
23
23
  export { SuggestionError, suggestionsForWord, suggestionsForWords } from './suggestions.js';
package/dist/lib/index.js CHANGED
@@ -7,11 +7,11 @@ export { getLanguagesForBasename as getLanguageIdsForBaseFilename, getLanguagesF
7
7
  export { getDictionary } from './getDictionary.js';
8
8
  export { createTextDocument, updateTextDocument } from './Models/TextDocument.js';
9
9
  export { createPerfTimer } from './perf/index.js';
10
- export { calcOverrideSettings, checkFilenameMatchesGlob, createConfigLoader, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getGlobalSettings, getGlobalSettingsAsync, getSources, ImportError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readConfigFile, readRawSettings, readSettings, readSettingsFiles, resolveConfigFileImports, searchForConfig, sectionCSpell, } from './Settings/index.js';
10
+ export { calcOverrideSettings, checkFilenameMatchesGlob, createConfigLoader, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getGlobalSettings, getGlobalSettingsAsync, getSources, ImportError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readConfigFile, readRawSettings, readSettings, readSettingsFiles, resolveConfigFileImports, searchForConfig, sectionCSpell, toCSpellSettingsWithOutSourceTrace, } from './Settings/index.js';
11
11
  export { defaultFileName as defaultSettingsFilename } from './Settings/index.js';
12
12
  export * as Link from './Settings/index.link.js';
13
13
  export { combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, } from './Settings/TextDocumentSettings.js';
14
- export { determineFinalDocumentSettings, spellCheckDocument, spellCheckFile, } from './spellCheckFile.js';
14
+ export { determineFinalDocumentSettings, spellCheckDocument, spellCheckDocumentRPC, spellCheckFile, } from './spellCheckFile.js';
15
15
  export { CompoundWordsMethod, createSpellingDictionary, createCollection as createSpellingDictionaryCollection, isSpellingDictionaryLoadError, refreshDictionaryCache, SpellingDictionaryLoadError, } from './SpellingDictionary/index.js';
16
16
  export { SuggestionError, suggestionsForWord, suggestionsForWords } from './suggestions.js';
17
17
  export { DocumentValidator, shouldCheckDocument } from './textValidation/index.js';
@@ -1,3 +1,4 @@
1
1
  export type { PerfTimer } from './timer.js';
2
2
  export { createPerfTimer } from './timer.js';
3
+ export { measurePerf } from '@cspell/cspell-performance-monitor';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,3 @@
1
1
  export { createPerfTimer } from './timer.js';
2
+ export { measurePerf } from '@cspell/cspell-performance-monitor';
2
3
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,7 @@
1
1
  import type { CSpellSettingsWithSourceTrace, CSpellUserSettings } from '@cspell/cspell-types';
2
- import { ICSpellConfigFile } from 'cspell-config-lib';
2
+ import type { ICSpellConfigFile } from 'cspell-config-lib';
3
3
  import type { Document, DocumentWithText } from './Document/index.js';
4
+ import type { ImportFileRefWithError } from './Settings/index.js';
4
5
  import type { Uri } from './util/IUri.js';
5
6
  import type { ValidateTextOptions, ValidationIssue } from './validator.js';
6
7
  export interface SpellCheckFileOptions extends ValidateTextOptions, Pick<CSpellUserSettings, 'unknownWords'> {
@@ -38,6 +39,8 @@ export interface SpellCheckFileResult {
38
39
  issues: ValidationIssue[];
39
40
  checked: boolean;
40
41
  errors: Error[] | undefined;
42
+ configErrors?: ImportFileRefWithError[] | undefined;
43
+ dictionaryErrors?: Map<string, Error[]> | undefined;
41
44
  perf?: SpellCheckFilePerf;
42
45
  }
43
46
  /**
@@ -54,6 +57,13 @@ export declare function spellCheckFile(file: string | Uri | URL, options: SpellC
54
57
  * @param settings - default settings to use.
55
58
  */
56
59
  export declare function spellCheckDocument(document: Document | DocumentWithText, options: SpellCheckFileOptions, settingsOrConfigFile: CSpellUserSettings | ICSpellConfigFile): Promise<SpellCheckFileResult>;
60
+ /**
61
+ * Spell Check a Document.
62
+ * @param document - document to be checked. If `document.text` is `undefined` the file will be loaded
63
+ * @param options - options to control checking
64
+ * @param settings - default settings to use.
65
+ */
66
+ export declare function spellCheckDocumentRPC(document: Document | DocumentWithText, options: SpellCheckFileOptions, settingsOrConfigFile: CSpellUserSettings | ICSpellConfigFile): Promise<SpellCheckFileResult>;
57
67
  export interface DetermineFinalDocumentSettingsResult {
58
68
  document: DocumentWithText;
59
69
  settings: CSpellSettingsWithSourceTrace;
@@ -3,9 +3,11 @@ import { isBinaryDoc } from './Document/isBinaryDoc.js';
3
3
  import { documentToTextDocument, resolveDocument } from './Document/resolveDocument.js';
4
4
  import { createTextDocument } from './Models/TextDocument.js';
5
5
  import { createPerfTimer } from './perf/index.js';
6
+ import { cloneSettingsForExport } from './Settings/sanitizeSettings.js';
6
7
  import { determineTextDocumentSettings } from './textValidation/determineTextDocumentSettings.js';
7
8
  import { DocumentValidator } from './textValidation/index.js';
8
9
  import { isError } from './util/errors.js';
10
+ import { memoizeLastCall } from './util/memoizeLastCall.js';
9
11
  import { toUri } from './util/Uri.js';
10
12
  /**
11
13
  * Spell Check a file
@@ -73,6 +75,21 @@ export async function spellCheckDocument(document, options, settingsOrConfigFile
73
75
  };
74
76
  }
75
77
  }
78
+ const memoizedCloneSettingsForExport = memoizeLastCall(cloneSettingsForExport);
79
+ function sanitizeSettingsForExport(settings) {
80
+ return settings ? memoizedCloneSettingsForExport(settings) : {};
81
+ }
82
+ /**
83
+ * Spell Check a Document.
84
+ * @param document - document to be checked. If `document.text` is `undefined` the file will be loaded
85
+ * @param options - options to control checking
86
+ * @param settings - default settings to use.
87
+ */
88
+ export async function spellCheckDocumentRPC(document, options, settingsOrConfigFile) {
89
+ const result = { ...(await spellCheckDocument(document, options, settingsOrConfigFile)) };
90
+ result.settingsUsed = sanitizeSettingsForExport(result.settingsUsed);
91
+ return result;
92
+ }
76
93
  async function spellCheckFullDocument(document, options, settingsOrConfigFile) {
77
94
  // if (options.skipValidation) {
78
95
  // return {
@@ -95,17 +112,18 @@ async function spellCheckFullDocument(document, options, settingsOrConfigFile) {
95
112
  Object.assign(perf, Object.fromEntries(Object.entries(docValidator.perfTiming).map(([k, v]) => ['_' + k, v])));
96
113
  const prep = docValidator._getPreparations();
97
114
  if (docValidator.errors.length) {
115
+ const settingsUsed = prep?.localConfig ||
116
+ (satisfiesCSpellConfigFile(settingsOrConfigFile) ? settingsOrConfigFile.settings : settingsOrConfigFile);
98
117
  return {
99
118
  document,
100
119
  options,
101
- settingsUsed: prep?.localConfig ||
102
- (satisfiesCSpellConfigFile(settingsOrConfigFile)
103
- ? settingsOrConfigFile.settings
104
- : settingsOrConfigFile),
120
+ settingsUsed,
105
121
  localConfigFilepath: prep?.localConfigFilepath,
106
122
  issues: [],
107
123
  checked: false,
108
124
  errors: docValidator.errors,
125
+ configErrors: docValidator.getConfigErrors(),
126
+ dictionaryErrors: docValidator.getDictionaryErrors(),
109
127
  perf,
110
128
  };
111
129
  }
@@ -121,6 +139,8 @@ async function spellCheckFullDocument(document, options, settingsOrConfigFile) {
121
139
  issues,
122
140
  checked: docValidator.shouldCheckDocument(),
123
141
  errors: undefined,
142
+ configErrors: docValidator.getConfigErrors(),
143
+ dictionaryErrors: docValidator.getDictionaryErrors(),
124
144
  perf,
125
145
  };
126
146
  timer.end();
@@ -1,5 +1,5 @@
1
1
  import type { CSpellSettings, LocaleId } from '@cspell/cspell-types';
2
- import { ICSpellConfigFile } from 'cspell-config-lib';
2
+ import type { ICSpellConfigFile } from 'cspell-config-lib';
3
3
  import type { LanguageId } from './fileTypes.js';
4
4
  import type { SpellingDictionaryCollection, SuggestionResult, SuggestOptions } from './SpellingDictionary/index.js';
5
5
  export interface WordSuggestion extends SuggestionResult {
@@ -4,7 +4,7 @@ import { finalizeSettings, getDefaultSettings, getGlobalSettingsAsync, mergeSett
4
4
  import { calcSettingsForLanguageId, isValidLocaleIntlFormat, normalizeLocaleIntl, } from './Settings/LanguageSettings.js';
5
5
  import { getDictionaryInternal, refreshDictionaryCache } from './SpellingDictionary/index.js';
6
6
  import { createAutoResolveCache } from './util/AutoResolve.js';
7
- import { memorizeLastCall } from './util/memorizeLastCall.js';
7
+ import { memoizeLastCall } from './util/memoizeLastCall.js';
8
8
  import * as util from './util/util.js';
9
9
  const emptySuggestionOptions = Object.freeze({});
10
10
  const emptyCSpellSettings = Object.freeze({});
@@ -14,14 +14,14 @@ export async function* suggestionsForWords(words, options, settings) {
14
14
  yield await suggestionsForWord(word, options, cspellSettings);
15
15
  }
16
16
  }
17
- const memorizeSuggestions = memorizeLastCall(cacheSuggestionsForWord);
17
+ const memoizeSuggestions = memoizeLastCall(cacheSuggestionsForWord);
18
18
  function cacheSuggestionsForWord(options, settings) {
19
19
  const cache = createAutoResolveCache();
20
20
  return (word) => cache.get(word, (word) => _suggestionsForWord(word, options, settings));
21
21
  }
22
22
  export async function suggestionsForWord(word, options = emptySuggestionOptions, settings = emptyCSpellSettings) {
23
23
  const cspellSettings = satisfiesCSpellConfigFile(settings) ? await resolveConfigFileImports(settings) : settings;
24
- return memorizeSuggestions(options, cspellSettings)(word);
24
+ return memoizeSuggestions(options, cspellSettings)(word);
25
25
  }
26
26
  async function _suggestionsForWord(word, options, settings) {
27
27
  const { languageId, locale: language, includeDefaultConfig = true, dictionaries } = options;
@@ -0,0 +1,3 @@
1
+ import type { ValidationIssue } from '../Models/ValidationIssue.js';
2
+ export declare function cleanValidationIssue(issue: ValidationIssue): ValidationIssue;
3
+ //# sourceMappingURL=cleanValidationIssue.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { cloneInto, copy0, copy1 } from '../util/clone.js';
2
+ export function cleanValidationIssue(issue) {
3
+ const cleanIssue = {};
4
+ cloneInto(issue, cleanIssue, ValidationIssueHandlers);
5
+ return cleanIssue;
6
+ }
7
+ const ValidationIssueHandlers = {
8
+ text: copy0,
9
+ offset: copy0,
10
+ message: copy0,
11
+ line: copy1,
12
+ length: copy0,
13
+ issueType: copy0,
14
+ hasPreferredSuggestions: copy0,
15
+ hasSimpleSuggestions: copy0,
16
+ isFlagged: copy0,
17
+ isFound: copy0,
18
+ suggestions: copy1,
19
+ suggestionsEx: copy1,
20
+ };
21
+ //# sourceMappingURL=cleanValidationIssue.js.map
@@ -1,6 +1,6 @@
1
1
  import type { CSpellUserSettings } from '@cspell/cspell-types';
2
- import type { CSpellSettingsInternal } from '../Models/CSpellSettingsInternalDef.js';
3
2
  import type { TextDocument, TextDocumentRef } from '../Models/TextDocument.js';
3
+ import type { CSpellSettingsInternal } from '../Settings/index.js';
4
4
  /**
5
5
  * Combines all relevant setting values into a final configuration to be used for spell checking.
6
6
  * It applies any overrides and appropriate language settings by taking into account the document type (languageId)
@@ -1,15 +1,16 @@
1
1
  import type { CSpellUserSettings, MappedText, ParsedText } from '@cspell/cspell-types';
2
- import { ICSpellConfigFile } from 'cspell-config-lib';
3
- import type { CSpellSettingsInternal, CSpellSettingsInternalFinalized } from '../Models/CSpellSettingsInternalDef.js';
2
+ import type { ICSpellConfigFile } from 'cspell-config-lib';
4
3
  import type { ExtendedSuggestion } from '../Models/Suggestion.js';
5
4
  import type { TextDocument, TextDocumentRef } from '../Models/TextDocument.js';
6
5
  import type { ValidationIssue } from '../Models/ValidationIssue.js';
6
+ import type { ImportFileRefWithError } from '../Settings/index.js';
7
+ import type { CSpellSettingsInternal, CSpellSettingsInternalFinalized } from '../Settings/index.js';
7
8
  import type { SpellingDictionaryCollection } from '../SpellingDictionary/index.js';
8
9
  import type { WordSuggestion } from '../suggestions.js';
9
10
  import type { MatchRange } from '../util/TextRange.js';
10
11
  import type { TextValidator } from './lineValidatorFactory.js';
11
12
  import type { SimpleRange } from './parsedText.js';
12
- import { TraceResult } from './traceWord.js';
13
+ import type { TraceResult } from './traceWord.js';
13
14
  import type { ValidateTextOptions } from './ValidateTextOptions.js';
14
15
  import type { ValidationOptions } from './ValidationTypes.js';
15
16
  export interface DocumentValidatorOptions extends ValidateTextOptions {
@@ -101,6 +102,8 @@ export declare class DocumentValidator {
101
102
  private genSuggestions;
102
103
  private adjustSuggestions;
103
104
  getFinalizedDocSettings(): CSpellSettingsInternal;
105
+ getConfigErrors(): ImportFileRefWithError[] | undefined;
106
+ getDictionaryErrors(): Map<string, Error[]> | undefined;
104
107
  /**
105
108
  * Returns true if the final result of the configuration calculation results
106
109
  * in the document being enabled. Note: in some cases, checking the document
@@ -5,14 +5,15 @@ import { toFilePathOrHref, toFileURL } from '@cspell/url';
5
5
  import { satisfiesCSpellConfigFile } from 'cspell-config-lib';
6
6
  import { getGlobMatcherForExcluding } from '../globs/getGlobMatcher.js';
7
7
  import { documentUriToURL, updateTextDocument } from '../Models/TextDocument.js';
8
- import { createPerfTimer } from '../perf/index.js';
9
- import { finalizeSettings, loadConfig, mergeSettings, resolveConfigFileImports, resolveSettingsImports, searchForConfig, } from '../Settings/index.js';
8
+ import { createPerfTimer, measurePerf } from '../perf/index.js';
9
+ import { extractImportErrors, finalizeSettings, loadConfig, mergeSettings, resolveConfigFileImports, resolveSettingsImports, searchForConfig, } from '../Settings/index.js';
10
10
  import { validateInDocumentSettings } from '../Settings/InDocSettings.js';
11
11
  import { getDictionaryInternal } from '../SpellingDictionary/index.js';
12
12
  import { calcSuggestionAdjustedToToMatchCase } from '../suggestions.js';
13
13
  import { catchPromiseError, toError } from '../util/errors.js';
14
14
  import { AutoCache } from '../util/simpleCache.js';
15
15
  import { uriToFilePath } from '../util/Uri.js';
16
+ import { cleanValidationIssue } from './cleanValidationIssue.js';
16
17
  import { defaultMaxDuplicateProblems, defaultMaxNumberOfProblems } from './defaultConstants.js';
17
18
  import { determineTextDocumentSettings } from './determineTextDocumentSettings.js';
18
19
  import { textValidatorFactory } from './lineValidatorFactory.js';
@@ -82,13 +83,14 @@ export class DocumentValidator {
82
83
  ? timePromise(this.perfTiming, '__searchForDocumentConfig', searchForDocumentConfig(this._document, settings, settings))
83
84
  : undefined;
84
85
  if (pLocalConfig) {
85
- timePromise(this.perfTiming, '_loadConfig', pLocalConfig);
86
+ timePromise(this.perfTiming, '_loadConfig', pLocalConfig).catch(() => undefined);
86
87
  }
87
88
  const localConfig = (await catchPromiseError(pLocalConfig, (e) => this.addPossibleError(e))) || {};
88
- this.addPossibleError(localConfig?.__importRef?.error);
89
+ extractImportErrors(localConfig).forEach((e) => this.addPossibleError(e.error));
89
90
  const config = mergeSettings(settings, localConfig);
90
91
  const docSettings = await timePromise(this.perfTiming, '_determineTextDocumentSettings', determineTextDocumentSettings(this._document, config));
91
92
  const dict = await timePromise(this.perfTiming, '_getDictionaryInternal', getDictionaryInternal(docSettings));
93
+ const stopMeasure = measurePerf('DocumentValidator._prepareAsync');
92
94
  const recGlobMatcherTime = recordPerfTime(this.perfTiming, '_GlobMatcher');
93
95
  const matcher = getGlobMatcherForExcluding(localConfig?.ignorePaths);
94
96
  const uri = this._document.uri;
@@ -120,6 +122,7 @@ export class DocumentValidator {
120
122
  this._ready = true;
121
123
  this._preparationTime = timer.elapsed;
122
124
  this.perfTiming.prepTime = this._preparationTime;
125
+ stopMeasure();
123
126
  }
124
127
  async _updatePrep() {
125
128
  assert(this._preparations, ERROR_NOT_PREPARED);
@@ -127,6 +130,7 @@ export class DocumentValidator {
127
130
  const prep = this._preparations;
128
131
  const docSettings = await determineTextDocumentSettings(this._document, prep.config);
129
132
  const dict = await getDictionaryInternal(docSettings);
133
+ const stopMeasure = measurePerf('DocumentValidator._updatePrep');
130
134
  const shouldCheck = docSettings.enabled ?? true;
131
135
  const finalSettings = finalizeSettings(docSettings);
132
136
  const validateOptions = settingsToValidateOptions(finalSettings);
@@ -144,6 +148,7 @@ export class DocumentValidator {
144
148
  textValidator,
145
149
  };
146
150
  this._preparationTime = timer.elapsed;
151
+ stopMeasure();
147
152
  }
148
153
  /**
149
154
  * The amount of time in ms to prepare for validation.
@@ -241,7 +246,9 @@ export class DocumentValidator {
241
246
  const spellingIssues = forceCheck || this.shouldCheckDocument() ? [...this._checkParsedText(this._parse())] : [];
242
247
  const directiveIssues = this.checkDocumentDirectives();
243
248
  // console.log('Stats: %o', this._preparations.textValidator.lineValidator.dict.stats());
244
- const allIssues = [...spellingIssues, ...directiveIssues].sort((a, b) => a.offset - b.offset);
249
+ const allIssues = [...spellingIssues, ...directiveIssues]
250
+ .map(cleanValidationIssue)
251
+ .sort((a, b) => a.offset - b.offset);
245
252
  return allIssues;
246
253
  }
247
254
  finally {
@@ -297,6 +304,7 @@ export class DocumentValidator {
297
304
  const { maxNumberOfProblems = defaultMaxNumberOfProblems, maxDuplicateProblems = defaultMaxDuplicateProblems } = this._preparations.validateOptions;
298
305
  let numProblems = 0;
299
306
  const mapOfProblems = new Map();
307
+ const stopMeasure = measurePerf('DocumentValidator._checkParsedText');
300
308
  for (const pText of parsedTexts) {
301
309
  for (const issue of this.check(pText)) {
302
310
  const { text } = issue;
@@ -309,6 +317,7 @@ export class DocumentValidator {
309
317
  return;
310
318
  }
311
319
  }
320
+ stopMeasure();
312
321
  }
313
322
  addPossibleError(error) {
314
323
  if (!error)
@@ -354,6 +363,20 @@ export class DocumentValidator {
354
363
  assert(this._preparations, ERROR_NOT_PREPARED);
355
364
  return this._preparations.docSettings;
356
365
  }
366
+ getConfigErrors() {
367
+ const settings = this.getFinalizedDocSettings();
368
+ const errors = extractImportErrors(settings);
369
+ return errors.length ? errors : undefined;
370
+ }
371
+ getDictionaryErrors() {
372
+ assert(this._ready);
373
+ assert(this._preparations, ERROR_NOT_PREPARED);
374
+ const { dictionary } = this._preparations;
375
+ const errors = dictionary.dictionaries
376
+ .map((dict) => [dict.name, dict.getErrors?.()])
377
+ .filter((entry) => (entry[1] && entry[1].length > 0) || false);
378
+ return errors.length ? new Map(errors) : undefined;
379
+ }
357
380
  /**
358
381
  * Returns true if the final result of the configuration calculation results
359
382
  * in the document being enabled. Note: in some cases, checking the document
@@ -422,7 +445,7 @@ export async function shouldCheckDocument(doc, options, settings) {
422
445
  ? searchForDocumentConfig(doc, settings, settings)
423
446
  : undefined;
424
447
  const localConfig = (await catchPromiseError(pLocalConfig, addPossibleError)) || {};
425
- addPossibleError(localConfig?.__importRef?.error);
448
+ extractImportErrors(localConfig).forEach((e) => addPossibleError(e.error));
426
449
  const config = mergeSettings(settings, localConfig);
427
450
  const matcher = getGlobMatcherForExcluding(localConfig?.ignorePaths);
428
451
  // eslint-disable-next-line unicorn/prefer-regexp-test
@@ -1,4 +1,4 @@
1
- import { TextOffset } from '@cspell/cspell-types';
1
+ import type { TextOffset } from '@cspell/cspell-types';
2
2
  /**
3
3
  * Try to detect if a string is a random string of characters or is it camel case / snake case words.
4
4
  * @param s - string to check
@@ -13,7 +13,7 @@ import { isWordValidWithEscapeRetry } from './isWordValid.js';
13
13
  import { mapRangeBackToOriginalPos } from './parsedText.js';
14
14
  const MIN_HEX_SEQUENCE_LENGTH = 8;
15
15
  export function lineValidatorFactory(sDict, options) {
16
- const { minWordLength = defaultMinWordLength, flagWords = [], allowCompoundWords = false, ignoreCase = true, ignoreRandomStrings = defaultCSpellSettings.ignoreRandomStrings, minRandomLength = defaultCSpellSettings.minRandomLength, unknownWords = unknownWordsChoices.ReportAll, } = options;
16
+ const { minWordLength = defaultMinWordLength, flagWords = [], allowCompoundWords = false, ignoreCase = true, ignoreRandomStrings = defaultCSpellSettings.ignoreRandomStrings, minRandomLength = defaultCSpellSettings.minRandomLength, unknownWords = unknownWordsChoices.ReportAll, numSuggestions, } = options;
17
17
  const hasWordOptions = {
18
18
  ignoreCase,
19
19
  useCompounds: allowCompoundWords || undefined, // let the dictionaries decide on useCompounds if allow is false
@@ -67,17 +67,21 @@ export function lineValidatorFactory(sDict, options) {
67
67
  return autoResolve(cacheGetPreferredSuggestions, word, () => dictCol.getPreferredSuggestions(word));
68
68
  }
69
69
  const cacheHasSimpleSuggestions = new Map();
70
- function hasSimpleSuggestions(word) {
70
+ function getSimpleSuggestions(word) {
71
+ const numSug = numSuggestions ?? 5;
71
72
  return autoResolve(cacheHasSimpleSuggestions, word, () => {
72
73
  const sugs = dictCol.suggest(word, {
73
74
  numSuggestions: 1,
74
75
  compoundMethod: 0,
75
- includeTies: false,
76
+ includeTies: true, // We want the top suggestions even if there are ties
76
77
  ignoreCase,
77
78
  timeout: 100,
78
79
  numChanges: 1.8, // Only consider very simple changes (1 edit distance plus case changes)
79
80
  });
80
- return !!sugs.length;
81
+ if (sugs.length > numSug) {
82
+ sugs.length = numSug;
83
+ }
84
+ return sugs;
81
85
  });
82
86
  }
83
87
  function isWordFlagged(wo) {
@@ -92,7 +96,11 @@ export function lineValidatorFactory(sDict, options) {
92
96
  if (!sugs?.length) {
93
97
  issue.hasPreferredSuggestions = sugs !== undefined ? false : undefined;
94
98
  if (unknownWords === unknownWordsChoices.ReportSimple) {
95
- issue.hasSimpleSuggestions = hasSimpleSuggestions(issue.text);
99
+ const sug = getSimpleSuggestions(issue.text);
100
+ issue.hasSimpleSuggestions = !!sug.length;
101
+ if (sug.length) {
102
+ issue.suggestionsEx = sug.map((s) => ({ ...s, isPreferred: !!s.isPreferred }));
103
+ }
96
104
  }
97
105
  return issue;
98
106
  }
@@ -1,4 +1,4 @@
1
- import type { CSpellSettingsInternalFinalized } from '../Models/CSpellSettingsInternalDef.js';
1
+ import type { CSpellSettingsInternalFinalized } from '../Settings/index.js';
2
2
  import type { ValidationOptions } from './ValidationTypes.js';
3
3
  export declare function settingsToValidateOptions(settings: CSpellSettingsInternalFinalized): ValidationOptions;
4
4
  //# sourceMappingURL=settingsToValidateOptions.d.ts.map
@@ -31,6 +31,7 @@ export interface TraceResult extends Array<DictionaryTraceResult> {
31
31
  }
32
32
  export interface TraceOptions extends Pick<CSpellSettingsWithSourceTrace, 'source' | 'allowCompoundWords'> {
33
33
  ignoreCase?: boolean;
34
+ compoundSeparator?: string | undefined;
34
35
  }
35
36
  export declare function traceWord(word: string, dictCollection: SpellingDictionaryCollection, config: TraceOptions): TraceResult;
36
37
  export {};