Skip to content

Commit

Permalink
fix: Be able to disable the default configuration (#2643)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S committed Apr 1, 2022
1 parent ba244d9 commit 46c1e4f
Show file tree
Hide file tree
Showing 39 changed files with 221 additions and 76 deletions.
10 changes: 10 additions & 0 deletions cspell.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,11 @@
},
"type": "array"
},
"loadDefaultConfiguration": {
"default": "true;",
"description": "By default, the bundled dictionary configurations are loaded. Explicitly setting this to `false` will prevent ALL default configuration from being loaded.",
"type": "boolean"
},
"maxDuplicateProblems": {
"default": 5,
"description": "The maximum number of times the same word can be flagged as an error in a file.",
Expand Down Expand Up @@ -1317,6 +1322,11 @@
},
"type": "array"
},
"loadDefaultConfiguration": {
"default": "true;",
"description": "By default, the bundled dictionary configurations are loaded. Explicitly setting this to `false` will prevent ALL default configuration from being loaded.",
"type": "boolean"
},
"maxDuplicateProblems": {
"default": 5,
"description": "The maximum number of times the same word can be flagged as an error in a file.",
Expand Down
5 changes: 3 additions & 2 deletions packages/cspell-lib/api/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ interface ConfigurationDependencies {
}
declare function extractDependencies(settings: CSpellSettingsWSTO | CSpellSettingsI): ConfigurationDependencies;

declare function getDefaultSettings(): CSpellSettingsInternal;
declare function getDefaultSettings(useDefaultDictionaries?: boolean): CSpellSettingsInternal;
declare function getDefaultBundledSettings(): CSpellSettingsInternal;

declare class ImportError extends Error {
readonly cause: Error | undefined;
Expand Down Expand Up @@ -797,4 +798,4 @@ declare function resolveFile(filename: string, relativeTo: string): ResolveFileR
declare function clearCachedFiles(): Promise<void>;
declare function getDictionary(settings: CSpellUserSettings): Promise<SpellingDictionaryCollection>;

export { CheckTextInfo, ConfigurationDependencies, CreateTextDocumentParams, DetermineFinalDocumentSettingsResult, Document, DocumentValidator, DocumentValidatorOptions, ENV_CSPELL_GLOB_ROOT, ExcludeFilesGlobMap, ExclusionFunction, exclusionHelper_d as ExclusionHelper, ImportError, ImportFileRefWithError, IncludeExcludeFlag, IncludeExcludeOptions, index_link_d as Link, Logger, SpellCheckFileOptions, SpellCheckFileResult, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryLoadError, SuggestOptions, SuggestedWord, SuggestionError, SuggestionOptions, SuggestionsForWordResult, text_d as Text, TextDocument, TextDocumentLine, TextInfoItem, TraceOptions, TraceResult, ValidationIssue, calcOverrideSettings, checkFilenameMatchesGlob, checkText, clearCachedFiles, clearCachedSettingsFiles, combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, createSpellingDictionary, createTextDocument, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, defaultFileName as defaultSettingsFilename, determineFinalDocumentSettings, extractDependencies, extractImportErrors, fileToDocument, finalizeSettings, getCachedFileSize, getDefaultSettings, getDictionary, getGlobalSettings, getLanguagesForExt, getLogger, getSources, isBinaryFile, isSpellingDictionaryLoadError, loadConfig, loadPnP, loadPnPSync, mergeInDocSettings, mergeSettings, readRawSettings, readSettings, readSettingsFiles, refreshDictionaryCache, resolveFile, searchForConfig, sectionCSpell, setLogger, spellCheckDocument, spellCheckFile, suggestionsForWord, suggestionsForWords, traceWords, traceWordsAsync, updateTextDocument, validateText };
export { CheckTextInfo, ConfigurationDependencies, CreateTextDocumentParams, DetermineFinalDocumentSettingsResult, Document, DocumentValidator, DocumentValidatorOptions, ENV_CSPELL_GLOB_ROOT, ExcludeFilesGlobMap, ExclusionFunction, exclusionHelper_d as ExclusionHelper, ImportError, ImportFileRefWithError, IncludeExcludeFlag, IncludeExcludeOptions, index_link_d as Link, Logger, SpellCheckFileOptions, SpellCheckFileResult, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryLoadError, SuggestOptions, SuggestedWord, SuggestionError, SuggestionOptions, SuggestionsForWordResult, text_d as Text, TextDocument, TextDocumentLine, TextInfoItem, TraceOptions, TraceResult, ValidationIssue, calcOverrideSettings, checkFilenameMatchesGlob, checkText, clearCachedFiles, clearCachedSettingsFiles, combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, createSpellingDictionary, createTextDocument, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, defaultFileName as defaultSettingsFilename, determineFinalDocumentSettings, extractDependencies, extractImportErrors, fileToDocument, finalizeSettings, getCachedFileSize, getDefaultBundledSettings, getDefaultSettings, getDictionary, getGlobalSettings, getLanguagesForExt, getLogger, getSources, isBinaryFile, isSpellingDictionaryLoadError, loadConfig, loadPnP, loadPnPSync, mergeInDocSettings, mergeSettings, readRawSettings, readSettings, readSettingsFiles, refreshDictionaryCache, resolveFile, searchForConfig, sectionCSpell, setLogger, spellCheckDocument, spellCheckFile, suggestionsForWord, suggestionsForWords, traceWords, traceWordsAsync, updateTextDocument, validateText };
13 changes: 13 additions & 0 deletions packages/cspell-lib/src/Models/PatternRegExp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PatternRegExp } from './PatternRegExp';

describe('Pattern', () => {
test.each`
pattern | expected
${/\b\w+/gi} | ${/\b\w+/gi}
${'.*'} | ${/.*/}
`('pattern $pattern', ({ pattern, expected }) => {
const pat = new PatternRegExp(pattern);
expect(JSON.stringify(pat)).toEqual(JSON.stringify(expected.toString()));
expect(pat).toEqual(expected);
});
});
9 changes: 9 additions & 0 deletions packages/cspell-lib/src/Models/PatternRegExp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class PatternRegExp extends RegExp {
constructor(pattern: RegExp | string) {
super(pattern);
}

toJSON() {
return this.toString();
}
}
8 changes: 4 additions & 4 deletions packages/cspell-lib/src/Settings/CSpellSettingsServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
__testing__ as __configLoader_testing__,
} from './configLoader';
import { calcOverrideSettings, checkFilenameMatchesGlob, getSources, mergeSettings } from './CSpellSettingsServer';
import { getDefaultSettings, _defaultSettings } from './DefaultSettings';
import { getDefaultBundledSettings, _defaultSettings } from './DefaultSettings';

