@cspell/eslint-plugin 6.24.0 → 6.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,6 +23,12 @@ This plugin is still in active development as part of the CSpell suite of tools
23
23
 
24
24
  ````ts
25
25
  interface Options {
26
+ /**
27
+ * Automatically fix common mistakes.
28
+ * This is only possible if a single preferred suggestion is available.
29
+ * @default false
30
+ */
31
+ autoFix: boolean;
26
32
  /**
27
33
  * Number of spelling suggestions to make.
28
34
  * @default 8
@@ -99,11 +105,37 @@ Example:
99
105
  {
100
106
  "plugins": ["@cspell"],
101
107
  "rules": {
102
- "@cspell/spellchecker": ["warn", { "checkComments": false }]
108
+ "@cspell/spellchecker": ["warn", { "checkComments": false, "autoFix": true }]
103
109
  }
104
110
  }
105
111
  ```
106
112
 
113
+ ## `autoFix`
114
+
115
+ When enabled, `autoFix` corrects any spelling issues that have a single "preferred" suggestion. It attempts to match
116
+ case and style, but it cannot guarantee correctness of code.
117
+
118
+ ### Preferred Suggestions
119
+
120
+ CSpell offers the ability to flag words as incorrect and to provide suggestions.
121
+
122
+ **`cspell.config.yaml`**
123
+
124
+ ```yaml
125
+ words:
126
+ - allowlist
127
+ flagWords:
128
+ - blacklist->allowlist
129
+ suggestWords:
130
+ - colour->color
131
+ ```
132
+
133
+ With this configuration, `blacklist` is flagged as forbidden and `allowlist` is the "preferred" suggestion. When `autoFix` is enabled, all instances of `blacklist` will be replaced with `allowlist`.
134
+
135
+ When spell checking, if `colour` is not in one of the dictionaries, then `color` will be offered as the preferred suggestion. `suggestWords` are used to provide preferred suggestions, but will not flag any words as incorrect.
136
+
137
+ CSpell will match case, but not word stems. `blacklist` and `Blacklist` will get replaced, but not `blacklists`.
138
+
107
139
  ## In Combination with CSpell
108
140
 
109
141
  Due to the nature of how files are parsed, the `cspell` command line tool and this ESLint plugin will give different results.
@@ -116,8 +148,32 @@ Differences:
116
148
 
117
149
  - The CSpell ESLint plugin uses the [AST](https://dev.to/akshay9677/what-the-heck-is-an-abstract-syntax-tree-ast--3kk5) (a way to identify the meaning of the individual parts of your code) provided by ESLint to only check literal strings, identifiers, and comments. See [Options](#options) on selecting what to check.
118
150
 
119
- Example spell checked with ESLint CSpell Plugin:
120
- <img width="749" alt="image" src="https://user-images.githubusercontent.com/3740137/216295162-38ddf6a0-3873-4e48-b3a5-65fd421dae94.png">
151
+ Example spell checked with ESLint CSpell Plugin: <img width="749" alt="image" src="https://user-images.githubusercontent.com/3740137/216295162-38ddf6a0-3873-4e48-b3a5-65fd421dae94.png">
152
+
153
+ Example spell checked with just `cspell`: <img width="744" alt="image" src="https://user-images.githubusercontent.com/3740137/216295368-024c1065-2432-4d10-b204-7eb0589695e6.png">
154
+
155
+ ## CSpell for Enterprise
156
+
157
+ <!--- @@inject: ../../static/tidelift.md --->
158
+
159
+ Available as part of the Tidelift Subscription.
160
+
161
+ The maintainers of cspell and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-cspell?utm_source=npm-cspell&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
162
+
163
+ <!--- @@inject-end: ../../static/tidelift.md --->
164
+
165
+ <!--- @@inject: ../../static/footer.md --->
166
+
167
+ <br/>
168
+
169
+ ---
170
+
171
+ <p align="center">
172
+ Brought to you by <a href="https://streetsidesoftware.com" title="Street Side Software">
173
+ <img width="16" alt="Street Side Software Logo" src="https://i.imgur.com/CyduuVY.png" /> Street Side Software
174
+ </a>
175
+ </p>
176
+
177
+ <!--- @@inject-end: ../../static/footer.md --->
121
178
 
122
- Example spell checked with just `cspell`:
123
- <img width="744" alt="image" src="https://user-images.githubusercontent.com/3740137/216295368-024c1065-2432-4d10-b204-7eb0589695e6.png">
179
+ <!--- cspell:ignore colour --->
@@ -3,6 +3,11 @@
3
3
  "additionalProperties": false,
4
4
  "definitions": {},
5
5
  "properties": {
6
+ "autoFix": {
7
+ "default": false,
8
+ "description": "Automatically fix common mistakes. This is only possible if a single preferred suggestion is available.",
9
+ "type": "boolean"
10
+ },
6
11
  "checkComments": {
7
12
  "default": true,
8
13
  "description": "Spell check comments",
@@ -78,7 +83,8 @@
78
83
  },
79
84
  "required": [
80
85
  "numSuggestions",
81
- "generateSuggestions"
86
+ "generateSuggestions",
87
+ "autoFix"
82
88
  ],
83
89
  "type": "object"
84
90
  }
@@ -9,6 +9,12 @@ export interface Options extends Check {
9
9
  * @default true
10
10
  */
11
11
  generateSuggestions: boolean;
12
+ /**
13
+ * Automatically fix common mistakes.
14
+ * This is only possible if a single preferred suggestion is available.
15
+ * @default false
16
+ */
17
+ autoFix: boolean;
12
18
  /**
13
19
  * Output debug logs
14
20
  * @default false
@@ -12,8 +12,7 @@ const spellCheck = (0, synckit_1.createSyncFn)(require.resolve('../worker/worker
12
12
  const messages = {
13
13
  wordUnknown: 'Unknown word: "{{word}}"',
14
14
  wordForbidden: 'Forbidden word: "{{word}}"',
15
- suggestWord: '{{word}}',
16
- addWordToDictionary: 'Add "{{word}}" to {{dictionary}}',
15
+ suggestWord: '{{word}}{{preferred}}',
17
16
  };
18
17
  const meta = {
19
18
  docs: {
@@ -23,6 +22,7 @@ const meta = {
23
22
  },
24
23
  messages,
25
24
  hasSuggestions: true,
25
+ fixable: 'code',
26
26
  schema: [schema],
27
27
  };
28
28
  let isDebugMode = false;
@@ -31,8 +31,12 @@ function log(...args) {
31
31
  return;
32
32
  console.log(...args);
33
33
  }
34
+ function nullFix() {
35
+ return null;
36
+ }
34
37
  function create(context) {
35
38
  const options = (0, defaultCheckOptions_1.normalizeOptions)(context.options[0], context.getCwd());
39
+ const autoFix = options.autoFix;
36
40
  isDebugMode = options.debugMode || false;
37
41
  isDebugMode && logContext(context);
38
42
  function reportIssue(issue) {
@@ -48,8 +52,10 @@ function create(context) {
48
52
  function fixFactory(word) {
49
53
  return (fixer) => fixer.replaceTextRange([start, end], word);
50
54
  }
51
- function createSug(word) {
52
- const data = { word };
55
+ function createSug(sug) {
56
+ const word = sug.wordAdjustedToMatchCase || sug.word;
57
+ const preferred = sug.isPreferred ? '*' : '';
58
+ const data = { word, preferred };
53
59
  const messageId = 'suggestWord';
54
60
  return {
55
61
  messageId,
@@ -58,13 +64,20 @@ function create(context) {
58
64
  };
59
65
  }
60
66
  log('Suggestions: %o', issue.suggestions);
61
- const suggestions = issue.suggestions?.map(createSug);
67
+ const fixable = issue.suggestionsEx?.filter((sug) => !!sug.isPreferred);
68
+ const canFix = fixable?.length === 1;
69
+ const preferredSuggestion = autoFix && canFix && fixable[0];
70
+ const fix = preferredSuggestion
71
+ ? fixFactory(preferredSuggestion.wordAdjustedToMatchCase || preferredSuggestion.word)
72
+ : nullFix;
73
+ const suggestions = issue.suggestionsEx?.map((sug) => createSug(sug));
62
74
  const suggest = suggestions;
63
75
  const des = {
64
76
  messageId,
65
77
  data,
66
78
  loc,
67
79
  suggest,
80
+ fix,
68
81
  };
69
82
  context.report(des);
70
83
  }
@@ -16,6 +16,7 @@ exports.defaultOptions = {
16
16
  numSuggestions: 8,
17
17
  generateSuggestions: true,
18
18
  debugMode: false,
19
+ autoFix: false,
19
20
  };
20
21
  function normalizeOptions(opts, cwd) {
21
22
  const options = Object.assign({}, exports.defaultOptions, opts || {}, { cwd });
@@ -1,3 +1,4 @@
1
+ import type { ValidationIssue } from 'cspell-lib';
1
2
  import type { Node } from 'estree';
2
3
  import type { WorkerOptions } from '../common/options.js';
3
4
  export interface Issue {
@@ -6,6 +7,7 @@ export interface Issue {
6
7
  word: string;
7
8
  severity: 'Forbidden' | 'Unknown' | 'Hint';
8
9
  suggestions: string[] | undefined;
10
+ suggestionsEx: ValidationIssue['suggestionsEx'];
9
11
  }
10
12
  type SpellCheckFn = typeof spellCheck;
11
13
  export type SpellCheckSyncFn = (...p: Parameters<SpellCheckFn>) => Awaited<ReturnType<SpellCheckFn>>;
@@ -154,8 +154,9 @@ export async function spellCheck(filename, text, root, options) {
154
154
  const start = issue.offset;
155
155
  const end = issue.offset + (issue.length || issue.text.length);
156
156
  const suggestions = issue.suggestions;
157
+ const suggestionsEx = issue.suggestionsEx;
157
158
  const severity = issue.isFlagged ? 'Forbidden' : 'Unknown';
158
- issues.push({ word, start, end, suggestions, severity });
159
+ issues.push({ word, start, end, suggestions, suggestionsEx, severity });
159
160
  }
160
161
  const processors = {
161
162
  Line: checkComment,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "6.24.0",
6
+ "version": "6.26.0",
7
7
  "description": "CSpell ESLint plugin",
8
8
  "keywords": [
9
9
  "cspell",
@@ -54,21 +54,21 @@
54
54
  "node": ">=14"
55
55
  },
56
56
  "devDependencies": {
57
- "@types/eslint": "^8.21.0",
57
+ "@types/eslint": "^8.21.1",
58
58
  "@types/estree": "^1.0.0",
59
59
  "@types/node": "^18.13.0",
60
- "@typescript-eslint/parser": "^5.51.0",
61
- "@typescript-eslint/types": "^5.51.0",
62
- "@typescript-eslint/typescript-estree": "^5.51.0",
60
+ "@typescript-eslint/parser": "^5.52.0",
61
+ "@typescript-eslint/types": "^5.52.0",
62
+ "@typescript-eslint/typescript-estree": "^5.52.0",
63
63
  "eslint": "^8.34.0",
64
64
  "eslint-plugin-react": "^7.32.2",
65
65
  "mocha": "^10.2.0",
66
66
  "ts-json-schema-generator": "^1.2.0"
67
67
  },
68
68
  "dependencies": {
69
- "cspell-lib": "6.24.0",
69
+ "cspell-lib": "6.26.0",
70
70
  "estree-walker": "^3.0.3",
71
71
  "synckit": "^0.8.5"
72
72
  },
73
- "gitHead": "0d1e8bf9426cd0bfb814df4f61da12d8aee57ddd"
73
+ "gitHead": "a72f603f4f1afbe237f938b1a23d7cbe2a07d86f"
74
74
  }