Change:
The content of the line: Open definition does nothing !
Also happens on Mac with Cmd+Click. Makes it very difficult to navigate my documentation.
I believe this is a result of fixing Markdown has a link provider and a definition provider. However in this case, the definition provider returns since we are not on a reference link
revert of the bad change is up

Discussion:
import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { ModelDecorationInjectedTextOptions } from 'vs/editor/common/model/textModel'; <del> import { LinkOpener } from 'vs/editor/contrib/links/browser/links'; </del> export class GotoDefinitionAtPositionEditorContribution implements IEditorContribution {

})); this.toUnhook.add(linkGesture.onExecute((mouseEvent: ClickLinkMouseEvent) => { <del> if (!this.isEnabled(mouseEvent)) { return; </del> <ins> if (this.isEnabled(mouseEvent)) { this.gotoDefinition(mouseEvent.target.position!, mouseEvent.hasSideBySideModifier) .catch((error: Error) => { onUnexpectedError(error); }) .finally(() => { this.removeLinkDecorations(); }); </ins> } <del> LinkOpener.get(this.editor)?.openLink( mouseEvent.target.range!, nls.localize('link.label', "Go to Definition"), () => { this.gotoDefinition(mouseEvent.target.position!, mouseEvent.hasSideBySideModifier) .catch((error: Error) => { onUnexpectedError(error); }) .finally(() => { this.removeLinkDecorations(); }); }); </del> })); this.toUnhook.add(linkGesture.onCancel(() => {

*  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ <del> import * as dom from 'vs/base/browser/dom'; import { toAction } from 'vs/base/common/actions'; import { coalesceInPlace } from 'vs/base/common/arrays'; </del> import { createCancelablePromise, CancelablePromise, RunOnceScheduler } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable } from 'vs/base/common/lifecycle'; <del> import { LinkedList } from 'vs/base/common/linkedList'; </del> import { Schemas } from 'vs/base/common/network'; import * as platform from 'vs/base/common/platform'; import * as resources from 'vs/base/common/resources'; import { StopWatch } from 'vs/base/common/stopwatch'; <del> import { assertType } from 'vs/base/common/types'; </del> import { URI } from 'vs/base/common/uri'; import 'vs/css!./links'; import { ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorContributionInstantiation, registerEditorAction, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; <del> import { IRange, Range } from 'vs/editor/common/core/range'; </del> import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; import { LinkProvider } from 'vs/editor/common/languages';

import { ClickLinkGesture, ClickLinkKeyboardEvent, ClickLinkMouseEvent } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; import { getLinks, Link, LinksList } from 'vs/editor/contrib/links/browser/getLinks'; import * as nls from 'vs/nls'; <del> import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; </del> import { INotificationService } from 'vs/platform/notification/common/notification'; import { IOpenerService } from 'vs/platform/opener/common/opener';

} public openLinkOccurrence(occurrence: LinkOccurrence, openToSide: boolean, fromUserGesture = false): void { <del> const { link } = occurrence; LinkOpener.get(this.editor)?.openLink(link.range, nls.localize('open', "Open Link"), () => { link.resolve(CancellationToken.None).then(uri => { </del> <ins> if (!this.openerService) { return; } </ins> <del> // Support for relative file URIs of the shape file://./relativeFile.txt or file:///./relativeFile.txt if (typeof uri === 'string' && this.editor.hasModel()) { const modelUri = this.editor.getModel().uri; if (modelUri.scheme === Schemas.file && uri.startsWith(`${Schemas.file}:`)) { const parsedUri = URI.parse(uri); if (parsedUri.scheme === Schemas.file) { const fsPath = resources.originalFSPath(parsedUri); </del> <ins> const { link } = occurrence; </ins> <del> let relativePath: string | null = null; if (fsPath.startsWith('/./')) { relativePath = `.${fsPath.substr(1)}`; } else if (fsPath.startsWith('//./')) { relativePath = `.${fsPath.substr(2)}`; } </del> <ins> link.resolve(CancellationToken.None).then(uri => { // Support for relative file URIs of the shape file://./relativeFile.txt or file:///./relativeFile.txt if (typeof uri === 'string' && this.editor.hasModel()) { const modelUri = this.editor.getModel().uri; if (modelUri.scheme === Schemas.file && uri.startsWith(`${Schemas.file}:`)) { const parsedUri = URI.parse(uri); if (parsedUri.scheme === Schemas.file) { const fsPath = resources.originalFSPath(parsedUri); let relativePath: string | null = null; if (fsPath.startsWith('/./')) { relativePath = `.${fsPath.substr(1)}`; } else if (fsPath.startsWith('//./')) { relativePath = `.${fsPath.substr(2)}`; } </ins> <del> if (relativePath) { uri = resources.joinPath(modelUri, relativePath); } </del> <ins> if (relativePath) { uri = resources.joinPath(modelUri, relativePath); </ins> } } } <ins> } </ins> <del> return this.openerService.open(uri, { openToSide, fromUserGesture, allowContributedOpeners: true, allowCommands: true, fromWorkspace: true }); }, err => { const messageOrError = err instanceof Error ? (<Error>err).message : err; // different error cases if (messageOrError === 'invalid') { this.notificationService.warn(nls.localize('invalid.url', 'Failed to open this link because it is not well-formed: {0}', link.url!.toString())); } else if (messageOrError === 'missing') { this.notificationService.warn(nls.localize('missing.url', 'Failed to open this link because its target is missing.')); } else { onUnexpectedError(err); } }); </del> <ins> return this.openerService.open(uri, { openToSide, fromUserGesture, allowContributedOpeners: true, allowCommands: true, fromWorkspace: true }); }, err => { const messageOrError = err instanceof Error ? (<Error>err).message : err; // different error cases if (messageOrError === 'invalid') { this.notificationService.warn(nls.localize('invalid.url', 'Failed to open this link because it is not well-formed: {0}', link.url!.toString())); } else if (messageOrError === 'missing') { this.notificationService.warn(nls.localize('missing.url', 'Failed to open this link because its target is missing.')); } else { onUnexpectedError(err); } </ins> }); }

} } <del> export class LinkOpener extends Disposable implements IEditorContribution { public static readonly ID = 'editor.linkOpener'; public static get(editor: ICodeEditor): LinkOpener | null { return editor.getContribution<LinkOpener>(LinkOpener.ID); } private readonly links = new LinkedList<{ range: IRange; label: string; callback: () => void }>(); constructor( private readonly editor: ICodeEditor, @IContextMenuService private readonly contextMenuService: IContextMenuService, ) { super(); } openLink(range: IRange, label: string, callback: () => void): void { this.links.push({ range, label, callback }); if (this.links.size === 1) { queueMicrotask(() => this.openLinks()); } } private openLinks(): void { if (!this.editor.hasModel()) { return; } const links = [...this.links]; this.links.clear(); // remove links that don't overlap, late links win over early links for (let i = 1; i < links.length; i++) { const link = links[i]; const prevLink = links[i - 1]; if (!Range.areIntersecting(link.range, prevLink.range)) { links[i - 1] = undefined!; } } coalesceInPlace(links); if (links.length === 1) { // single: just invoke callback links[0].callback(); } else if (links.length > 1) { // multiple: show context menu this.contextMenuService.showContextMenu({ getAnchor: () => { assertType(this.editor.hasModel()); const position = Range.getStartPosition(links[0].range); const cursorCoords = this.editor.getScrolledVisiblePosition(position); // Translate to absolute editor position const editorCoords = dom.getDomNodePagePosition(this.editor.getDomNode()); const posx = editorCoords.left + cursorCoords.left; const posy = editorCoords.top + cursorCoords.top + cursorCoords.height; return { x: posx, y: posy }; }, getActions: () => { return links.map(item => toAction({ id: '', label: item.label, run: item.callback })); }, }); } } } </del> class OpenLinkAction extends EditorAction { constructor() {

}); } <del> public run(_accessor: ServicesAccessor, editor: ICodeEditor): void { </del> <ins> public run(accessor: ServicesAccessor, editor: ICodeEditor): void { </ins> const linkDetector = LinkDetector.get(editor); if (!linkDetector) { return;

} registerEditorContribution(LinkDetector.ID, LinkDetector, EditorContributionInstantiation.AfterFirstRender); <del> registerEditorContribution(LinkOpener.ID, LinkOpener, EditorContributionInstantiation.Lazy); </del> registerEditorAction(OpenLinkAction);