const rootCspellLib = path.resolve(path.join(__dirname, '../..'));
const samplesDir = path.resolve(rootCspellLib, 'samples');
Expand Down Expand Up @@ -246,19 +246,19 @@ describe('Validate CSpellSettingsServer', () => {
test('makes sure global settings is an object', () => {
const settings = getGlobalSettings();
expect(Object.keys(settings)).not.toHaveLength(0);
const merged = mergeSettings(getDefaultSettings(), getGlobalSettings());
const merged = mergeSettings(getDefaultBundledSettings(), getGlobalSettings());
expect(Object.keys(merged)).not.toHaveLength(0);
});

test('verify clearing the file cache works', () => {
mergeSettings(getDefaultSettings(), getGlobalSettings());
mergeSettings(getDefaultBundledSettings(), getGlobalSettings());
expect(getCachedFileSize()).toBeGreaterThan(0);
clearCachedSettingsFiles();
expect(getCachedFileSize()).toBe(0);
});

test('the loaded defaults contain expected settings', () => {
const settings = getDefaultSettings();
const settings = getDefaultBundledSettings();
const sources = getSources(settings);
const sourceNames = sources.map((s) => s.name || '?');
expect(sourceNames).toEqual(expect.arrayContaining([_defaultSettings.name]));
Expand Down
6 changes: 5 additions & 1 deletion packages/cspell-lib/src/Settings/DefaultSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ describe('Validate Default Settings', () => {
});

test('tests the default setting file is loaded', () => {
const defaultSetting = DefaultSettings.getDefaultSettings();
const defaultSetting = DefaultSettings.getDefaultBundledSettings();
expect(defaultSetting.name).toBe('cspell default settings');
});

test('default', () => {
expect(DefaultSettings.getDefaultBundledSettings()).toEqual(DefaultSettings.getDefaultSettings(undefined));
});
});
66 changes: 47 additions & 19 deletions packages/cspell-lib/src/Settings/DefaultSettings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { PredefinedPatterns, RegExpPatternDefinition } from '@cspell/cspell-types';
import { createCSpellSettingsInternal, CSpellSettingsInternal } from '../Models/CSpellSettingsInternalDef';
import { PatternRegExp } from '../Models/PatternRegExp';
import { resolveFile } from '../util/resolveFile';
import { readSettings } from './configLoader';
import { mergeSettings } from './index';
Expand All @@ -12,9 +13,9 @@ const defaultConfigFileModuleRef = '@cspell/cspell-bundled-dicts/cspell-default.
const defaultConfigFile = resolveConfigModule(defaultConfigFileModuleRef);

const regExpSpellCheckerDisable = [
RegPat.regExSpellingGuardBlock,
RegPat.regExSpellingGuardLine,
RegPat.regExSpellingGuardNext,
new PatternRegExp(RegPat.regExSpellingGuardBlock),
new PatternRegExp(RegPat.regExSpellingGuardLine),
new PatternRegExp(RegPat.regExSpellingGuardNext),
];

// cspell:ignore filetypes
Expand Down Expand Up @@ -58,7 +59,7 @@ type ExtendsType<T, U> = T extends U ? T : never;

type PredefinedPatternNames = ExtendsType<NameType<typeof predefinedPatterns>, PredefinedPatterns>;

const defaultRegExpPatterns: RegExpPatternDefinition[] = [...predefinedPatterns];
const defaultRegExpPatterns: RegExpPatternDefinition[] = [...predefinedPatterns].map(normalizePattern);

const definedDefaultRegExpExcludeList: PredefinedPatterns[] = [
'SpellCheckerDisable',
Expand All @@ -82,12 +83,32 @@ const definedDefaultRegExpExcludeList: PredefinedPatterns[] = [
// This bit of copying is done to have the complier ensure that the defaults exist.
const defaultRegExpExcludeList: PredefinedPatternNames[] = definedDefaultRegExpExcludeList;

export const _defaultSettings: Readonly<CSpellSettingsInternal> = Object.freeze(
export const _defaultSettingsBasis: Readonly<CSpellSettingsInternal> = Object.freeze(
createCSpellSettingsInternal({
id: 'static_defaults',
language: 'en',
name: 'Static Defaults',
enabled: true,
enabledLanguageIds: [],
maxNumberOfProblems: 100,
numSuggestions: 10,
suggestionsTimeout: 500,
suggestionNumChanges: 3,
words: [],
userWords: [],
ignorePaths: [],
allowCompoundWords: false,
patterns: defaultRegExpPatterns,
ignoreRegExpList: [],
languageSettings: [],
source: { name: 'defaultSettings' },
reporters: [],
})
);

export const _defaultSettings: Readonly<CSpellSettingsInternal> = Object.freeze(
createCSpellSettingsInternal({
..._defaultSettingsBasis,
enabledLanguageIds: [
'ada',
'csharp',
Expand All @@ -114,25 +135,17 @@ export const _defaultSettings: Readonly<CSpellSettingsInternal> = Object.freeze(
'shellscript',
'toml',
],
maxNumberOfProblems: 100,
numSuggestions: 10,
suggestionsTimeout: 500,
suggestionNumChanges: 3,
words: [],
userWords: [],
ignorePaths: [],
allowCompoundWords: false,
patterns: defaultRegExpPatterns,
ignoreRegExpList: defaultRegExpExcludeList,
languageSettings: LanguageSettings.getDefaultLanguageSettings(),
source: { name: 'defaultSettings' },
reporters: [],
})
);

const getSettings = (function () {
let settings: CSpellSettingsInternal | undefined = undefined;
return function () {
return function (useDefaultDictionaries: boolean) {
if (!useDefaultDictionaries) {
return _defaultSettingsBasis;
}
if (!settings) {
const jsonSettings = readSettings(defaultConfigFile);
settings = mergeSettings(_defaultSettings, jsonSettings);
Expand All @@ -150,6 +163,21 @@ function resolveConfigModule(configModuleName: string) {
return resolveFile(configModuleName, __dirname).filename;
}

export function getDefaultSettings(): CSpellSettingsInternal {
return getSettings();
function normalizePattern(pat: RegExpPatternDefinition): RegExpPatternDefinition {
const { name, pattern, description } = pat;
if (!(pattern instanceof RegExp)) return pat;

return {
name,
pattern: new PatternRegExp(pattern),
description,
};
}

export function getDefaultSettings(useDefaultDictionaries = true): CSpellSettingsInternal {
return getSettings(useDefaultDictionaries);
}

export function getDefaultBundledSettings(): CSpellSettingsInternal {
return getDefaultSettings();
}
4 changes: 2 additions & 2 deletions packages/cspell-lib/src/Settings/DictionarySettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import type { DictionaryDefinition, DictionaryDefinitionLegacy } from '@cspell/c
import * as fsp from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { getDefaultSettings } from './DefaultSettings';
import { getDefaultBundledSettings } from './DefaultSettings';
import { createDictionaryReferenceCollection as createRefCol } from './DictionaryReferenceCollection';
import * as DictSettings from './DictionarySettings';

const defaultSettings = getDefaultSettings();
const defaultSettings = getDefaultBundledSettings();
const oc = expect.objectContaining;

describe('Validate DictionarySettings', () => {
Expand Down
8 changes: 4 additions & 4 deletions packages/cspell-lib/src/Settings/LanguageSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { CSpellUserSettings } from '@cspell/cspell-types';
import { getGlobalSettings } from './configLoader';
import { mergeSettings } from './CSpellSettingsServer';
import { getDefaultSettings } from './DefaultSettings';
import { getDefaultBundledSettings } from './DefaultSettings';
import * as LS from './LanguageSettings';
import { calcSettingsForLanguage, calcUserSettingsForLanguage } from './LanguageSettings';

Expand All @@ -25,12 +25,12 @@ const extraSettings: CSpellUserSettings = {
],
};

const defaultSettings = getDefaultSettings();
const defaultSettings = getDefaultBundledSettings();
const defaultLanguageSettings = defaultSettings.languageSettings;

describe('Validate LanguageSettings', () => {
test('tests merging language settings', () => {
const defaultSettings = getDefaultSettings();
const defaultSettings = getDefaultBundledSettings();
const languageSettings = defaultSettings.languageSettings || [];
const sPython = calcSettingsForLanguage(languageSettings, 'python', 'en');
expect(sPython.allowCompoundWords).toBe(true);
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('Validate LanguageSettings', () => {
);

test('merged settings with global', () => {
const merged = mergeSettings(getDefaultSettings(), getGlobalSettings());
const merged = mergeSettings(getDefaultBundledSettings(), getGlobalSettings());
const sPHP = calcSettingsForLanguage(merged.languageSettings || [], 'php', 'en');
expect(Object.keys(sPHP)).not.toHaveLength(0);
});
Expand Down
8 changes: 4 additions & 4 deletions packages/cspell-lib/src/Settings/configLoader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
ImportFileRefWithError,
mergeSettings,
} from './CSpellSettingsServer';
import { getDefaultSettings, _defaultSettings } from './DefaultSettings';
import { getDefaultBundledSettings, _defaultSettings } from './DefaultSettings';

const { normalizeCacheSettings, normalizeSettings, validateRawConfigExports, validateRawConfigVersion } =
__configLoader_testing__;
Expand Down Expand Up @@ -103,19 +103,19 @@ describe('Validate CSpellSettingsServer', () => {
test('makes sure global settings is an object', () => {
const settings = getGlobalSettings();
expect(Object.keys(settings)).not.toHaveLength(0);
const merged = mergeSettings(getDefaultSettings(), getGlobalSettings());
const merged = mergeSettings(getDefaultBundledSettings(), getGlobalSettings());
expect(Object.keys(merged)).not.toHaveLength(0);
});

test('verify clearing the file cache works', () => {
mergeSettings(getDefaultSettings(), getGlobalSettings());
mergeSettings(getDefaultBundledSettings(), getGlobalSettings());
expect(getCachedFileSize()).toBeGreaterThan(0);
clearCachedSettingsFiles();
expect(getCachedFileSize()).toBe(0);
});

test('the loaded defaults contain expected settings', () => {
const settings = getDefaultSettings();
const settings = getDefaultBundledSettings();
const sources = getSources(settings);
const sourceNames = sources.map((s) => s.name || '?');
expect(sourceNames).toEqual(expect.arrayContaining([_defaultSettings.name]));
Expand Down
2 changes: 1 addition & 1 deletion packages/cspell-lib/src/Settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ export {
mergeSettings,
} from './CSpellSettingsServer';
export type { ConfigurationDependencies, ImportFileRefWithError } from './CSpellSettingsServer';
export { getDefaultSettings } from './DefaultSettings';
export { getDefaultSettings, getDefaultBundledSettings } from './DefaultSettings';
export { ImportError } from './ImportError';
12 changes: 6 additions & 6 deletions packages/cspell-lib/src/SpellingDictionary/Dictionaries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { CSpellUserSettings } from '@cspell/cspell-types';
import * as fs from 'fs-extra';
import * as path from 'path';
import { createCSpellSettingsInternal as csi } from '../Models/CSpellSettingsInternalDef';
import { getDefaultSettings, loadConfig } from '../Settings';
import { getDefaultBundledSettings, loadConfig } from '../Settings';
import { createDictionaryReferenceCollection } from '../Settings/DictionaryReferenceCollection';
import { filterDictDefsToLoad, mapDictDefToInternal } from '../Settings/DictionarySettings';
import * as Dictionaries from './Dictionaries';
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('Validate getDictionary', () => {
${'snarf'} | ${ignoreCaseTrue} | ${false}
`('tests that userWords are included in the dictionary $word', async ({ word, opts, expected }) => {
const settings = csi({
...getDefaultSettings(),
...getDefaultBundledSettings(),
dictionaries: [],
words: ['one', 'two', 'three', 'café', '!snarf'],
userWords: ['four', 'five', 'six', 'Rhône'],
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('Validate getDictionary', () => {
${'colour'} | ${{ found: 'colour', forbidden: true, noSuggest: false }}
`('find words $word', async ({ word, expected }) => {
const settings = csi({
...getDefaultSettings(),
...getDefaultBundledSettings(),
noSuggestDictionaries: ['companies'],
words: ['one', 'two', 'three', 'café', '!snarf'],
userWords: ['four', 'five', 'six', 'Rhône'],
Expand Down Expand Up @@ -119,7 +119,7 @@ describe('Validate getDictionary', () => {
${'cafe'} | ${ignoreCaseTrue} | ${true}
`('Case sensitive "$word" $opts', async ({ word, opts, expected }) => {
const settings = {
...getDefaultSettings(),
...getDefaultBundledSettings(),
dictionaries: [],
words: ['one', 'two', 'three', 'café'],
userWords: ['four', 'five', 'six', 'Rhône'],
Expand Down Expand Up @@ -186,7 +186,7 @@ describe('Validate Refresh', () => {
const tempDictPathNotFound = tempPath('not-found.txt');
await fs.mkdirp(path.dirname(tempDictPath));
await fs.writeFile(tempDictPath, 'one\ntwo\nthree\n');
const settings = getDefaultSettings();
const settings = getDefaultBundledSettings();
const defs = (settings.dictionaryDefinitions || []).concat([
di({ name: 'temp', path: tempDictPath }, __filename),
di({ name: 'not_found', path: tempDictPathNotFound }, __filename),
Expand Down Expand Up @@ -234,7 +234,7 @@ describe('Validate Refresh', () => {
const tempDictPath = tempPath('words_sync.txt');
await fs.mkdirp(path.dirname(tempDictPath));
await fs.writeFile(tempDictPath, 'one\ntwo\nthree\n');
const settings = getDefaultSettings();
const settings = getDefaultBundledSettings();
const defs = (settings.dictionaryDefinitions || []).concat([
di({ name: 'temp', path: tempDictPath }, __filename),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class SpellingDictionaryCollection implements SpellingDictionary {

public _suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[] {
const {
numSuggestions = getDefaultSettings().numSuggestions || defaultNumSuggestions,
numSuggestions = getDefaultSettings(false).numSuggestions || defaultNumSuggestions,
numChanges,
ignoreCase,
includeTies,
Expand Down
Loading

0 comments on commit 46c1e4f

Please sign in to comment.