From 682de6a2d696335780324d0ceef88855a420ed59 Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Mon, 30 Oct 2023 11:33:20 +0100 Subject: [PATCH 1/3] refactor: Rename issueViewer --- packages/client/src/commands.ts | 6 ++++-- packages/client/src/issueViewer/index.ts | 2 +- .../client/src/issueViewer/{viewer.ts => issueViewer.ts} | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) rename packages/client/src/issueViewer/{viewer.ts => issueViewer.ts} (97%) diff --git a/packages/client/src/commands.ts b/packages/client/src/commands.ts index 64578d3dd..cab6db128 100644 --- a/packages/client/src/commands.ts +++ b/packages/client/src/commands.ts @@ -149,10 +149,12 @@ const commandHandlers = { 'cSpell.openFileAtLine': openFileAtLine, 'cSpell.selectRange': handleSelectRange, - 'cSpell.issueViewer.item.openSuggestionsForIssue': handlerResolvedLater, - 'cSpell.issueViewer.item.autoFixSpellingIssues': handlerResolvedLater, 'cSpell.fixSpellingIssue': handleFixSpellingIssue, 'cSpell.autoFixSpellingIssues': actionAutoFixSpellingIssues, + + 'cSpell.issueViewer.item.openSuggestionsForIssue': handlerResolvedLater, + 'cSpell.issueViewer.item.autoFixSpellingIssues': handlerResolvedLater, + 'cSpell.issueViewer.item.addWordToDictionary': handlerResolvedLater, } as const satisfies CommandHandler; type ImplementedCommandHandlers = typeof commandHandlers; diff --git a/packages/client/src/issueViewer/index.ts b/packages/client/src/issueViewer/index.ts index c6d1fbeda..c578294e6 100644 --- a/packages/client/src/issueViewer/index.ts +++ b/packages/client/src/issueViewer/index.ts @@ -1 +1 @@ -export { activate as activateIssueViewer } from './viewer'; +export { activate as activateIssueViewer } from './issueViewer'; diff --git a/packages/client/src/issueViewer/viewer.ts b/packages/client/src/issueViewer/issueViewer.ts similarity index 97% rename from packages/client/src/issueViewer/viewer.ts rename to packages/client/src/issueViewer/issueViewer.ts index 82ba3ff7c..d18264edc 100644 --- a/packages/client/src/issueViewer/viewer.ts +++ b/packages/client/src/issueViewer/issueViewer.ts @@ -18,6 +18,7 @@ export function activate(context: ExtensionContext, issueTracker: IssueTracker, context.subscriptions.push( vscode.commands.registerCommand(knownCommands['cSpell.issueViewer.item.openSuggestionsForIssue'], handleOpenSuggestionsForIssue), vscode.commands.registerCommand(knownCommands['cSpell.issueViewer.item.autoFixSpellingIssues'], handleAutoFixSpellingIssues), + vscode.commands.registerCommand(knownCommands['cSpell.issueViewer.item.addWordToDictionary'], handleAddWordToDictionary), ); } @@ -216,6 +217,8 @@ class IssueTreeItem extends IssueTreeItemBase { return handleFixSpellingIssue(this.context.document.uri, pref.text, pref.newText, pref.ranges); } + async addToDictionary() {} + private onUpdate(suggestions: Suggestion[]) { this.suggestions = suggestions; this.context.invalidate(this); @@ -392,6 +395,11 @@ function handleAutoFixSpellingIssues(item?: IssueTreeItem) { return item.autoFix(); } +function handleAddWordToDictionary(item?: IssueTreeItem) { + if (!(item instanceof IssueTreeItem)) return; + return item.addToDictionary(); +} + interface PreferredFix { text: string; newText: string; From 4e6c3e83a5272b44d0d8668edb56d3361586241e Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Tue, 31 Oct 2023 20:27:15 +0100 Subject: [PATCH 2/3] Improve the settings descripitons --- docs/_includes/generated-docs/commands.md | 1 + .../_includes/generated-docs/configuration.md | 44 ++- package.json | 323 ++++++++++++++++-- .../_server/spell-checker-config.schema.json | 320 ++++++++++++++--- .../CSpellSettingsPackageProperties.mts | 92 +---- .../config/cspellConfig/CustomDictionary.mts | 22 +- .../src/config/cspellConfig/cspellConfig.mts | 23 +- 7 files changed, 661 insertions(+), 164 deletions(-) diff --git a/docs/_includes/generated-docs/commands.md b/docs/_includes/generated-docs/commands.md index f4e2c6659..c02a5bb19 100644 --- a/docs/_includes/generated-docs/commands.md +++ b/docs/_includes/generated-docs/commands.md @@ -31,6 +31,7 @@ | `cSpell.goToNextSpellingIssueAndSuggest` | Go to Next Spelling Issue and Suggest | | `cSpell.goToPreviousSpellingIssue` | Go to Previous Spelling Issue | | `cSpell.goToPreviousSpellingIssueAndSuggest` | Go to Previous Spelling Issue and Suggest | +| `cSpell.issueViewer.item.addWordToDictionary` | Add Word to Dictionary
**When:**
`view == cspell-info.issuesView` | | `cSpell.issueViewer.item.autoFixSpellingIssues` | Fix issue with preferred suggestion in the current document.
**When:**
`view == cspell-info.issuesView` | | `cSpell.issueViewer.item.openSuggestionsForIssue` | Show Suggestions
**When:**
`view == cspell-info.issuesView` | | `cSpell.logPerfTimeline` | Log CSpell performance times to console | diff --git a/docs/_includes/generated-docs/configuration.md b/docs/_includes/generated-docs/configuration.md index 11a0f9ffc..63795182a 100644 --- a/docs/_includes/generated-docs/configuration.md +++ b/docs/_includes/generated-docs/configuration.md @@ -46,8 +46,8 @@ Default | -------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------- | | [`cSpell.caseSensitive`](#cspellcasesensitive) | resource | Determines if words must match case and accent rules. | | [`cSpell.customDictionaries`](#cspellcustomdictionaries) | resource | Custom Dictionaries | -| [`cSpell.dictionaries`](#cspelldictionaries) | resource | Optional list of dictionaries to use. Each entry should match the name of the dictionary. To… | -| [`cSpell.dictionaryDefinitions`](#cspelldictionarydefinitions) | resource | Define additional available dictionaries. | +| [`cSpell.dictionaries`](#cspelldictionaries) | resource | Optional list of dictionaries to use. | +| [`cSpell.dictionaryDefinitions`](#cspelldictionarydefinitions) | resource | Dictionary Definitions | | [`cSpell.flagWords`](#cspellflagwords) | resource | List of words to always be considered incorrect. Words found in `flagWords` override `words`. | | [`cSpell.ignoreWords`](#cspellignorewords) | resource | A list of words to be ignored by the spell checker. | | [`cSpell.language`](#cspelllanguage) | resource | Current active spelling language. | @@ -132,9 +132,19 @@ Scope Description : Optional list of dictionaries to use. -Each entry should match the name of the dictionary. -To remove a dictionary from the list add `!` before the name. -i.e. `!typescript` will turn off the dictionary with the name `typescript`. + + Each entry should match the name of the dictionary. + + To remove a dictionary from the list add `!` before the name. + i.e. `!typescript` will turn off the dictionary with the name `typescript`. + + + Example: + + ```jsonc + // Enable `lorem-ipsum` and disable `typescript` + "cSpell.dictionaries": ["lorem-ipsum", "!typescript"] + ``` Default : _- none -_ @@ -144,7 +154,7 @@ Default ### `cSpell.dictionaryDefinitions` Name -: `cSpell.dictionaryDefinitions` +: `cSpell.dictionaryDefinitions` -- Dictionary Definitions Type : [] @@ -153,7 +163,25 @@ Scope : resource Description -: Define additional available dictionaries. +: Define custom dictionaries.. +If `addWords` is `true` words will be added to this dictionary. + + This setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence). + + It is better to use `#cSpell.customDictionaries#` + + **Example:** + + ```js + "cSpell.dictionaryDefinitions": [ + { + "name": "project-words", + "path": "${workspaceRoot}/project-words.txt", + "description": "Words used in this project", + "addWords": true + } + ] + ``` Default : _- none -_ @@ -1289,7 +1317,7 @@ Description The default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode. - | VS Code UI | JSON | Description | + | VS Code UI | settings.json | Description | | :------------------ | :-------------------- | :------------------------------------------- | | `/\\[a-z]+/gi` | `/\\\\[a-z]+/gi` | Exclude LaTeX command like `\mapsto` | | `/\b[A-Z]{3,5}\b/g` | `/\\b[A-Z]{3,5}\\b/g` | Exclude full-caps acronyms of 3-5 length. | diff --git a/package.json b/package.json index 8a8e2faaf..8cbe6f457 100644 --- a/package.json +++ b/package.json @@ -167,6 +167,11 @@ "command": "cSpell.issueViewer.item.autoFixSpellingIssues", "when": "view == cspell-info.issuesView && viewItem == issue.hasPreferred", "group": "inline" + }, + { + "command": "cSpell.issueViewer.item.addWordToDictionary", + "when": "view == cspell-info.issuesView && viewItem == issue", + "group": "inline" } ] }, @@ -346,7 +351,8 @@ { "command": "cSpell.addWordToDictionary", "category": "Spell", - "title": "Add Words to Dictionary" + "title": "Add Words to Dictionary", + "icon": "$(book)" }, { "command": "cSpell.addWordToCSpellConfig", @@ -396,12 +402,19 @@ }, { "command": "cSpellRegExpTester.testRegExp", - "title": "Test a Regular Expression on the current document." + "title": "Test a Regular Expression on the current document.", + "enablement": "config.cSpell.experimental.enableRegexpView" }, { "command": "cSpellRegExpTester.editRegExp", "title": "Edit", - "icon": "$(edit)" + "icon": "$(edit)", + "enablement": "config.cSpell.experimental.enableRegexpView" + }, + { + "command": "cSpell.autoFixSpellingIssues", + "title": "Fix all issues with a preferred suggestion in the current document.", + "icon": "$(lightbulb-autofix)" }, { "command": "cSpell.issueViewer.item.openSuggestionsForIssue", @@ -409,16 +422,18 @@ "icon": "$(list-unordered)", "enablement": "view == cspell-info.issuesView" }, - { - "command": "cSpell.autoFixSpellingIssues", - "title": "Fix all issues with a preferred suggestion in the current document.", - "icon": "$(lightbulb-autofix)" - }, { "command": "cSpell.issueViewer.item.autoFixSpellingIssues", "title": "Fix issue with preferred suggestion in the current document.", "icon": "$(lightbulb-autofix)", "enablement": "view == cspell-info.issuesView" + }, + { + "command": "cSpell.issueViewer.item.addWordToDictionary", + "category": "Spell", + "title": "Add Word to Dictionary", + "icon": "$(book)", + "enablement": "view == cspell-info.issuesView" } ], "languages": [ @@ -549,7 +564,7 @@ "markdownDescription": "A PatternRef is a Pattern or PatternId.", "type": "string" }, - "markdownDescription": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file,\n it is necessary to escape `\\`.\n Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | JSON | Description |\n| :------------------ | :-------------------- | :------------------------------------------- |\n| `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` |\n| `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. |\n| `CStyleComment` | `CStyleComment` | A built in pattern |", + "markdownDescription": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file,\n it is necessary to escape `\\`.\n Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | settings.json | Description |\n| :------------------ | :-------------------- | :------------------------------------------- |\n| `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` |\n| `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. |\n| `CStyleComment` | `CStyleComment` | A built in pattern |", "scope": "resource", "type": "array" }, @@ -629,6 +644,68 @@ "dictionaryDefinitions": { "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": [ + "name", + "path" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -714,8 +791,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enableFiletypes": { @@ -853,6 +931,68 @@ "dictionaryDefinitions": { "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": [ + "name", + "path" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -938,8 +1078,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enabled": { @@ -1578,7 +1719,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "title": "Name of Dictionary", "type": "string" }, @@ -1587,7 +1728,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -1634,13 +1775,75 @@ "markdownDescription": "Reference to a dictionary by name.\nOne of:\n- {@link DictionaryRef } \n- {@link DictionaryNegRef }", "type": "string" }, - "markdownDescription": "Optional list of dictionaries to use.\nEach entry should match the name of the dictionary.\nTo remove a dictionary from the list add `!` before the name.\ni.e. `!typescript` will turn off the dictionary with the name `typescript`.", + "markdownDescription": "Optional list of dictionaries to use.\n\nEach entry should match the name of the dictionary.\n\nTo remove a dictionary from the list add `!` before the name.\ni.e. `!typescript` will turn off the dictionary with the name `typescript`.\n\n\nExample:\n\n```jsonc\n// Enable `lorem-ipsum` and disable `typescript`\n\"cSpell.dictionaries\": [\"lorem-ipsum\", \"!typescript\"]\n```", "scope": "resource", "type": "array" }, "cSpell.dictionaryDefinitions": { "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": [ + "name", + "path" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1726,8 +1929,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "cSpell.flagWords": { @@ -1781,6 +1985,68 @@ "dictionaryDefinitions": { "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "enum": [ + "user", + "workspace", + "folder" + ], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": [ + "name", + "path" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1866,8 +2132,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enabled": { @@ -2162,7 +2429,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2172,7 +2439,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -2224,7 +2491,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2234,7 +2501,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { @@ -2303,7 +2570,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2313,7 +2580,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -2365,7 +2632,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2375,7 +2642,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { @@ -2444,7 +2711,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2454,7 +2721,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -2506,7 +2773,7 @@ "type": "string" }, "name": { - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2516,7 +2783,7 @@ "type": "boolean" }, "path": { - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { diff --git a/packages/_server/spell-checker-config.schema.json b/packages/_server/spell-checker-config.schema.json index 78e884ebc..9a917413b 100644 --- a/packages/_server/spell-checker-config.schema.json +++ b/packages/_server/spell-checker-config.schema.json @@ -75,13 +75,13 @@ "order": 5, "properties": { "cSpell.ignoreRegExpList": { - "description": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file, it is necessary to escape `\\`. Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | JSON | Description | | :------------------ | :-------------------- | :------------------------------------------- | | `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` | | `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. | | `CStyleComment` | `CStyleComment` | A built in pattern |", + "description": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file, it is necessary to escape `\\`. Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | settings.json | Description | | :------------------ | :-------------------- | :------------------------------------------- | | `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` | | `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. | | `CStyleComment` | `CStyleComment` | A built in pattern |", "items": { "description": "A PatternRef is a Pattern or PatternId.", "markdownDescription": "A PatternRef is a Pattern or PatternId.", "type": "string" }, - "markdownDescription": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file,\n it is necessary to escape `\\`.\n Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | JSON | Description |\n| :------------------ | :-------------------- | :------------------------------------------- |\n| `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` |\n| `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. |\n| `CStyleComment` | `CStyleComment` | A built in pattern |", + "markdownDescription": "List of regular expressions or Pattern names (defined in `#cSpell.patterns#`) to exclude from spell checking.\n\n- When using the VS Code Preferences UI, it is not necessary to escape the `\\`, VS Code takes care of that.\n- When editing the VS Code `settings.json` file,\n it is necessary to escape `\\`.\n Each `\\` becomes `\\\\`.\n\nThe default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode.\n\n| VS Code UI | settings.json | Description |\n| :------------------ | :-------------------- | :------------------------------------------- |\n| `/\\\\[a-z]+/gi` | `/\\\\\\\\[a-z]+/gi` | Exclude LaTeX command like `\\mapsto` |\n| `/\\b[A-Z]{3,5}\\b/g` | `/\\\\b[A-Z]{3,5}\\\\b/g` | Exclude full-caps acronyms of 3-5 length. |\n| `CStyleComment` | `CStyleComment` | A built in pattern |", "scope": "resource", "type": "array" }, @@ -159,9 +159,68 @@ "type": "array" }, "dictionaryDefinitions": { - "description": "Define additional available dictionaries.", + "description": "Define custom dictionaries.. If `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js \"cSpell.dictionaryDefinitions\": [ { \"name\": \"project-words\", \"path\": \"${workspaceRoot}/project-words.txt\", \"description\": \"Words used in this project\", \"addWords\": true } ] ```", "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "description": "Indicate if this custom dictionary should be used to store added words.", + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "description": "Optional: A human readable description.", + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "description": "Indicate that suggestions should not come from this dictionary. Words in this dictionary are considered correct, but will not be used when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in this dictionary, it will be removed from the set of possible suggestions.", + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "description": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": ["name", "path"], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -244,8 +303,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enableFiletypes": { @@ -407,9 +467,68 @@ "type": "array" }, "dictionaryDefinitions": { - "description": "Define additional available dictionaries.", + "description": "Define custom dictionaries.. If `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js \"cSpell.dictionaryDefinitions\": [ { \"name\": \"project-words\", \"path\": \"${workspaceRoot}/project-words.txt\", \"description\": \"Words used in this project\", \"addWords\": true } ] ```", "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "description": "Indicate if this custom dictionary should be used to store added words.", + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "description": "Optional: A human readable description.", + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "description": "Indicate that suggestions should not come from this dictionary. Words in this dictionary are considered correct, but will not be used when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in this dictionary, it will be removed from the set of possible suggestions.", + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "description": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": ["name", "path"], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -492,8 +611,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enabled": { @@ -1170,8 +1290,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "title": "Name of Dictionary", "type": "string" }, @@ -1181,8 +1301,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -1221,20 +1341,79 @@ "type": "object" }, "cSpell.dictionaries": { - "description": "Optional list of dictionaries to use. Each entry should match the name of the dictionary. To remove a dictionary from the list add `!` before the name. i.e. `!typescript` will turn off the dictionary with the name `typescript`.", + "description": "Optional list of dictionaries to use.\n\nEach entry should match the name of the dictionary.\n\nTo remove a dictionary from the list add `!` before the name. i.e. `!typescript` will turn off the dictionary with the name `typescript`.\n\n\nExample:\n\n```jsonc // Enable `lorem-ipsum` and disable `typescript` \"cSpell.dictionaries\": [\"lorem-ipsum\", \"!typescript\"] ```", "items": { "description": "Reference to a dictionary by name. One of:\n- {@link DictionaryRef } \n- {@link DictionaryNegRef }", "markdownDescription": "Reference to a dictionary by name.\nOne of:\n- {@link DictionaryRef } \n- {@link DictionaryNegRef }", "type": "string" }, - "markdownDescription": "Optional list of dictionaries to use.\nEach entry should match the name of the dictionary.\nTo remove a dictionary from the list add `!` before the name.\ni.e. `!typescript` will turn off the dictionary with the name `typescript`.", + "markdownDescription": "Optional list of dictionaries to use.\n\nEach entry should match the name of the dictionary.\n\nTo remove a dictionary from the list add `!` before the name.\ni.e. `!typescript` will turn off the dictionary with the name `typescript`.\n\n\nExample:\n\n```jsonc\n// Enable `lorem-ipsum` and disable `typescript`\n\"cSpell.dictionaries\": [\"lorem-ipsum\", \"!typescript\"]\n```", "scope": "resource", "type": "array" }, "cSpell.dictionaryDefinitions": { - "description": "Define additional available dictionaries.", + "description": "Define custom dictionaries.. If `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js \"cSpell.dictionaryDefinitions\": [ { \"name\": \"project-words\", \"path\": \"${workspaceRoot}/project-words.txt\", \"description\": \"Words used in this project\", \"addWords\": true } ] ```", "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "description": "Indicate if this custom dictionary should be used to store added words.", + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "description": "Optional: A human readable description.", + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "description": "Indicate that suggestions should not come from this dictionary. Words in this dictionary are considered correct, but will not be used when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in this dictionary, it will be removed from the set of possible suggestions.", + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "description": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": ["name", "path"], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1317,8 +1496,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "cSpell.flagWords": { @@ -1379,9 +1559,68 @@ "type": "array" }, "dictionaryDefinitions": { - "description": "Define additional available dictionaries.", + "description": "Define custom dictionaries.. If `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js \"cSpell.dictionaryDefinitions\": [ { \"name\": \"project-words\", \"path\": \"${workspaceRoot}/project-words.txt\", \"description\": \"Words used in this project\", \"addWords\": true } ] ```", "items": { "anyOf": [ + { + "additionalProperties": false, + "properties": { + "addWords": { + "default": true, + "description": "Indicate if this custom dictionary should be used to store added words.", + "markdownDescription": "Indicate if this custom dictionary should be used to store added words.", + "title": "Add Words to Dictionary", + "type": "boolean" + }, + "description": { + "description": "Optional: A human readable description.", + "markdownDescription": "Optional: A human readable description.", + "title": "Description of the Dictionary", + "type": "string" + }, + "name": { + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", + "title": "Name of Dictionary", + "type": "string" + }, + "noSuggest": { + "description": "Indicate that suggestions should not come from this dictionary. Words in this dictionary are considered correct, but will not be used when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in this dictionary, it will be removed from the set of possible suggestions.", + "markdownDescription": "Indicate that suggestions should not come from this dictionary.\nWords in this dictionary are considered correct, but will not be\nused when making spell correction suggestions.\n\nNote: if a word is suggested by another dictionary, but found in\nthis dictionary, it will be removed from the set of\npossible suggestions.", + "type": "boolean" + }, + "path": { + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", + "type": "string" + }, + "scope": { + "anyOf": [ + { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + { + "items": { + "description": "Specifies the scope of a dictionary.", + "enum": ["user", "workspace", "folder"], + "markdownDescription": "Specifies the scope of a dictionary.", + "type": "string" + }, + "type": "array" + } + ], + "description": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "markdownDescription": "Options are\n- `user` - words that apply to all projects and workspaces\n- `workspace` - words that apply to the entire workspace\n- `folder` - words that apply to only a workspace folder", + "title": "Scope of dictionary" + } + }, + "required": ["name", "path"], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1464,8 +1703,9 @@ } ] }, - "markdownDescription": "Define additional available dictionaries.", + "markdownDescription": "Define custom dictionaries..\nIf `addWords` is `true` words will be added to this dictionary.\n\nThis setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence).\n\nIt is better to use `#cSpell.customDictionaries#`\n\n**Example:**\n\n```js\n\"cSpell.dictionaryDefinitions\": [\n {\n \"name\": \"project-words\",\n \"path\": \"${workspaceRoot}/project-words.txt\",\n \"description\": \"Words used in this project\",\n \"addWords\": true\n }\n]\n```", "scope": "resource", + "title": "Dictionary Definitions", "type": "array" }, "enabled": { @@ -1797,8 +2037,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -1809,8 +2049,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -1857,8 +2097,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -1869,8 +2109,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { @@ -1935,8 +2175,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -1947,8 +2187,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -1995,8 +2235,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2007,8 +2247,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { @@ -2073,8 +2313,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2085,8 +2325,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "title": "Path to Dictionary Text File", "type": "string" }, @@ -2133,8 +2373,8 @@ "type": "string" }, "name": { - "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", - "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf they name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", + "description": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary. If you use: `typescript` it will replace the built-in TypeScript dictionary.", + "markdownDescription": "The reference name of the dictionary.\n\n\nExample: `My Words` or `custom`\n\n\nIf the name matches a pre-defined dictionary, it will override the pre-defined dictionary.\nIf you use: `typescript` it will replace the built-in TypeScript dictionary.", "pattern": "^(?=[^!*,;{}[\\]~\\n]+$)(?=(.*\\w)).+$", "title": "Name of Dictionary", "type": "string" @@ -2145,8 +2385,8 @@ "type": "boolean" }, "path": { - "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n``` ~/dictionaries/custom_dictionary.txt ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n``` ${workspaceFolder:client}/build/custom_dictionary.txt ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n``` ${workspaceFolder}/build/custom_dictionary.txt ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n``` ./build/custom_dictionary.txt ```", - "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```\n~/dictionaries/custom_dictionary.txt\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```\n${workspaceFolder:client}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might no as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```\n${workspaceFolder}/build/custom_dictionary.txt\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```\n./build/custom_dictionary.txt\n```", + "description": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found in the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json \"path\": \"~/dictionaries/custom_dictionary.txt\" ```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json \"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative workspace for the currently open file.\n\n```json \"path\": \"${workspaceFolder}/build/custom_dictionary.txt\" ```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in a multi-root workspace\n\n```json \"path\": \"./build/custom_dictionary.txt\" ```", + "markdownDescription": "Define the path to the dictionary text file.\n\n**Note:** if path is `undefined` the `name`d dictionary is expected to be found\nin the `dictionaryDefinitions`.\n\nFile Format: Each line in the file is considered a dictionary entry.\n\nCase is preserved while leading and trailing space is removed.\n\nThe path should be absolute, or relative to the workspace.\n\n**Example:** relative to User's folder\n\n```json\n\"path\": \"~/dictionaries/custom_dictionary.txt\"\n```\n\n**Example:** relative to the `client` folder in a multi-root workspace\n\n```json\n\"path\": \"${workspaceFolder:client}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the current workspace folder in a single-root workspace\n\n**Note:** this might not work as expected in a multi-root workspace since it is based upon the relative\nworkspace for the currently open file.\n\n```json\n\"path\": \"${workspaceFolder}/build/custom_dictionary.txt\"\n```\n\n**Example:** relative to the workspace folder in a single-root workspace or the first folder in\na multi-root workspace\n\n```json\n\"path\": \"./build/custom_dictionary.txt\"\n```", "type": "string" }, "scope": { diff --git a/packages/_server/src/config/cspellConfig/CSpellSettingsPackageProperties.mts b/packages/_server/src/config/cspellConfig/CSpellSettingsPackageProperties.mts index c4b2bdc8e..6803839d2 100644 --- a/packages/_server/src/config/cspellConfig/CSpellSettingsPackageProperties.mts +++ b/packages/_server/src/config/cspellConfig/CSpellSettingsPackageProperties.mts @@ -70,72 +70,11 @@ export interface CSpellSettingsPackageProperties extends CSpellSettings { * @scope resource * @uniqueItems true * @default [ - * "asciidoc", - * "bat", - * "c", - * "clojure", - * "coffeescript", - * "cpp", - * "csharp", - * "css", - * "dart", - * "diff", - * "dockerfile", - * "elixir", - * "erlang", - * "fsharp", - * "git-commit", - * "git-rebase", - * "github-actions-workflow", - * "go", - * "graphql", - * "groovy", - * "handlebars", - * "haskell", - * "html", - * "ini", - * "jade", - * "java", - * "javascript", - * "javascriptreact", - * "json", - * "jsonc", - * "julia", - * "jupyter", - * "latex", - * "less", - * "lua", - * "makefile", - * "markdown", - * "objective-c", - * "perl", - * "perl6", - * "php", - * "plaintext", - * "powershell", - * "properties", - * "pug", - * "python", - * "r", - * "razor", - * "restructuredtext", - * "ruby", - * "rust", - * "scala", - * "scminput", - * "scss", - * "shaderlab", - * "shellscript", - * "sql", - * "swift", - * "text", - * "typescript", - * "typescriptreact", - * "vb", - * "vue", - * "xml", - * "xsl", - * "yaml" + * "asciidoc","bat","c","clojure","coffeescript","cpp","csharp","css","dart","diff","dockerfile","elixir","erlang","fsharp","git-commit", + * "git-rebase","github-actions-workflow","go","graphql","groovy","handlebars","haskell","html","ini","jade","java","javascript","javascriptreact", + * "json","jsonc","julia","jupyter","latex","less","lua","makefile","markdown","objective-c","perl","perl6","php","plaintext","powershell", + * "properties","pug","python","r","razor","restructuredtext","ruby","rust","scala","scminput","scss","shaderlab","shellscript","sql","swift", + * "text","typescript","typescriptreact","vb","vue","xml","xsl","yaml" * ] */ enabledLanguageIds?: CSpellSettings['enabledLanguageIds']; @@ -168,14 +107,7 @@ export interface CSpellSettingsPackageProperties extends CSpellSettings { * Glob patterns of files to be ignored. The patterns are relative to the `#cSpell.globRoot#` of the configuration file that defines them. * @title Glob patterns of files to be ignored * @scope resource - * @default [ - * "package-lock.json", - * "node_modules", - * "vscode-extension", - * ".git/objects", - * ".vscode", - * ".vscode-insiders" - * ] + * @default ["package-lock.json","node_modules","vscode-extension",".git/objects",".vscode",".vscode-insiders"] */ ignorePaths?: (SimpleGlob | GlobDefX)[]; @@ -249,7 +181,7 @@ export interface CSpellSettingsPackageProperties extends CSpellSettings { * * The default regular expression flags are `gi`. Add `u` (`gui`), to enable Unicode. * - * | VS Code UI | JSON | Description | + * | VS Code UI | settings.json | Description | * | :------------------ | :-------------------- | :------------------------------------------- | * | `/\\[a-z]+/gi` | `/\\\\[a-z]+/gi` | Exclude LaTeX command like `\mapsto` | * | `/\b[A-Z]{3,5}\b/g` | `/\\b[A-Z]{3,5}\\b/g` | Exclude full-caps acronyms of 3-5 length. | @@ -278,10 +210,20 @@ export interface CSpellSettingsPackageProperties extends CSpellSettings { /** * Optional list of dictionaries to use. + * * Each entry should match the name of the dictionary. + * * To remove a dictionary from the list add `!` before the name. * i.e. `!typescript` will turn off the dictionary with the name `typescript`. * + * + * Example: + * + * ```jsonc + * // Enable `lorem-ipsum` and disable `typescript` + * "cSpell.dictionaries": ["lorem-ipsum", "!typescript"] + * ``` + * * @scope resource */ dictionaries?: CSpellSettings['dictionaries']; diff --git a/packages/_server/src/config/cspellConfig/CustomDictionary.mts b/packages/_server/src/config/cspellConfig/CustomDictionary.mts index 060ef30df..b8f0a234f 100644 --- a/packages/_server/src/config/cspellConfig/CustomDictionary.mts +++ b/packages/_server/src/config/cspellConfig/CustomDictionary.mts @@ -12,7 +12,7 @@ type DictionaryDefPreferred = Omit; -export type DictionaryDef = DictionaryDefPreferred | DictionaryDefCustom; +export type DictionaryDef = CustomDictionary | DictionaryDefPreferred | DictionaryDefCustom; export type CustomDictionaries = { [Name in DictionaryId]: EnableCustomDictionary | CustomDictionariesDictionary; @@ -37,7 +37,7 @@ interface CustomDictionaryBase extends Pick { * Example: `My Words` or `custom` * * - * If they name matches a pre-defined dictionary, it will override the pre-defined dictionary. + * If the name matches a pre-defined dictionary, it will override the pre-defined dictionary. * If you use: `typescript` it will replace the built-in TypeScript dictionary. * @title Name of Dictionary */ @@ -63,30 +63,30 @@ interface CustomDictionaryBase extends Pick { * * **Example:** relative to User's folder * - * ``` - * ~/dictionaries/custom_dictionary.txt + * ```json + * "path": "~/dictionaries/custom_dictionary.txt" * ``` * * **Example:** relative to the `client` folder in a multi-root workspace * - * ``` - * ${workspaceFolder:client}/build/custom_dictionary.txt + * ```json + * "path": "${workspaceFolder:client}/build/custom_dictionary.txt" * ``` * * **Example:** relative to the current workspace folder in a single-root workspace * - * **Note:** this might no as expected in a multi-root workspace since it is based upon the relative + * **Note:** this might not work as expected in a multi-root workspace since it is based upon the relative * workspace for the currently open file. * - * ``` - * ${workspaceFolder}/build/custom_dictionary.txt + * ```json + * "path": "${workspaceFolder}/build/custom_dictionary.txt" * ``` * * **Example:** relative to the workspace folder in a single-root workspace or the first folder in * a multi-root workspace * - * ``` - * ./build/custom_dictionary.txt + * ```json + * "path": "./build/custom_dictionary.txt" * ``` * @title Path to Dictionary Text File */ diff --git a/packages/_server/src/config/cspellConfig/cspellConfig.mts b/packages/_server/src/config/cspellConfig/cspellConfig.mts index 47ec5a7f1..b9c163b7d 100644 --- a/packages/_server/src/config/cspellConfig/cspellConfig.mts +++ b/packages/_server/src/config/cspellConfig/cspellConfig.mts @@ -24,7 +24,26 @@ export type SpellCheckerSettingsVSCodePropertyKeys = `cspell.${keyof CSpellUserS interface DictionaryDefinitions { /** - * Define additional available dictionaries. + * Define custom dictionaries.. + * If `addWords` is `true` words will be added to this dictionary. + * + * This setting is subject to User/Workspace settings precedence rules: [Visual Studio Code User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings#_settings-precedence). + * + * It is better to use `#cSpell.customDictionaries#` + * + * **Example:** + * + * ```js + * "cSpell.dictionaryDefinitions": [ + * { + * "name": "project-words", + * "path": "${workspaceRoot}/project-words.txt", + * "description": "Words used in this project", + * "addWords": true + * } + * ] + * ``` + * @title Dictionary Definitions * @scope resource */ dictionaryDefinitions?: DictionaryDef[]; @@ -89,7 +108,7 @@ type CSpellOmitFieldsFromExtensionContributesInPackageJson = export interface SpellCheckerSettingsVSCodeBase extends Omit< CSpellUserSettings, - CSpellOmitFieldsFromExtensionContributesInPackageJson | 'dictionaryDefinitions' | 'languageSettings' | 'overrides' + CSpellOmitFieldsFromExtensionContributesInPackageJson | keyof DictionaryDefinitions | keyof LanguageSettings | keyof Overrides >, DictionaryDefinitions, LanguageSettings, From ae197fe33780d16dc1907ffc5c5220ace8f4e97c Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Wed, 1 Nov 2023 13:07:19 +0100 Subject: [PATCH 3/3] refactor the issue viewer --- packages/client/src/addWords.ts | 39 ++++ packages/client/src/commands.ts | 112 +---------- packages/client/src/extension.ts | 5 +- .../client/src/issueViewer/issueViewer.ts | 182 +++++++++++------- packages/client/src/promptUser.ts | 75 ++++++++ 5 files changed, 234 insertions(+), 179 deletions(-) create mode 100644 packages/client/src/addWords.ts create mode 100644 packages/client/src/promptUser.ts diff --git a/packages/client/src/addWords.ts b/packages/client/src/addWords.ts new file mode 100644 index 000000000..1154608d7 --- /dev/null +++ b/packages/client/src/addWords.ts @@ -0,0 +1,39 @@ +import type { Uri } from 'vscode'; + +import * as di from './di'; +import type { MatchTargetsFn } from './settings/configTargetHelper'; +import { + dictionaryTargetBestMatchesFolder, + dictionaryTargetBestMatchesUser, + dictionaryTargetBestMatchesWorkspace, +} from './settings/configTargetHelper'; +import { handleErrors } from './util/errors'; +import { toUri } from './util/uriHelper'; + +export function addWordToFolderDictionary(word: string, docUri: string | null | Uri | undefined): Promise { + return addWordToTarget(word, dictionaryTargetBestMatchesFolder, docUri); +} + +export function addWordToWorkspaceDictionary(word: string, docUri: string | null | Uri | undefined): Promise { + return addWordToTarget(word, dictionaryTargetBestMatchesWorkspace, docUri); +} + +export function addWordToUserDictionary(word: string): Promise { + return addWordToTarget(word, dictionaryTargetBestMatchesUser, undefined); +} + +export function addWordToTarget(word: string, target: MatchTargetsFn, docUri: string | null | Uri | undefined) { + return handleErrors(_addWordToTarget(word, target, docUri), 'addWordToTarget'); +} + +function _addWordToTarget(word: string, target: MatchTargetsFn, docUri: string | null | Uri | undefined) { + docUri = toUri(docUri); + return di.get('dictionaryHelper').addWordsToTargets(word, target, docUri); +} + +export function fnWTarget( + fn: (word: string, t: TT, uri: Uri | undefined) => Promise, + t: TT, +): (word: string, uri: Uri | undefined) => Promise { + return (word, uri) => fn(word, t, uri); +} diff --git a/packages/client/src/commands.ts b/packages/client/src/commands.ts index cab6db128..dfc6b0d0b 100644 --- a/packages/client/src/commands.ts +++ b/packages/client/src/commands.ts @@ -1,12 +1,14 @@ -import type { Command, ConfigurationScope, Diagnostic, Disposable, QuickPickOptions, TextDocument, TextEdit, Uri } from 'vscode'; +import type { Command, ConfigurationScope, Diagnostic, Disposable, TextDocument, TextEdit, Uri } from 'vscode'; import { commands, FileType, Position, Range, Selection, TextEditorRevealType, window, workspace } from 'vscode'; import type { Position as LsPosition, Range as LsRange, TextEdit as LsTextEdit } from 'vscode-languageclient/node'; +import { addWordToFolderDictionary, addWordToTarget, addWordToUserDictionary, addWordToWorkspaceDictionary, fnWTarget } from './addWords'; import { actionAutoFixSpellingIssues, handleApplyTextEdits, handleFixSpellingIssue } from './applyCorrections'; import type { ClientSideCommandHandlerApi } from './client'; import { actionSuggestSpellingCorrections } from './codeActions/actionSuggestSpellingCorrections'; import * as di from './di'; -import { extractMatchingDiagTexts, getCSpellDiags } from './diags'; +import { getCSpellDiags } from './diags'; +import { onCommandUseDiagsSelectionOrPrompt } from './promptUser'; import type { ConfigTargetLegacy, TargetsAndScopes } from './settings'; import * as Settings from './settings'; import { @@ -20,25 +22,20 @@ import type { ClientConfigTarget } from './settings/clientConfigTarget'; import type { ConfigRepository } from './settings/configRepository'; import { createCSpellConfigRepository, createVSCodeConfigRepository } from './settings/configRepository'; import { configTargetToConfigRepo } from './settings/configRepositoryHelper'; -import type { MatchTargetsFn } from './settings/configTargetHelper'; import { createClientConfigTargetVSCode, createConfigTargetMatchPattern, dictionaryTargetBestMatches, dictionaryTargetBestMatchesCSpell, - dictionaryTargetBestMatchesFolder, - dictionaryTargetBestMatchesUser, dictionaryTargetBestMatchesVSCodeFolder as dtVSCodeFolder, dictionaryTargetBestMatchesVSCodeUser as dtVSCodeUser, dictionaryTargetBestMatchesVSCodeWorkspace as dtVSCodeWorkspace, - dictionaryTargetBestMatchesWorkspace, filterClientConfigTargets, matchKindAll, matchScopeAll, patternMatchNoDictionaries, quickPickTarget, } from './settings/configTargetHelper'; -import { normalizeWords } from './settings/CSpellSettings'; import type { DictionaryTarget } from './settings/DictionaryTarget'; import { createDictionaryTargetForFile } from './settings/DictionaryTarget'; import { mapConfigTargetToClientConfigTarget } from './settings/mappers/configTarget'; @@ -49,7 +46,6 @@ import { dictionaryScopeToConfigurationTarget, } from './settings/targetAndScope'; import { catchErrors, handleErrors } from './util/errors'; -import { findEditor } from './util/findEditor'; import { performance, toMilliseconds } from './util/perf'; import { pVoid } from './util/pVoid'; import { scrollToText } from './util/textEditor'; @@ -100,7 +96,7 @@ const actionAddIgnoreWordToUser = prompt('Ignore Words in User Settings', fnWTar const actionAddWordToCSpell = prompt('Add Words to cSpell Configuration', fnWTarget(addWordToTarget, dictionaryTargetBestMatchesCSpell)); const actionAddWordToDictionary = prompt('Add Words to Dictionary', fnWTarget(addWordToTarget, dictionaryTargetBestMatches)); -const commandHandlers = { +export const commandHandlers = { 'cSpell.addWordToDictionary': actionAddWordToDictionary, 'cSpell.addWordToFolderDictionary': actionAddWordToFolder, 'cSpell.addWordToWorkspaceDictionary': actionAddWordToWorkspace, @@ -198,29 +194,6 @@ function registerCmd(cmd: string, fn: (...args: any[]) => unknown): Disposable { return commands.registerCommand(cmd, catchErrors(fn, `Register command: ${cmd}`)); } -function addWordToFolderDictionary(word: string, docUri: string | null | Uri | undefined): Promise { - return addWordToTarget(word, dictionaryTargetBestMatchesFolder, docUri); -} - -export function addWordToWorkspaceDictionary(word: string, docUri: string | null | Uri | undefined): Promise { - // eslint-disable-next-line prefer-rest-params - console.log('addWordToWorkspaceDictionary %o', arguments); - return addWordToTarget(word, dictionaryTargetBestMatchesWorkspace, docUri); -} - -export function addWordToUserDictionary(word: string): Promise { - return addWordToTarget(word, dictionaryTargetBestMatchesUser, undefined); -} - -function addWordToTarget(word: string, target: MatchTargetsFn, docUri: string | null | Uri | undefined) { - return handleErrors(_addWordToTarget(word, target, docUri), 'addWordToTarget'); -} - -function _addWordToTarget(word: string, target: MatchTargetsFn, docUri: string | null | Uri | undefined) { - docUri = toUri(docUri); - return di.get('dictionaryHelper').addWordsToTargets(word, target, docUri); -} - function addAllIssuesFromDocument(): Promise { return handleErrors(di.get('dictionaryHelper').addIssuesToDictionary(), 'addAllIssuesFromDocument'); } @@ -387,74 +360,6 @@ async function uriToTextDocInfo(uri: Uri): Promise<{ uri: Uri; languageId?: stri return await workspace.openTextDocument(uri); } -const compareStrings = new Intl.Collator().compare; - -function onCommandUseDiagsSelectionOrPrompt( - prompt: string, - fnAction: (text: string, uri: Uri | undefined) => Promise, -): (text?: string, uri?: Uri | string) => Promise { - return async function (text?: string, uri?: Uri | string) { - const selected = await determineTextSelection(prompt, text, uri); - if (!selected) return; - - const editor = window.activeTextEditor; - await fnAction(selected.text, selected.uri); - await (editor?.document && window.showTextDocument(editor.document)); - }; -} - -async function determineTextSelection(prompt: string, text?: string, uri?: Uri | string): Promise<{ text: string; uri?: Uri } | undefined> { - uri = toUri(uri); - if (text) { - return { text, uri: uri || window.activeTextEditor?.document.uri }; - } - - const editor = findEditor(uri); - - const document = editor?.document; - const selection = editor?.selection; - const range = selection && document?.getWordRangeAtPosition(selection.active); - const diags = document ? getCSpellDiags(document.uri) : undefined; - const matchingDiagWords = normalizeWords(extractMatchingDiagTexts(document, selection, diags) || []); - if (matchingDiagWords.length) { - const picked = - selection?.anchor.isEqual(selection.active) && matchingDiagWords.length === 1 - ? matchingDiagWords - : await chooseWords(matchingDiagWords.sort(compareStrings), { title: prompt, placeHolder: 'Choose words' }); - if (!picked) return; - return { text: picked.join(' '), uri: document?.uri }; - } - - if (!range || !selection || !document || !document.getText(range)) { - const word = await window.showInputBox({ title: prompt, prompt }); - if (!word) return; - return { text: word, uri: document?.uri }; - } - - text = selection.contains(range) ? document.getText(selection) : document.getText(range); - - const words = normalizeWords(text); - const picked = - words.length > 1 - ? await chooseWords(words.sort(compareStrings), { title: prompt, placeHolder: 'Choose words' }) - : [await window.showInputBox({ title: prompt, prompt, value: words[0] })]; - if (!picked) return; - return { text: picked.join(' '), uri: document.uri }; -} - -async function chooseWords(words: string[], options: QuickPickOptions): Promise { - if (words.length <= 1) { - const picked = await window.showInputBox({ ...options, value: words[0] }); - if (!picked) return; - return [picked]; - } - - const items = words.map((label) => ({ label, picked: true })); - - const picked = await window.showQuickPick(items, { ...options, canPickMany: true }); - return picked?.map((p) => p.label); -} - function ctx(method: string, target: ConfigurationTarget | undefined, uri: Uri | string | null | undefined): string { const scope = target ? configurationTargetToDictionaryScope(target) : ''; return scope ? `${method} ${scope} ${toUri(uri)}` : `${method} ${toUri(uri)}`; @@ -476,13 +381,6 @@ function dumpPerfTimeline(): void { }); } -function fnWTarget( - fn: (word: string, t: TT, uri: Uri | undefined) => Promise, - t: TT, -): (word: string, uri: Uri | undefined) => Promise { - return (word, uri) => fn(word, t, uri); -} - async function createCSpellConfig(): Promise { const uri = await createConfigFileRelativeToDocumentUri(window.activeTextEditor?.document.uri); if (uri) { diff --git a/packages/client/src/extension.ts b/packages/client/src/extension.ts index b37f2c41d..b7ed7fd12 100644 --- a/packages/client/src/extension.ts +++ b/packages/client/src/extension.ts @@ -6,6 +6,7 @@ import { registerCspellInlineCompletionProviders } from './autocomplete'; import { CSpellClient } from './client'; import { registerSpellCheckerCodeActionProvider } from './codeAction'; import * as commands from './commands'; +import * as addWords from './addWords'; import { updateDocumentRelatedContext } from './context'; import { SpellingIssueDecorator } from './decorate'; import * as di from './di'; @@ -179,8 +180,8 @@ export async function activate(context: ExtensionContext): Promise disableLanguageId: commands.disableLanguageIdCmd, enableCurrentLanguage: commands.enableCurrentLanguage, disableCurrentLanguage: commands.disableCurrentLanguage, - addWordToUserDictionary: commands.addWordToUserDictionary, - addWordToWorkspaceDictionary: commands.addWordToWorkspaceDictionary, + addWordToUserDictionary: addWords.addWordToUserDictionary, + addWordToWorkspaceDictionary: addWords.addWordToWorkspaceDictionary, enableLocale: methods.enableLocale, disableLocale: methods.disableLocale, updateSettings: () => false, diff --git a/packages/client/src/issueViewer/issueViewer.ts b/packages/client/src/issueViewer/issueViewer.ts index d18264edc..8dd2b7c85 100644 --- a/packages/client/src/issueViewer/issueViewer.ts +++ b/packages/client/src/issueViewer/issueViewer.ts @@ -1,20 +1,21 @@ +import { uriToName } from '@internal/common-utils'; import type { Suggestion } from 'code-spell-checker-server/api'; import { createDisposableList } from 'utils-disposables'; -import type { Disposable, ExtensionContext, ProviderResult, Range, TextDocument, TreeDataProvider } from 'vscode'; +import type { Disposable, ExtensionContext, ProviderResult, Range, TextDocument, TreeDataProvider, Uri } from 'vscode'; import * as vscode from 'vscode'; import { TreeItem } from 'vscode'; import { handleFixSpellingIssue } from '../applyCorrections'; import type { CSpellClient } from '../client'; import { actionSuggestSpellingCorrections } from '../codeActions/actionSuggestSpellingCorrections'; -import { knownCommands } from '../commands'; +import { commandHandlers, knownCommands } from '../commands'; import type { IssueTracker, SpellingDiagnostic } from '../issueTracker'; import { createEmitter } from '../Subscribables'; import { logErrors } from '../util/errors'; -import { findEditor } from '../util/findEditor'; +import { findEditor, findTextDocument } from '../util/findEditor'; export function activate(context: ExtensionContext, issueTracker: IssueTracker, client: CSpellClient) { - context.subscriptions.push(IssuesTreeDataProvider.register(issueTracker, client)); + context.subscriptions.push(IssueExplorer.register(issueTracker, client)); context.subscriptions.push( vscode.commands.registerCommand(knownCommands['cSpell.issueViewer.item.openSuggestionsForIssue'], handleOpenSuggestionsForIssue), vscode.commands.registerCommand(knownCommands['cSpell.issueViewer.item.autoFixSpellingIssues'], handleAutoFixSpellingIssues), @@ -30,49 +31,67 @@ interface RequestSuggestionsParam { readonly onUpdate: (suggestions: Suggestion[]) => void; } +class IssueExplorer { + private disposeList = createDisposableList(); + private treeView: vscode.TreeView; + + constructor(issueTracker: IssueTracker, client: CSpellClient) { + const treeDataProvider = new IssuesTreeDataProvider({ + issueTracker, + client, + setDescription: (des) => { + this.treeView.description = des; + }, + setMessage: (msg) => { + this.treeView.message = msg; + }, + }); + this.treeView = vscode.window.createTreeView(IssueExplorer.viewID, { treeDataProvider, showCollapseAll: true }); + this.disposeList.push(this.treeView); + this.treeView.title = 'Spelling Issues'; + this.treeView.message = 'No open documents.'; + } + + readonly dispose = this.disposeList.dispose; + + static viewID = 'cspell-info.issuesView'; + + static register(issueTracker: IssueTracker, client: CSpellClient) { + return new IssueExplorer(issueTracker, client); + } +} + interface Context { client: CSpellClient; issueTracker: IssueTracker; document: TextDocument; - currentEditor: vscode.TextEditor | undefined; invalidate: (item: OnDidChangeEventType) => void; requestSuggestions: (item: RequestSuggestionsParam) => Suggestion[] | undefined; } +interface ProviderOptions { + issueTracker: IssueTracker; + client: CSpellClient; + setMessage(msg: string | undefined): void; + setDescription(des: string | undefined): void; +} + class IssuesTreeDataProvider implements TreeDataProvider { private emitOnDidChange = createEmitter(); private disposeList = createDisposableList(); private currentEditor: vscode.TextEditor | undefined = undefined; + private currentDocUri: Uri | undefined = undefined; private suggestions = new Map(); + private issueTracker: IssueTracker; + private client: CSpellClient; - constructor( - private issueTracker: IssueTracker, - private client: CSpellClient, - ) { + constructor(private options: ProviderOptions) { + this.issueTracker = options.issueTracker; + this.client = options.client; this.disposeList.push( this.emitOnDidChange, - vscode.window.onDidChangeActiveTextEditor((editor) => { - if (editor === this.currentEditor) return; - if (editor) { - this.currentEditor = editor; - this.emitOnDidChange.notify(undefined); - } - this.currentEditor = this.currentEditor && findEditor(this.currentEditor.document.uri); - }), - issueTracker.onDidChangeDiagnostics((e) => { - const activeTextEditor = vscode.window.activeTextEditor; - if (activeTextEditor && activeTextEditor !== this.currentEditor) { - this.currentEditor = activeTextEditor; - this.emitOnDidChange.notify(undefined); - return; - } - const current = this.currentEditor?.document.uri.toString(); - if (!current) return; - const matching = e.uris.filter((u) => u.toString() === current); - if (matching.length) { - this.emitOnDidChange.notify(undefined); - } - }), + vscode.window.onDidChangeActiveTextEditor((editor) => this.updateEditor(editor)), + this.issueTracker.onDidChangeDiagnostics((e) => this.handleOnDidChangeDiagnostics(e)), ); } @@ -81,14 +100,16 @@ class IssuesTreeDataProvider implements TreeDataProvider { } getChildren(element?: IssueTreeItemBase | undefined): ProviderResult { - if (element) return element.getChildren(); - const editor = vscode.window.activeTextEditor; - if (!editor) return [new NoIssuesTreeItem()]; + if (element) { + return element.getChildren(); + } + const editor = this.currentEditor; + const document = editor?.document || findTextDocument(this.currentDocUri); + if (!document) return this.updateMessage('No open documents.'); const context: Context = { issueTracker: this.issueTracker, client: this.client, - document: editor.document, - currentEditor: editor, + document: document, invalidate: (item) => this.emitOnDidChange.notify(item), requestSuggestions: (item) => { logErrors(this.fetchSuggestions(item), 'IssuesTreeDataProvider requestSuggestions'); @@ -96,7 +117,8 @@ class IssuesTreeDataProvider implements TreeDataProvider { }, }; const issues = collectIssues(context); - return issues.length ? issues : [new NoIssuesTreeItem()]; + this.updateMessage(issues.length ? undefined : 'No issues found...'); + return issues; } onDidChangeTreeData(listener: (e: OnDidChangeEventType) => void, thisArg?: unknown, disposables?: Disposable[]): Disposable { @@ -108,6 +130,15 @@ class IssuesTreeDataProvider implements TreeDataProvider { return d; } + private handleOnDidChangeDiagnostics(e: vscode.DiagnosticChangeEvent) { + const current = this.currentEditor?.document.uri.toString(); + if (!current) return; + const matching = e.uris.filter((u) => u.toString() === current); + if (matching.length) { + this.emitOnDidChange.notify(undefined); + } + } + private async fetchSuggestions(item: RequestSuggestionsParam) { const { word, document } = item; const result = await this.client.requestSpellingSuggestions(word, document); @@ -117,6 +148,27 @@ class IssuesTreeDataProvider implements TreeDataProvider { item.onUpdate(suggestions); } + private updateEditor(editor: vscode.TextEditor | undefined) { + if (editor === this.currentEditor) return; + if (editor) { + this.currentEditor = editor; + this.currentDocUri = editor.document.uri; + this.emitOnDidChange.notify(undefined); + return; + } + this.currentEditor = this.currentDocUri && findEditor(this.currentDocUri); + this.emitOnDidChange.notify(undefined); + } + + private updateMessage(msg: string | undefined) { + const doc = findTextDocument(this.currentDocUri); + const uri = doc?.uri; + const name = uri && uriToName(uri); + this.options.setDescription(name); + this.options.setMessage(msg); + return undefined; + } + // private hasPreferred(): boolean { // for (const group of this.suggestions.values()) { // return !!(group[0]?.isPreferred && !group[1].isPreferred); @@ -130,15 +182,6 @@ class IssuesTreeDataProvider implements TreeDataProvider { // } readonly dispose = this.disposeList.dispose; - - static register(issueTracker: IssueTracker, client: CSpellClient, name = 'cspell-info.issuesView') { - const provider = new IssuesTreeDataProvider(issueTracker, client); - const disposeList = createDisposableList( - [provider, vscode.window.registerTreeDataProvider(name, provider)], - 'IssuesTreeDataProvider.register', - ); - return disposeList; - } } const icons = { @@ -172,15 +215,18 @@ class IssueTreeItem extends IssueTreeItemBase { getTreeItem(): TreeItem { const item = new TreeItem(this.word); const hasPreferred = this.hasPreferred(); - item.iconPath = this.diags[0]?.data?.isFlagged ? icons.error : icons.warning; + const isFlagged = this.diags[0]?.data?.isFlagged; + item.iconPath = isFlagged ? icons.error : icons.warning; item.description = this.diags.length + (hasPreferred ? ' (auto fix)' : ''); - if (this.diags.length === 1) { - item.command = { - title: 'Goto Issue', - command: knownCommands['cSpell.selectRange'], - arguments: [this.context.document.uri, this.diags[0].range], - }; - } + const cWord = cleanWord(this.word); + item.tooltip = new vscode.MarkdownString().appendMarkdown((isFlagged ? 'Flagged' : 'Unknown') + ' word: `' + cWord + '`'); + // if (this.diags.length === 1) { + // item.command = { + // title: 'Goto Issue', + // command: knownCommands['cSpell.selectRange'], + // arguments: [this.context.document.uri, this.diags[0].range], + // }; + // } item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; item.contextValue = hasPreferred ? 'issue.hasPreferred' : 'issue'; return item; @@ -217,7 +263,9 @@ class IssueTreeItem extends IssueTreeItemBase { return handleFixSpellingIssue(this.context.document.uri, pref.text, pref.newText, pref.ranges); } - async addToDictionary() {} + async addToDictionary() { + return commandHandlers['cSpell.addWordToDictionary'](this.word, this.context.document.uri); + } private onUpdate(suggestions: Suggestion[]) { this.suggestions = suggestions; @@ -313,7 +361,7 @@ class IssueSuggestionTreeItem extends IssueTreeItemBase { const item = new TreeItem(word); item.iconPath = isPreferred ? icons.suggestionPreferred : icons.suggestion; item.description = isPreferred && '(preferred)'; - const fixMessage = 'Fix Issue with ' + word; + const fixMessage = 'Fix Issue with: ' + word; item.command = { title: fixMessage, command: knownCommands['cSpell.fixSpellingIssue'], @@ -338,20 +386,6 @@ class IssueSuggestionTreeItem extends IssueTreeItemBase { } } -class NoIssuesTreeItem extends IssueTreeItemBase { - constructor() { - super(); - } - - getTreeItem(): TreeItem { - return new TreeItem('No Issues Found...'); - } - - getChildren() { - return undefined; - } -} - function collectIssues(context: Context): IssueTreeItem[] { const doc = context.document; const issues = context.issueTracker.getDiagnostics(doc.uri); @@ -410,3 +444,11 @@ interface PreferredFix { // const issues = issueTracker.getDiagnostics(uri); // if (!issues.length) return undefined; // } + +/** + * Clean a word for markdown. + * @param word + */ +function cleanWord(word: string): string { + return word.replace(/\s/g, ' ').replace(/`/g, "'"); +} diff --git a/packages/client/src/promptUser.ts b/packages/client/src/promptUser.ts new file mode 100644 index 000000000..14a3bb208 --- /dev/null +++ b/packages/client/src/promptUser.ts @@ -0,0 +1,75 @@ +import type { QuickPickOptions, Uri } from 'vscode'; +import { window } from 'vscode'; + +import { extractMatchingDiagTexts, getCSpellDiags } from './diags'; +import { normalizeWords } from './settings/CSpellSettings'; +import { findEditor } from './util/findEditor'; +import { toUri } from './util/uriHelper'; + +const compareStrings = new Intl.Collator().compare; + +export function onCommandUseDiagsSelectionOrPrompt( + prompt: string, + fnAction: (text: string, uri: Uri | undefined) => Promise, +): (text?: string, uri?: Uri | string) => Promise { + return async function (text?: string, uri?: Uri | string) { + const selected = await determineTextSelection(prompt, text, uri); + if (!selected) return; + + const editor = window.activeTextEditor; + await fnAction(selected.text, selected.uri); + await (editor?.document && window.showTextDocument(editor.document)); + }; +} + +async function determineTextSelection(prompt: string, text?: string, uri?: Uri | string): Promise<{ text: string; uri?: Uri } | undefined> { + uri = toUri(uri); + if (text) { + return { text, uri: uri || window.activeTextEditor?.document.uri }; + } + + const editor = findEditor(uri); + + const document = editor?.document; + const selection = editor?.selection; + const range = selection && document?.getWordRangeAtPosition(selection.active); + const diags = document ? getCSpellDiags(document.uri) : undefined; + const matchingDiagWords = normalizeWords(extractMatchingDiagTexts(document, selection, diags) || []); + if (matchingDiagWords.length) { + const picked = + selection?.anchor.isEqual(selection.active) && matchingDiagWords.length === 1 + ? matchingDiagWords + : await chooseWords(matchingDiagWords.sort(compareStrings), { title: prompt, placeHolder: 'Choose words' }); + if (!picked) return; + return { text: picked.join(' '), uri: document?.uri }; + } + + if (!range || !selection || !document || !document.getText(range)) { + const word = await window.showInputBox({ title: prompt, prompt }); + if (!word) return; + return { text: word, uri: document?.uri }; + } + + text = selection.contains(range) ? document.getText(selection) : document.getText(range); + + const words = normalizeWords(text); + const picked = + words.length > 1 + ? await chooseWords(words.sort(compareStrings), { title: prompt, placeHolder: 'Choose words' }) + : [await window.showInputBox({ title: prompt, prompt, value: words[0] })]; + if (!picked) return; + return { text: picked.join(' '), uri: document.uri }; +} + +async function chooseWords(words: string[], options: QuickPickOptions): Promise { + if (words.length <= 1) { + const picked = await window.showInputBox({ ...options, value: words[0] }); + if (!picked) return; + return [picked]; + } + + const items = words.map((label) => ({ label, picked: true })); + + const picked = await window.showQuickPick(items, { ...options, canPickMany: true }); + return picked?.map((p) => p.label); +}