• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

streetsidesoftware / cspell / 15428360260

03 Jun 2025 09:35PM UTC coverage: 92.362% (-0.8%) from 93.187%
15428360260

Pull #7414

github

web-flow
Merge b37bef57d into 6e3c5d0e0
Pull Request #7414: fix: Add init command to command-line.

12857 of 15175 branches covered (84.72%)

210 of 382 new or added lines in 13 files covered. (54.97%)

2 existing lines in 1 file now uncovered.

15828 of 17137 relevant lines covered (92.36%)

30059.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.52
/packages/cspell-config-lib/src/CSpellConfigFile.ts
1
import type { CSpellSettings } from '@cspell/cspell-types';
2

3
import type { ValueOf1 } from './types.js';
4
import type { RCfgNode } from './UpdateConfig/CfgTree.js';
5

6
export type { CfgNode } from './UpdateConfig/CfgTree.js';
7

8
export interface CSpellConfigFileReference {
9
    readonly url: URL;
10
}
11

12
export interface ICSpellConfigFile {
13
    /**
14
     * The url of the config file, used to resolve imports.
15
     */
16
    readonly url: URL;
17
    /**
18
     * The settings from the config file.
19
     */
20
    readonly settings: CSpellSettings;
21
    /**
22
     * Indicate that the config file is readonly.
23
     */
24
    readonly?: boolean;
25
    /**
26
     * Indicate that the config file is virtual and not associated with a file on disk.
27
     */
28
    virtual?: boolean;
29
    /**
30
     * Indicate that the config file is remote and not associated with a file on disk.
31
     */
32
    remote?: boolean;
33
}
34

35
export abstract class CSpellConfigFile implements ICSpellConfigFile {
36
    constructor(readonly url: URL) {}
106✔
37

38
    /**
39
     * The settings from the config file.
40
     * Note: this is a copy of the settings from the config file. It should be treated as immutable.
41
     * For performance reasons, it might not be frozen.
42
     */
43
    abstract readonly settings: CSpellSettings;
44

45
    /**
46
     * Helper function to add words to the config file.
47
     * @param words - words to add to the config file.
48
     */
49
    abstract addWords(words: string[]): this;
50

51
    /**
52
     * Tell the config file to remove all comments.
53
     * This is useful when the config file is being serialized and comments are not needed.
54
     * @returns this - the config file.
55
     */
56
    abstract removeAllComments(): this;
57

58
    /**
59
     * Configure the jason.schema for the config file.
60
     * @param schema - The schema to set for the config file.
61
     */
62
    abstract setSchema(schema: string): this;
63

64
    abstract setValue<K extends keyof CSpellSettings>(key: K, value: CSpellSettings[K]): this;
65

66
    /**
67
     *
68
     * @param key - the field to set the comment for.
69
     * @param comment - the comment to set.
70
     * @param inline - if true, the comment will be set as an inline comment.
71
     */
72
    abstract setComment(key: keyof CSpellSettings, comment: string, inline?: boolean): this;
73

74
    get readonly(): boolean {
75
        return this.settings.readonly || this.url.protocol !== 'file:';
13✔
76
    }
77

78
    get virtual(): boolean {
79
        return false;
1✔
80
    }
81

82
    get remote(): boolean {
83
        return this.url.protocol !== 'file:';
3✔
84
    }
85
}
86

87
type S = CSpellSettings;
88

89
export abstract class MutableCSpellConfigFile extends CSpellConfigFile {
90
    /**
91
     * Helper function to add words to the config file.
92
     * @param words - words to add to the config file.
93
     */
94
    abstract addWords(words: string[]): this;
95

96
    abstract setValue<K extends keyof S>(key: K, value: ValueOf1<S, K>): this;
97
    abstract getValue<K extends keyof S>(key: K): ValueOf1<S, K> | undefined;
98
    abstract getNode<K extends keyof S>(key: K): RCfgNode<ValueOf1<S, K>> | undefined;
99
    abstract getNode<K extends keyof S>(
100
        key: K,
101
        defaultValue: Exclude<ValueOf1<S, K>, undefined>,
102
    ): Exclude<RCfgNode<ValueOf1<S, K>>, undefined>;
103
    abstract getNode<K extends keyof S>(
104
        key: K,
105
        defaultValue: ValueOf1<S, K> | undefined,
106
    ): RCfgNode<ValueOf1<S, K>> | undefined;
107
}
108

109
export abstract class ImplCSpellConfigFile extends CSpellConfigFile {
110
    constructor(
111
        readonly url: URL,
78✔
112
        readonly settings: CSpellSettings,
78✔
113
    ) {
114
        super(url);
78✔
115
    }
116

117
    setSchema(_schema: string): this {
NEW
118
        return this;
×
119
    }
120

121
    removeAllComments(): this {
NEW
122
        if (this.readonly) {
×
NEW
123
            throw new Error(`Config file is readonly: ${this.url.href}`);
×
124
        }
125
        // do nothing
NEW
126
        return this;
×
127
    }
128

129
    addWords(words: string[]): this {
130
        if (this.readonly) throw new Error(`Config file is readonly: ${this.url.href}`);
5✔
131
        const w = this.settings.words || [];
4✔
132
        this.settings.words = w;
4✔
133
        addUniqueWordsToListAndSort(w, words);
4✔
134
        return this;
4✔
135
    }
136

137
    setComment(_key: keyof CSpellSettings, _comment: string, _inline?: boolean): this {
NEW
138
        if (this.readonly) throw new Error(`Config file is readonly: ${this.url.href}`);
×
139
        // do nothing
NEW
140
        return this;
×
141
    }
142

143
    setValue<K extends keyof CSpellSettings>(key: K, value: CSpellSettings[K]): this {
NEW
144
        if (this.readonly) throw new Error(`Config file is readonly: ${this.url.href}`);
×
NEW
145
        this.settings[key] = value;
×
NEW
146
        return this;
×
147
    }
148
}
149

150
/**
151
 * Adds words to a list, sorts the list and makes sure it is unique.
152
 * Note: this method is used to try and preserve comments in the config file.
153
 * @param list - list to be modified
154
 * @param toAdd - words to add
155
 */
156
function addUniqueWordsToListAndSort(list: string[], toAdd: string[]): void {
157
    list.push(...toAdd);
8✔
158
    list.sort();
8✔
159
    for (let i = 1; i < list.length; ++i) {
8✔
160
        if (list[i] === list[i - 1]) {
20✔
161
            list.splice(i, 1);
4✔
162
            --i;
4✔
163
        }
164
    }
165
}
166

167
export function satisfiesCSpellConfigFile(obj: unknown): obj is ICSpellConfigFile {
168
    const r: boolean =
169
        obj instanceof CSpellConfigFile ||
×
170
        (!!obj &&
171
            typeof obj === 'object' &&
172
            'url' in obj &&
173
            obj.url instanceof URL &&
174
            'settings' in obj &&
175
            !!obj.settings &&
176
            typeof obj.settings === 'object');
177
    return r;
×
178
}
179

180
export const cspellConfigFileSchema =
181
    'https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json';
13✔
182

183
export const __testing__ = {
13✔
184
    addUniqueWordsToListAndSort,
185
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc