Change:
Add some form of error reporting for links in markdown files where we are confident that link is incorrect. Example: We should also have a setting to disable this error reporting since we will not be able to understand every flavor of markdown link
Bad references (seems like this should almost always be a reasonable error to report) Missing files (false positive if users rely on different logic to resolve markdown paths) - Missing headers (false positive if users rely on custom slugifier or are linking to something besides headers, such as html elements) -Checking links to external resources () Checking html in markdown
Re-opening as we will likely keep this as experimental this iteration

Discussion:
"experimental" ] }, <del> "markdown.experimental.validate.enabled": { </del> <ins> "markdown.validate.enabled": { </ins> "type": "boolean", "scope": "resource", <del> "description": "%configuration.markdown.experimental.validate.enabled.description%", "default": false, "tags": [ "experimental" ] </del> <ins> "description": "%configuration.markdown.validate.enabled.description%", "default": false </ins> }, <del> "markdown.experimental.validate.referenceLinks.enabled": { </del> <ins> "markdown.validate.referenceLinks.enabled": { </ins> "type": "string", "scope": "resource", <del> "markdownDescription": "%configuration.markdown.experimental.validate.referenceLinks.enabled.description%", </del> <ins> "markdownDescription": "%configuration.markdown.validate.referenceLinks.enabled.description%", </ins> "default": "warning", "enum": [ "ignore", "warning", "error" <del> ], "tags": [ "experimental" </del> ] }, <del> "markdown.experimental.validate.fragmentLinks.enabled": { </del> <ins> "markdown.validate.fragmentLinks.enabled": { </ins> "type": "string", "scope": "resource", <del> "markdownDescription": "%configuration.markdown.experimental.validate.fragmentLinks.enabled.description%", </del> <ins> "markdownDescription": "%configuration.markdown.validate.fragmentLinks.enabled.description%", </ins> "default": "warning", "enum": [ "ignore", "warning", "error" <del> ], "tags": [ "experimental" </del> ] }, <del> "markdown.experimental.validate.fileLinks.enabled": { </del> <ins> "markdown.validate.fileLinks.enabled": { </ins> "type": "string", "scope": "resource", <del> "markdownDescription": "%configuration.markdown.experimental.validate.fileLinks.enabled.description%", </del> <ins> "markdownDescription": "%configuration.markdown.validate.fileLinks.enabled.description%", </ins> "default": "warning", "enum": [ "ignore", "warning", "error" <del> ], "tags": [ "experimental" </del> ] }, <del> "markdown.experimental.validate.fileLinks.markdownFragmentLinks": { </del> <ins> "markdown.validate.fileLinks.markdownFragmentLinks": { </ins> "type": "string", "scope": "resource", <del> "markdownDescription": "%configuration.markdown.experimental.validate.fileLinks.markdownFragmentLinks.description%", </del> <ins> "markdownDescription": "%configuration.markdown.validate.fileLinks.markdownFragmentLinks.description%", </ins> "default": "ignore", "enum": [ "ignore", "warning", "error" <del> ], "tags": [ "experimental" </del> ] }, <del> "markdown.experimental.validate.ignoreLinks": { </del> <ins> "markdown.validate.ignoredLinks": { </ins> "type": "array", "scope": "resource", <del> "markdownDescription": "%configuration.markdown.experimental.validate.ignoreLinks.description%", </del> <ins> "markdownDescription": "%configuration.markdown.validate.ignoredLinks.description%", </ins> "items": { "type": "string" <del> }, "tags": [ "experimental" ] </del> <ins> } </ins> }, "markdown.experimental.updateLinksOnFileMove.enabled": { "type": "string",

"configuration.markdown.suggest.paths.enabled.description": "Enable/disable path suggestions for markdown links", "configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#editor.dropIntoEditor.enabled#`.", "configuration.markdown.editor.pasteLinks.enabled": "Enable/disable pasting files into a Markdown editor inserts Markdown links. Requires enabling `#editor.experimental.pasteActions.enabled#`.", <del> "configuration.markdown.experimental.validate.enabled.description": "Enable/disable all error reporting in Markdown files.", "configuration.markdown.experimental.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`.  Requires enabling `#markdown.experimental.validate.enabled#`.", "configuration.markdown.experimental.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, e.g. `[link](#header)`. Requires enabling `#markdown.experimental.validate.enabled#`.", "configuration.markdown.experimental.validate.fileLinks.enabled.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.experimental.validate.enabled#`.", "configuration.markdown.experimental.validate.fileLinks.markdownFragmentLinks.description": "Validate the fragment part of links to headers in other files in Markdown files, e.g. `[link](/path/to/file.md#header)`. Inherits the setting value from `#markdown.experimental.validate.fragmentLinks.enabled#` by default.", "configuration.markdown.experimental.validate.ignoreLinks.description": "Configure links that should not be validated. For example `/about` would not validate the link `[about](/about)`, while the glob `/assets/**/*.svg` would let you skip validation for any link to `.svg` files under the `assets` directory.", </del> <ins> "configuration.markdown.validate.enabled.description": "Enable/disable all error reporting in Markdown files.", "configuration.markdown.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`.  Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, e.g. `[link](#header)`. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fileLinks.enabled.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fileLinks.markdownFragmentLinks.description": "Validate the fragment part of links to headers in other files in Markdown files, e.g. `[link](/path/to/file.md#header)`. Inherits the setting value from `#markdown.validate.fragmentLinks.enabled#` by default.", "configuration.markdown.validate.ignoredLinks.description": "Configure links that should not be validated. For example adding `/about` would not validate the link `[about](/about)`, while the glob `/assets/**/*.svg` would let you skip validation for any link to `.svg` files under the `assets` directory.", </ins> "configuration.markdown.experimental.updateLinksOnFileMove.enabled": "Try to update links in Markdown files when a file is renamed/moved in the workspace. Use `#markdown.experimental.updateLinksOnFileMove.externalFileGlobs#` to configure which files trigger link updates.", "configuration.markdown.experimental.updateLinksOnFileMove.enabled.prompt": "Prompt on each file move.", "configuration.markdown.experimental.updateLinksOnFileMove.enabled.always": "Always update links automatically.",

- (experimental) Updating links when a file is moved / renamed. Uses a custom `markdown/getEditForFileRenames` message. <del> - (experimental) [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. </del> <ins> - [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. </ins> ## Client requirements

- `suggest` - `paths` - `enabled` — Enable/disable path suggestions. <del> - `experimental` - `validate` - `enabled` — Enable/disable all validation. - `referenceLinks` - `enabled` — Enable/disable validation of reference links: `[text][ref]` - `fragmentLinks` - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` - `fileLinks` - `enabled` — Enable/disable validation of links to file in the workspace. - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. - `ignoreLinks` — Array of glob patterns for files that should not be validated. </del> <ins> - `validate` - `enabled` — Enable/disable all validation. - `referenceLinks` - `enabled` — Enable/disable validation of reference links: `[text][ref]` - `fragmentLinks` - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` - `fileLinks` - `enabled` — Enable/disable validation of links to file in the workspace. - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. - `ignoredLinks` — Array of glob patterns for files that should not be validated. </ins> ### Custom requests

}; }; <del> readonly experimental: { readonly validate: { readonly enabled: true; readonly referenceLinks: { readonly enabled: ValidateEnabled; }; readonly fragmentLinks: { readonly enabled: ValidateEnabled; }; readonly fileLinks: { readonly enabled: ValidateEnabled; readonly markdownFragmentLinks: ValidateEnabled; }; readonly ignoreLinks: readonly string[]; </del> <ins> readonly validate: { readonly enabled: true; readonly referenceLinks: { readonly enabled: ValidateEnabled; </ins> }; <ins> readonly fragmentLinks: { readonly enabled: ValidateEnabled; }; readonly fileLinks: { readonly enabled: ValidateEnabled; readonly markdownFragmentLinks: ValidateEnabled; }; readonly ignoredLinks: readonly string[]; </ins> }; }; }

public getSettings(): Settings | undefined { return this._settings; } <del> } </del>  No newline at end of file <ins> } </ins>

import { Connection, FullDocumentDiagnosticReport, TextDocuments, UnchangedDocumentDiagnosticReport } from 'vscode-languageserver'; import * as md from 'vscode-markdown-languageservice'; <del> import { disposeAll } from 'vscode-markdown-languageservice/out/util/dispose'; </del> import { Disposable } from 'vscode-notebook-renderer/events'; import { URI } from 'vscode-uri'; import { ConfigurationManager, ValidateEnabled } from '../configuration'; <ins> import { disposeAll } from '../util/dispose'; </ins> const defaultDiagnosticOptions: md.DiagnosticOptions = { validateFileLinks: md.DiagnosticLevel.ignore,

} return { <del> validateFileLinks: convertDiagnosticLevel(settings.markdown.experimental.validate.fileLinks.enabled), validateReferences: convertDiagnosticLevel(settings.markdown.experimental.validate.referenceLinks.enabled), validateFragmentLinks: convertDiagnosticLevel(settings.markdown.experimental.validate.fragmentLinks.enabled), validateMarkdownFileLinkFragments: convertDiagnosticLevel(settings.markdown.experimental.validate.fileLinks.markdownFragmentLinks), ignoreLinks: settings.markdown.experimental.validate.ignoreLinks, </del> <ins> validateFileLinks: convertDiagnosticLevel(settings.markdown.validate.fileLinks.enabled), validateReferences: convertDiagnosticLevel(settings.markdown.validate.referenceLinks.enabled), validateFragmentLinks: convertDiagnosticLevel(settings.markdown.validate.fragmentLinks.enabled), validateMarkdownFileLinkFragments: convertDiagnosticLevel(settings.markdown.validate.fileLinks.markdownFragmentLinks), ignoreLinks: settings.markdown.validate.ignoredLinks, </ins> }; }

connection.languages.diagnostics.on(async (params, token): Promise<FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport> => { logger.log(md.LogLevel.Trace, 'Server: connection.languages.diagnostics.on', params.textDocument.uri); <del> if (!config.getSettings()?.markdown.experimental.validate.enabled) { </del> <ins> if (!config.getSettings()?.markdown.validate.enabled) { </ins> return emptyDiagnosticsResponse; }

const commandReg = commandManager.register({ id: AddToIgnoreLinksQuickFixProvider._addToIgnoreLinksCommandId, execute(resource: vscode.Uri, path: string) { <del> const settingId = 'experimental.validate.ignoreLinks'; </del> <ins> const settingId = 'validate.ignoredLinks'; </ins> const config = vscode.workspace.getConfiguration('markdown', resource); const paths = new Set(config.get<string[]>(settingId, [])); paths.add(path);