cspell-lib 8.14.1 → 8.14.3

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.
@@ -1,15 +1,12 @@
1
1
  import { clean } from '../util/util.js';
2
2
  export const SymbolCSpellSettingsInternal = Symbol('CSpellSettingsInternal');
3
- export function cleanCSpellSettingsInternal(parts = {}) {
4
- const csi = clean(parts);
5
- Object.assign(csi, { [SymbolCSpellSettingsInternal]: true });
6
- return csi;
3
+ export function cleanCSpellSettingsInternal(parts) {
4
+ return parts
5
+ ? Object.assign(clean(parts), { [SymbolCSpellSettingsInternal]: true })
6
+ : { [SymbolCSpellSettingsInternal]: true };
7
7
  }
8
- export function createCSpellSettingsInternal(parts = {}) {
9
- return clean({
10
- ...parts,
11
- [SymbolCSpellSettingsInternal]: true,
12
- });
8
+ export function createCSpellSettingsInternal(parts) {
9
+ return cleanCSpellSettingsInternal({ ...parts });
13
10
  }
14
11
  export function isCSpellSettingsInternal(cs) {
15
12
  return !!cs[SymbolCSpellSettingsInternal];
@@ -10,7 +10,7 @@ declare function mergeObjects<T>(left: T, right: undefined): T;
10
10
  declare function mergeObjects<T>(left: T, right: T): T;
11
11
  declare function mergeObjects<T>(left: undefined, right: T): T;
12
12
  export declare function mergeSettings(left: CSpellSettingsWSTO | CSpellSettingsI, ...settings: (CSpellSettingsWSTO | CSpellSettingsI | undefined)[]): CSpellSettingsI;
13
- export declare function mergeInDocSettings(left: CSpellSettingsWSTO, right: CSpellSettingsWSTO): CSpellSettingsWST;
13
+ export declare function mergeInDocSettings(left: CSpellSettingsWSTO, ...rest: CSpellSettingsWSTO[]): CSpellSettingsWST;
14
14
  /**
15
15
  *
16
16
  * @param settings - settings to finalize
@@ -1,5 +1,4 @@
1
1
  import assert from 'node:assert';
2
- import { pathToFileURL } from 'node:url';
3
2
  import { onClearCache } from '../events/index.js';
4
3
  import { cleanCSpellSettingsInternal as csi, isCSpellSettingsInternal } from '../Models/CSpellSettingsInternalDef.js';
5
4
  import { autoResolveWeak, AutoResolveWeakCache } from '../util/AutoResolve.js';
@@ -9,6 +8,7 @@ import { configSettingsFileVersion0_1, ENV_CSPELL_GLOB_ROOT } from './constants.
9
8
  import { calcDictionaryDefsToLoad, mapDictDefsToInternal } from './DictionarySettings.js';
10
9
  import { mergeList, mergeListUnique } from './mergeList.js';
11
10
  import { resolvePatterns } from './patterns.js';
11
+ import { CwdUrlResolver } from './resolveCwd.js';
12
12
  export { stats as getMergeStats } from './mergeList.js';
13
13
  const emptyWords = [];
14
14
  Object.freeze(emptyWords);
@@ -17,12 +17,16 @@ const mergeCache = new AutoResolveWeakCache();
17
17
  const cacheInternalSettings = new AutoResolveWeakCache();
18
18
  const parserCache = new AutoResolveWeakCache();
19
19
  const emptyParserMap = new Map();
20
+ const cwdResolver = new CwdUrlResolver();
21
+ let envCSpellGlobRoot = process.env[ENV_CSPELL_GLOB_ROOT];
20
22
  onClearCache(() => {
21
23
  parserCache.clear();
22
24
  emptyParserMap.clear();
23
25
  cachedMerges.clear();
24
26
  mergeCache.clear();
25
27
  cacheInternalSettings.clear();
28
+ cwdResolver.reset();
29
+ envCSpellGlobRoot = process.env[ENV_CSPELL_GLOB_ROOT];
26
30
  });
27
31
  function _mergeWordsCached(left, right) {
28
32
  const map = autoResolveWeak(cachedMerges, left, () => new WeakMap());
@@ -154,11 +158,8 @@ function hasAncestor(s, ancestor, side) {
154
158
  const src = sources[i];
155
159
  return src === ancestor || (src && hasAncestor(src, ancestor, side)) || false;
156
160
  }
157
- export function mergeInDocSettings(left, right) {
158
- const merged = {
159
- ...mergeSettings(left, right),
160
- includeRegExpList: mergeListUnique(left.includeRegExpList, right.includeRegExpList),
161
- };
161
+ export function mergeInDocSettings(left, ...rest) {
162
+ const merged = mergeSettings(left, ...rest);
162
163
  return util.clean(merged);
163
164
  }
164
165
  function takeRightOtherwiseLeft(left, right) {
@@ -197,7 +198,8 @@ export function toInternalSettings(settings) {
197
198
  }
198
199
  function _toInternalSettings(settings) {
199
200
  const { dictionaryDefinitions: defs, ...rest } = settings;
200
- const dictionaryDefinitions = mapDictDefsToInternal(defs, (settings.source?.filename && toFileUrl(settings.source?.filename)) || resolveCwd());
201
+ const dictionaryDefinitions = defs &&
202
+ mapDictDefsToInternal(defs, (settings.source?.filename && toFileUrl(settings.source?.filename)) || resolveCwd());
201
203
  const setting = dictionaryDefinitions ? { ...rest, dictionaryDefinitions } : rest;
202
204
  return csi(setting);
203
205
  }
@@ -260,9 +262,7 @@ export function extractDependencies(settings) {
260
262
  };
261
263
  }
262
264
  function resolveCwd() {
263
- const envGlobRoot = process.env[ENV_CSPELL_GLOB_ROOT];
264
- const cwd = envGlobRoot || process.cwd();
265
- return pathToFileURL(cwd);
265
+ return cwdResolver.resolveUrl(envCSpellGlobRoot);
266
266
  }
267
267
  function resolveParser(settings) {
268
268
  if (!settings.parser)
@@ -1,5 +1,4 @@
1
1
  import type { CSpellUserSettings, DictionaryDefinitionInline } from '@cspell/cspell-types';
2
- import type { Sequence } from 'gensequence';
3
2
  import type { ExtendedSuggestion } from '../Models/Suggestion.js';
4
3
  export type CSpellUserSettingsKeys = keyof CSpellUserSettings;
5
4
  export interface DirectiveIssue {
@@ -15,16 +14,31 @@ export interface DirectiveIssue {
15
14
  suggestions: string[];
16
15
  suggestionsEx: ExtendedSuggestion[];
17
16
  }
17
+ declare function collectInDocumentDirectives(text: string): DirectiveMatchWithParser[];
18
18
  export declare function getInDocumentSettings(text: string): CSpellUserSettings;
19
19
  export declare function validateInDocumentSettings(docText: string, _settings: CSpellUserSettings): Iterable<DirectiveIssue>;
20
+ interface PossibleMatch {
21
+ /** The full directive text till the end of the line */
22
+ fullDirective: string;
23
+ /** Offset of the directive */
24
+ offset: number;
25
+ /** the partial directive, missing the CSpell prefix. */
26
+ match: string;
27
+ }
28
+ type Directive = 'CompoundWords' | 'CaseSensitive' | 'Enable' | 'Disable' | 'Words' | 'Ignore' | 'Flag' | 'IgnoreRegExp' | 'IncludeRegExp' | 'Locale' | 'Dictionaries';
29
+ type ReducerFn = (acc: CSpellUserSettings, match: string) => CSpellUserSettings;
30
+ interface DirectiveMatchWithParser extends PossibleMatch {
31
+ directive: Directive;
32
+ fn: ReducerFn;
33
+ }
20
34
  export declare const regExSpellingGuardBlock: RegExp;
21
35
  export declare const regExSpellingGuardNext: RegExp;
22
36
  export declare const regExSpellingGuardLine: RegExp;
23
- declare function parseCompoundWords(match: string): CSpellUserSettings;
24
- declare function parseWords(match: string): CSpellUserSettings;
25
- declare function parseIgnoreWords(match: string): CSpellUserSettings;
26
- declare function parseIgnoreRegExp(match: string): CSpellUserSettings;
27
- declare function getPossibleInDocSettings(text: string): Sequence<RegExpExecArray>;
37
+ declare function parseCompoundWords(acc: CSpellUserSettings, match: string): CSpellUserSettings;
38
+ declare function parseWords(acc: CSpellUserSettings, match: string): CSpellUserSettings;
39
+ declare function parseIgnoreWords(acc: CSpellUserSettings, match: string): CSpellUserSettings;
40
+ declare function parseIgnoreRegExp(acc: CSpellUserSettings, match: string): CSpellUserSettings;
41
+ declare function getPossibleInDocSettings(text: string): Iterable<PossibleMatch>;
28
42
  declare function getWordsFromDocument(text: string): string[];
29
43
  export declare function extractInDocDictionary(settings: CSpellUserSettings): DictionaryDefinitionInline | undefined;
30
44
  export declare function getIgnoreWordsFromDocument(text: string): string[];
@@ -32,7 +46,8 @@ export declare function getIgnoreRegExpFromDocument(text: string): (string | Reg
32
46
  /**
33
47
  * These internal functions are used exposed for unit testing.
34
48
  */
35
- export declare const internal: {
49
+ export declare const __internal: {
50
+ collectInDocumentSettings: typeof collectInDocumentDirectives;
36
51
  getPossibleInDocSettings: typeof getPossibleInDocSettings;
37
52
  getWordsFromDocument: typeof getWordsFromDocument;
38
53
  parseWords: typeof parseWords;
@@ -1,9 +1,7 @@
1
- import { opAppend, opFilter, opMap, pipeSync } from '@cspell/cspell-pipe/sync';
2
- import { genSequence } from 'gensequence';
1
+ import { opAppend, opFilter, opFlatten, opMap, pipeSync } from '@cspell/cspell-pipe/sync';
3
2
  import { createSpellingDictionary } from '../SpellingDictionary/index.js';
4
3
  import * as Text from '../util/text.js';
5
4
  import { clean, isDefined } from '../util/util.js';
6
- import { mergeInDocSettings } from './CSpellSettingsServer.js';
7
5
  // cspell:ignore gimuy
8
6
  const regExMatchRegEx = /\/.*\/[gimuy]*/;
9
7
  const regExCSpellInDocDirective = /\b(?:spell-?checker|c?spell)::?(.*)/gi;
@@ -67,12 +65,17 @@ const dictInDocSettings = createSpellingDictionary(allDirectives, 'Directives',
67
65
  const EmptyWords = [];
68
66
  Object.freeze(EmptyWords);
69
67
  const staticInDocumentDictionaryName = `[in-document-dict]`;
68
+ function collectInDocumentDirectives(text) {
69
+ const dirs = [...getPossibleInDocSettings(text)].flatMap((a) => associateDirectivesWithParsers(a));
70
+ return dirs;
71
+ }
72
+ const baseInDocSettings = { id: 'in-doc-settings' };
73
+ Object.freeze(baseInDocSettings);
70
74
  export function getInDocumentSettings(text) {
71
- const collectedSettings = getPossibleInDocSettings(text)
72
- .concatMap((a) => parseSettingMatch(a))
73
- .reduce((s, setting) => {
74
- return mergeInDocSettings(s, setting);
75
- }, { id: 'in-doc-settings' });
75
+ const found = collectInDocumentDirectives(text);
76
+ if (!found.length)
77
+ return { ...baseInDocSettings };
78
+ const collectedSettings = reducePossibleMatchesToSettings(found, { ...baseInDocSettings });
76
79
  const { words, flagWords, ignoreWords, suggestWords, dictionaries = [], dictionaryDefinitions = [], ...rest } = collectedSettings;
77
80
  const dict = (words || flagWords || ignoreWords || suggestWords) &&
78
81
  clean({
@@ -95,44 +98,42 @@ export function getInDocumentSettings(text) {
95
98
  ...rest,
96
99
  ...dictSettings,
97
100
  };
98
- // console.log('InDocSettings: %o', settings);
99
101
  return settings;
100
102
  }
101
103
  export function validateInDocumentSettings(docText, _settings) {
102
104
  return pipeSync(getPossibleInDocSettings(docText), opMap(parseSettingMatchValidation), opFilter(isDefined));
103
105
  }
104
106
  const settingParsers = [
105
- [/^(?:enable|disable)(?:allow)?CompoundWords\b(?!-)/i, parseCompoundWords],
106
- [/^(?:enable|disable)CaseSensitive\b(?!-)/i, parseCaseSensitive],
107
- [/^enable\b(?!-)/i, parseEnable],
108
- [/^disable(-line|-next(-line)?)?\b(?!-)/i, parseDisable],
109
- [/^words?\b(?!-)/i, parseWords],
110
- [/^ignore(?:-?words?)?\b(?!-)/i, parseIgnoreWords],
111
- [/^(?:flag|forbid)(?:-?words?)?\b(?!-)/i, parseFlagWords],
112
- [/^ignore_?Reg_?Exp\s+.+$/i, parseIgnoreRegExp],
113
- [/^include_?Reg_?Exp\s+.+$/i, parseIncludeRegExp],
114
- [/^locale?\b(?!-)/i, parseLocale],
115
- [/^language\s\b(?!-)/i, parseLocale],
116
- [/^dictionar(?:y|ies)\b(?!-)/i, parseDictionaries], // cspell:disable-line
117
- [/^LocalWords:/, (w) => parseWords(w.replaceAll(/^LocalWords:?/gi, ' '))],
107
+ [/^(?:enable|disable)(?:allow)?CompoundWords\b(?!-)/i, parseCompoundWords, 'CompoundWords'],
108
+ [/^(?:enable|disable)CaseSensitive\b(?!-)/i, parseCaseSensitive, 'CaseSensitive'],
109
+ [/^enable\b(?!-)/i, parseEnable, 'Enable'],
110
+ [/^disable(-line|-next(-line)?)?\b(?!-)/i, parseDisable, 'Disable'],
111
+ [/^words?\b(?!-)/i, parseWords, 'Words'],
112
+ [/^ignore(?:-?words?)?\b(?!-)/i, parseIgnoreWords, 'Ignore'],
113
+ [/^(?:flag|forbid)(?:-?words?)?\b(?!-)/i, parseFlagWords, 'Flag'],
114
+ [/^ignore_?Reg_?Exp\s+.+$/i, parseIgnoreRegExp, 'IgnoreRegExp'],
115
+ [/^include_?Reg_?Exp\s+.+$/i, parseIncludeRegExp, 'IncludeRegExp'],
116
+ [/^locale?\b(?!-)/i, parseLocale, 'Locale'],
117
+ [/^language\s\b(?!-)/i, parseLocale, 'Locale'],
118
+ [/^dictionar(?:y|ies)\b(?!-)/i, parseDictionaries, 'Dictionaries'], // cspell:disable-line
119
+ [/^LocalWords:/, (acc, m) => reduceWordList(acc, m.replaceAll(/^LocalWords:?/gi, ' '), 'words'), 'Words'],
118
120
  ];
119
121
  export const regExSpellingGuardBlock = /(\bc?spell(?:-?checker)?::?)\s*disable(?!-line|-next)\b[\s\S]*?((?:\1\s*enable\b)|$)/gi;
120
122
  export const regExSpellingGuardNext = /\bc?spell(?:-?checker)?::?\s*disable-next\b.*\s\s?.*/gi;
121
123
  export const regExSpellingGuardLine = /^.*\bc?spell(?:-?checker)?::?\s*disable-line\b.*/gim;
122
- const emptySettings = Object.freeze({});
123
124
  const issueMessages = {
124
125
  unknownDirective: 'Unknown CSpell directive',
125
126
  };
126
- function parseSettingMatchValidation(matchArray) {
127
- const [fullMatch = ''] = matchArray;
128
- const directiveMatch = fullMatch.match(regExCSpellDirectiveKey);
127
+ function parseSettingMatchValidation(possibleMatch) {
128
+ const { fullDirective, offset } = possibleMatch;
129
+ const directiveMatch = fullDirective.match(regExCSpellDirectiveKey);
129
130
  if (!directiveMatch)
130
131
  return undefined;
131
132
  const match = directiveMatch[1];
132
133
  const possibleSetting = match.trim();
133
134
  if (!possibleSetting)
134
135
  return undefined;
135
- const start = (matchArray.index || 0) + (directiveMatch.index || 0) + (match.length - match.trimStart().length);
136
+ const start = offset + (directiveMatch.index || 0) + (match.length - match.trimStart().length);
136
137
  const text = possibleSetting.replace(/^([-\w]+)?.*/, '$1');
137
138
  const end = start + text.length;
138
139
  if (!text)
@@ -167,44 +168,66 @@ function* filterUniqueSuggestions(sugs) {
167
168
  yield sug;
168
169
  }
169
170
  }
170
- function parseSettingMatch(matchArray) {
171
- const [, match = ''] = matchArray;
171
+ function associateDirectivesWithParsers(possibleMatch) {
172
+ const { match } = possibleMatch;
172
173
  const possibleSetting = match.trim();
173
174
  return settingParsers
174
175
  .filter(([regex]) => regex.test(possibleSetting))
175
- .map(([, fn]) => fn)
176
- .map((fn) => fn(possibleSetting));
176
+ .map(([, fn, directive]) => ({ ...possibleMatch, directive, fn }));
177
+ }
178
+ function mergeDirectiveIntoSettings(settings, directive) {
179
+ return directive.fn(settings, directive.match);
177
180
  }
178
- function parseCompoundWords(match) {
179
- const allowCompoundWords = /enable/i.test(match);
180
- return { allowCompoundWords };
181
+ function reducePossibleMatchesToSettings(directives, settings) {
182
+ for (const directive of directives) {
183
+ settings = mergeDirectiveIntoSettings(settings, directive);
184
+ }
185
+ return settings;
181
186
  }
182
- function parseCaseSensitive(match) {
183
- const caseSensitive = /enable/i.test(match);
184
- return { caseSensitive };
187
+ function parseCompoundWords(acc, match) {
188
+ acc.allowCompoundWords = /enable/i.test(match);
189
+ return acc;
185
190
  }
186
- function parseWords(match) {
187
- const words = match
188
- // .replace(/[@#$%^&={}/"]/g, ' ')
191
+ function parseCaseSensitive(acc, match) {
192
+ acc.caseSensitive = /enable/i.test(match);
193
+ return acc;
194
+ }
195
+ function splitWords(match) {
196
+ return match
189
197
  .split(/[,\s;]+/g)
190
198
  .slice(1)
191
199
  .filter((a) => !!a);
192
- return { words };
193
200
  }
194
- function parseLocale(match) {
201
+ function mergeList(a, b) {
202
+ if (!a)
203
+ return b;
204
+ if (!b)
205
+ return a;
206
+ return [...a, ...b];
207
+ }
208
+ function reduceWordList(acc, match, key) {
209
+ const words = splitWords(match);
210
+ if (words.length) {
211
+ acc[key] = mergeList(acc[key], words);
212
+ }
213
+ return acc;
214
+ }
215
+ function parseWords(acc, match) {
216
+ return reduceWordList(acc, match, 'words');
217
+ }
218
+ function parseLocale(acc, match) {
195
219
  const parts = match.trim().split(/[\s,]+/);
196
220
  const language = parts.slice(1).join(',');
197
- return language ? { language } : emptySettings;
221
+ if (language) {
222
+ acc.language = language;
223
+ }
224
+ return acc;
198
225
  }
199
- function parseIgnoreWords(match) {
200
- const wordsSetting = parseWords(match);
201
- const ignoreWords = wordsSetting.words;
202
- return ignoreWords && ignoreWords.length ? { ignoreWords } : emptySettings;
226
+ function parseIgnoreWords(acc, match) {
227
+ return reduceWordList(acc, match, 'ignoreWords');
203
228
  }
204
- function parseFlagWords(match) {
205
- const wordsSetting = parseWords(match);
206
- const flagWords = wordsSetting.words;
207
- return flagWords && flagWords.length ? { flagWords } : emptySettings;
229
+ function parseFlagWords(acc, match) {
230
+ return reduceWordList(acc, match, 'flagWords');
208
231
  }
209
232
  function parseRegEx(match) {
210
233
  const patterns = [match.replace(/^[^\s]+\s+/, '')].map((a) => {
@@ -216,32 +239,41 @@ function parseRegEx(match) {
216
239
  });
217
240
  return patterns;
218
241
  }
219
- function parseIgnoreRegExp(match) {
242
+ function parseIgnoreRegExp(acc, match) {
220
243
  const ignoreRegExpList = parseRegEx(match);
221
- return { ignoreRegExpList };
244
+ if (ignoreRegExpList.length) {
245
+ acc.ignoreRegExpList = mergeList(acc.ignoreRegExpList, ignoreRegExpList);
246
+ }
247
+ return acc;
222
248
  }
223
- function parseIncludeRegExp(match) {
249
+ function parseIncludeRegExp(acc, match) {
224
250
  const includeRegExpList = parseRegEx(match);
225
- return { includeRegExpList };
251
+ if (includeRegExpList.length) {
252
+ acc.includeRegExpList = mergeList(acc.includeRegExpList, includeRegExpList);
253
+ }
254
+ return acc;
226
255
  }
227
- function parseDictionaries(match) {
256
+ function parseDictionaries(acc, match) {
228
257
  const dictionaries = match.split(/[,\s]+/g).slice(1);
229
- return { dictionaries };
258
+ if (dictionaries.length) {
259
+ acc.dictionaries = mergeList(acc.dictionaries, dictionaries);
260
+ }
261
+ return acc;
230
262
  }
231
263
  function getPossibleInDocSettings(text) {
232
- return genSequence(regExInFileSettings).concatMap((regexp) => Text.match(regexp, text));
264
+ return pipeSync(regExInFileSettings, opMap((regexp) => Text.match(regexp, text)), opFlatten(), opMap((match) => ({ fullDirective: match[0], offset: match.index, match: match[1].trim() })));
233
265
  }
234
266
  function getWordsFromDocument(text) {
235
267
  const dict = extractInDocDictionary(getInDocumentSettings(text));
236
268
  return dict?.words || EmptyWords;
237
269
  }
238
- function parseEnable(_match) {
270
+ function parseEnable(acc, _match) {
239
271
  // Do nothing. Enable / Disable is handled in a different way.
240
- return {};
272
+ return acc;
241
273
  }
242
- function parseDisable(_match) {
274
+ function parseDisable(acc, _match) {
243
275
  // Do nothing. Enable / Disable is handled in a different way.
244
- return {};
276
+ return acc;
245
277
  }
246
278
  export function extractInDocDictionary(settings) {
247
279
  const inDocDicts = settings.dictionaryDefinitions?.filter((def) => def.name === staticInDocumentDictionaryName);
@@ -259,7 +291,8 @@ export function getIgnoreRegExpFromDocument(text) {
259
291
  /**
260
292
  * These internal functions are used exposed for unit testing.
261
293
  */
262
- export const internal = {
294
+ export const __internal = {
295
+ collectInDocumentSettings: collectInDocumentDirectives,
263
296
  getPossibleInDocSettings,
264
297
  getWordsFromDocument,
265
298
  parseWords,
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=InDocSettings.perf.d.ts.map
@@ -0,0 +1,73 @@
1
+ import { suite } from 'perf-insight';
2
+ import { __internal, getInDocumentSettings } from './InDocSettings.js';
3
+ suite('Get InDocSettings', async (test) => {
4
+ const doc = sampleDoc();
5
+ const iterations = 10;
6
+ test('getInDocumentSettings', () => {
7
+ let settings = undefined;
8
+ for (let i = iterations; i > 0; --i) {
9
+ settings = getInDocumentSettings(doc);
10
+ }
11
+ return settings;
12
+ });
13
+ });
14
+ suite('Collect InDocSettings', async (test) => {
15
+ const doc = sampleDoc();
16
+ const iterations = 10;
17
+ test('collectInDocumentSettings', () => {
18
+ let settings = undefined;
19
+ for (let i = iterations; i > 0; --i) {
20
+ settings = __internal.collectInDocumentSettings(doc);
21
+ }
22
+ return settings;
23
+ });
24
+ });
25
+ function sampleDoc() {
26
+ return `
27
+ // cSpell\u003AenableCompoundWords
28
+ // cSpell\u003AdisableCompoundWords
29
+ // cSpell\u003A enableCOMPOUNDWords
30
+ // cSpell:words whiteberry, redberry, lightbrown
31
+ // cSpell\u003A ignoreRegExp /\\/\\/\\/.*/
32
+ // cSpell\u003AignoreRegexp w\\w+berry
33
+ // cSpell\u003A:ignoreRegExp /
34
+ /* cSpell\u003AignoreRegExp \\w+s{4}\\w+ */
35
+ /* cSpell\u003AignoreRegExp /faullts[/]?/ */
36
+ const berries = ['whiteberry', 'redberry', 'blueberry'];
37
+
38
+ /* cSpell\u003Aignore tripe, comment */
39
+ // cSpell\u003A: ignoreWords tooo faullts
40
+ /// ignore triple comment, with misssspellings and faullts
41
+ /// mooree prooobleems onn thisss line tooo with wordberry
42
+ // misssspellings faullts
43
+
44
+ // weirdberry can be straange.
45
+ // cSpell\u003Alanguage en-US
46
+ // cspell\u003Alocal
47
+ // cspell\u003Alocale es-ES
48
+ // cspell\u003Alocal en, nl
49
+
50
+ // cspell\u003Adictionaries lorem-ipsum
51
+ // LocalWords: one two three
52
+ // LocalWords:four five six
53
+ // localwords: seven eight nine
54
+
55
+ // cspell:ignore againxx
56
+ # cSpell\u003AdisableCompoundWords
57
+ # cSpell\u003AenableCOMPOUNDWords
58
+ # happydays arehere againxx
59
+
60
+ // cspell:ignore popoutlist
61
+
62
+ // spell\u003Adictionaries php
63
+ // spell\u003Awords const
64
+ // cspell\u003A
65
+ // cspell\u003Aignore popoutlist
66
+ const x = imp.popoutlist;
67
+ // cspell\u003Aignore again
68
+
69
+ // cspell:ignore happydays arehere againxx localwords weirdberry straange misssspellings
70
+ // cspell:ignore faullts mooree prooobleems onn thisss line tooo wordberry
71
+ `;
72
+ }
73
+ //# sourceMappingURL=InDocSettings.perf.js.map
@@ -21,10 +21,14 @@ export declare const regExBase64: RegExp;
21
21
  *
22
22
  * It must be:
23
23
  * - at least 40 characters
24
- * - contain at least 1 of [0-9+=]
25
- * - end at the end of the line or with [,"'\]
24
+ * - preceded by a non-Base64
25
+ * - contain at least 1 of [0-9+/]
26
+ * - contain at least 1 of [A-Z][a-z][A-Z]
27
+ * - contain at least 1 of [A-Z][0-9][A-Z] | [a-z][0-9][a-z] | [A-Z][0-9][a-z] | [0-9][A-Za-z][0-9]
28
+ * - contain at least 1 of [a-z]{3} | [A-Z]{3}
26
29
  */
27
30
  export declare const regExBase64SingleLine: RegExp;
31
+ export declare const regExBase64SingleLineLegacy: RegExp;
28
32
  export declare const regExBase64MultiLine: RegExp;
29
33
  export declare const regExPhpHereDoc: RegExp;
30
34
  export declare const regExString: RegExp;
@@ -23,10 +23,14 @@ export const regExBase64 = /(?<![A-Za-z0-9/+])(?:[A-Za-z0-9/+]{40,})(?:\s^\s*[A-
23
23
  *
24
24
  * It must be:
25
25
  * - at least 40 characters
26
- * - contain at least 1 of [0-9+=]
27
- * - end at the end of the line or with [,"'\]
26
+ * - preceded by a non-Base64
27
+ * - contain at least 1 of [0-9+/]
28
+ * - contain at least 1 of [A-Z][a-z][A-Z]
29
+ * - contain at least 1 of [A-Z][0-9][A-Z] | [a-z][0-9][a-z] | [A-Z][0-9][a-z] | [0-9][A-Za-z][0-9]
30
+ * - contain at least 1 of [a-z]{3} | [A-Z]{3}
28
31
  */
29
- export const regExBase64SingleLine = /(?<![A-Za-z0-9/+])(?=[^/]|[/][A-Za-z0-9/+]+?[=+])(?![A-Za-z/]+(?![A-Za-z0-9/+=]))(?=[A-Za-z0-9/+=]*?(?:[A-Z]{2}|[0-9]{2}))(?:[A-Za-z0-9/+]{4}){10,}(?:[A-Za-z0-9/+]{3}={1}|[A-Za-z0-9/+]{2}={2}|[A-Za-z0-9/+]{1}={3})?(?![A-Za-z0-9/+=])(?=$|[:.,"'\\)])/gm;
32
+ export const regExBase64SingleLine = /(?<=[^A-Za-z0-9/+_]|^)(?=[A-Za-z]{0,80}[0-9+/])(?=[A-Za-z0-9/+]{0,80}?[A-Z][a-z][A-Z])(?=[A-Za-z0-9/+]{0,80}?(?:[A-Z][0-9][A-Z]|[a-z][0-9][a-z]|[A-Z][0-9][a-z]|[a-z][0-9][A-Z]|[0-9][A-Za-z][0-9]))(?=[A-Za-z0-9/+]{0,80}?(?:[a-z]{3}|[A-Z]{3}))(?:[A-Za-z0-9/+]{40,})=*/gm;
33
+ export const regExBase64SingleLineLegacy = /((?<![A-Za-z0-9/+]))(?=[A-Za-z]{0,80}[0-9])(?:[A-Za-z0-9/+]{4}){10,}(?:[A-Za-z0-9/+]{3}={1}|[A-Za-z0-9/+]{2}={2}|[A-Za-z0-9/+]{1}={3})?(?![A-Za-z0-9/+=])(?=\1)/gm;
30
34
  export const regExBase64MultiLine = /(?<![A-Za-z0-9/+])["']?(?:[A-Za-z0-9/+]{40,})["']?(?:\s^\s*["']?[A-Za-z0-9/+]{40,}["']?)+(?:\s^\s*["']?[A-Za-z0-9/+]+={0,3}["']?)?(?![A-Za-z0-9/+=])/gm;
31
35
  // cspell:ignore aeiou
32
36
  // The following is an attempt at detecting random strings.
@@ -9,7 +9,8 @@ export function combineTextAndLanguageSettings(settings, text, languageId) {
9
9
  const settingsForText = mergeSettings(settings, docSettings);
10
10
  const langSettings = calcSettingsForLanguageId(settingsForText, languageId);
11
11
  // Merge again, to force In-Doc settings.
12
- return mergeSettings(langSettings, docSettings);
12
+ const final = mergeSettings(langSettings, docSettings);
13
+ return final;
13
14
  }
14
15
  export function extractSettingsFromText(text) {
15
16
  return getInDocumentSettings(text);
@@ -0,0 +1,7 @@
1
+ export declare class CwdUrlResolver {
2
+ #private;
3
+ constructor();
4
+ resolveUrl(path?: string): URL;
5
+ reset(cwd?: string): void;
6
+ }
7
+ //# sourceMappingURL=resolveCwd.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { pathToFileURL } from 'node:url';
2
+ export class CwdUrlResolver {
3
+ #lastPath;
4
+ #lastUrl;
5
+ #cwd;
6
+ #cwdUrl;
7
+ constructor() {
8
+ this.#cwd = process.cwd();
9
+ this.#cwdUrl = pathToFileURL(this.#cwd);
10
+ this.#lastPath = this.#cwd;
11
+ this.#lastUrl = this.#cwdUrl;
12
+ }
13
+ resolveUrl(path) {
14
+ path = path || this.#cwd;
15
+ if (path === this.#lastPath)
16
+ return this.#lastUrl;
17
+ if (path === this.#cwd)
18
+ return this.#cwdUrl;
19
+ this.#lastPath = path;
20
+ this.#lastUrl = pathToFileURL(path);
21
+ return this.#lastUrl;
22
+ }
23
+ reset(cwd = process.cwd()) {
24
+ this.#cwd = cwd;
25
+ this.#cwdUrl = pathToFileURL(this.#cwd);
26
+ }
27
+ }
28
+ //# sourceMappingURL=resolveCwd.js.map
@@ -1,6 +1,6 @@
1
1
  import * as path from 'node:path';
2
2
  import { getLanguagesForBasename } from '../fileTypes.js';
3
- import { calcOverrideSettings, getDefaultSettings, getGlobalSettings, mergeSettings } from '../Settings/index.js';
3
+ import { calcOverrideSettings, getDefaultSettings, getGlobalSettingsAsync, mergeSettings } from '../Settings/index.js';
4
4
  import { combineTextAndLanguageSettings } from '../Settings/TextDocumentSettings.js';
5
5
  import { uriToFilePath } from '../util/Uri.js';
6
6
  /**
@@ -17,7 +17,7 @@ import { uriToFilePath } from '../util/Uri.js';
17
17
  */
18
18
  export async function determineTextDocumentSettings(doc, settings) {
19
19
  const filename = uriToFilePath(doc.uri);
20
- const settingsWithDefaults = mergeSettings(await getDefaultSettings(settings.loadDefaultConfiguration ?? true), getGlobalSettings(), settings);
20
+ const settingsWithDefaults = mergeSettings(await getDefaultSettings(settings.loadDefaultConfiguration ?? true), await getGlobalSettingsAsync(), settings);
21
21
  const fileSettings = calcOverrideSettings(settingsWithDefaults, filename);
22
22
  const languageIds = fileSettings?.languageId?.length
23
23
  ? fileSettings.languageId
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cspell-lib",
3
- "version": "8.14.1",
3
+ "version": "8.14.3",
4
4
  "description": "A library of useful functions used across various cspell tools.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -33,7 +33,8 @@
33
33
  "#test": "vitest run --reporter=hanging-process --reporter=default",
34
34
  "test": "vitest run --pool=forks",
35
35
  "test:update-snapshot": "vitest run -u",
36
- "test:perf": "NODE_ENV=production insight --register ts-node/esm --file \"**/*.perf.{mts,ts}\""
36
+ "test:perf": "NODE_ENV=production insight --file \"**/*.perf.{mts,ts}\" --register ts-node/esm",
37
+ "test:perf:prof": "NODE_ENV=production node --cpu-prof ../../node_modules/perf-insight/bin.mjs --file \"dist/**/*.perf.{mjs,js}\" -t 1000"
37
38
  },
38
39
  "repository": {
39
40
  "type": "git",
@@ -56,24 +57,24 @@
56
57
  "bugs": {
57
58
  "url": "https://github.com/streetsidesoftware/cspell/labels/cspell-lib"
58
59
  },
59
- "homepage": "https://github.com/streetsidesoftware/cspell#readme",
60
+ "homepage": "https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-lib#readme",
60
61
  "dependencies": {
61
- "@cspell/cspell-bundled-dicts": "8.14.1",
62
- "@cspell/cspell-pipe": "8.14.1",
63
- "@cspell/cspell-resolver": "8.14.1",
64
- "@cspell/cspell-types": "8.14.1",
65
- "@cspell/dynamic-import": "8.14.1",
66
- "@cspell/filetypes": "8.14.1",
67
- "@cspell/strong-weak-map": "8.14.1",
68
- "@cspell/url": "8.14.1",
62
+ "@cspell/cspell-bundled-dicts": "8.14.3",
63
+ "@cspell/cspell-pipe": "8.14.3",
64
+ "@cspell/cspell-resolver": "8.14.3",
65
+ "@cspell/cspell-types": "8.14.3",
66
+ "@cspell/dynamic-import": "8.14.3",
67
+ "@cspell/filetypes": "8.14.3",
68
+ "@cspell/strong-weak-map": "8.14.3",
69
+ "@cspell/url": "8.14.3",
69
70
  "clear-module": "^4.1.2",
70
71
  "comment-json": "^4.2.5",
71
- "cspell-config-lib": "8.14.1",
72
- "cspell-dictionary": "8.14.1",
73
- "cspell-glob": "8.14.1",
74
- "cspell-grammar": "8.14.1",
75
- "cspell-io": "8.14.1",
76
- "cspell-trie-lib": "8.14.1",
72
+ "cspell-config-lib": "8.14.3",
73
+ "cspell-dictionary": "8.14.3",
74
+ "cspell-glob": "8.14.3",
75
+ "cspell-grammar": "8.14.3",
76
+ "cspell-io": "8.14.3",
77
+ "cspell-trie-lib": "8.14.3",
77
78
  "env-paths": "^3.0.0",
78
79
  "fast-equals": "^5.0.1",
79
80
  "gensequence": "^7.0.0",
@@ -87,14 +88,14 @@
87
88
  "node": ">=18"
88
89
  },
89
90
  "devDependencies": {
90
- "@cspell/dict-cpp": "^5.1.12",
91
+ "@cspell/dict-cpp": "^5.1.16",
91
92
  "@cspell/dict-csharp": "^4.0.2",
92
93
  "@cspell/dict-css": "^4.0.13",
93
94
  "@cspell/dict-fa-ir": "^4.0.0",
94
95
  "@cspell/dict-fr-fr": "^2.2.2",
95
96
  "@cspell/dict-html": "^4.0.5",
96
97
  "@cspell/dict-nl-nl": "^2.3.0",
97
- "@cspell/dict-python": "^4.2.4",
98
+ "@cspell/dict-python": "^4.2.6",
98
99
  "@types/configstore": "^6.0.2",
99
100
  "configstore": "^7.0.0",
100
101
  "cspell-dict-nl-nl": "^1.1.2",
@@ -102,5 +103,5 @@
102
103
  "lorem-ipsum": "^2.0.8",
103
104
  "perf-insight": "^1.2.0"
104
105
  },
105
- "gitHead": "5552bdba15adc8c073dd33791f30329147c5c64b"
106
+ "gitHead": "ce996377857f5d7c3e70f27fc512afbe605562f8"
106
107
  }