`DocumentLink` click target is unpredictable when multiple providers return overlapping ranges — provider priority (score/isBuiltin/registration order) is not respected
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: No — reproduction requires at least one additional `DocumentLinkProvider` registered alongside a built-in language feature that already provides `DocumentLink`s for the same text (e.g. `markdown-language-features`'s own link support for `[text](url)`).
- VS Code Version: 1.134.0 / 110a328ea54b42367b803ec53ee0bf52ef26b419 / arm64
- OS Version: MacOS
## Steps to Reproduce:
Plugin for reproduce. Save these two files in an empty folder:
`package.json`:
```json
{
"name": "doclink-overlap-repro",
"displayName": "DocumentLink overlap repro",
"description": "Minimal repro extension for the DocumentLink overlap/priority issue",
"version": "0.0.1",
"engines": { "vscode": "^1.90.0" },
"activationEvents": ["onLanguage:markdown"],
"main": "./extension.js"
}
```
`extension.js`:
```js
const vscode = require('vscode');
function activate(context) {
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(
{ scheme: 'file', language: 'markdown' },
{
provideDocumentLinks(document) {
const links = [];
const text = document.getText();
const re = /\[[^\]]*\]\(([^)]+)\)/g;
let m;
while ((m = re.exec(text))) {
const urlStart = m.index + m[0].indexOf(m[1]);
const start = document.positionAt(urlStart);
const end = document.positionAt(urlStart + m[1].length);
links.push(new vscode.DocumentLink(
new vscode.Range(start, end),
vscode.Uri.parse('https://example.com/from-test-extension')
));
}
return links;
}
}
));
}
module.exports = { activate };
```
Then, with a `test.md` containing `[Foo bar](./some.txt)` in the same folder:
```
code --extensionDevelopmentPath= /test.md
```
Then,
* Hover over `./some.txt` while holding Cmd/Ctrl
* Observe **two separate "Follow link (cmd+click)" entries** in the hover
* Cmd/Ctrl+click repeatedly — it always opens via `markdown-language-features`'s own resolution, never via `doclink-overlap-repro`'s
## Expected behavior
Per [`LanguageFeatureRegistry._compareByScoreAndTime`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languageFeatureRegistry.ts#L202-L222), providers are explicitly ranked by score, then by whether they come from a built-in extension (non-built-in wins), then by registration time. [`LinksList._union`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/links/browser/getLinks.ts#L100-L139) is designed to drop the lower-priority link whenever two providers' ranges intersect or touch, so that exactly one `DocumentLink` should remain for a given span, and clicking it should deterministically resolve to the highest-priority provider's target.
## Actual behavior
- Both providers' links remain simultaneously visible (two separate hover entries), i.e. `_union`'s intersection-based removal does not appear to take effect for this pair of overlapping ranges.
- Which one actually executes on click is decided by [`LinkDetector.getLinkOccurrence()`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/links/browser/links.ts#L269-L288), which just takes the first result of `model.getDecorationsInRange()` — an internal red-black interval-tree traversal ([`intervalSearch`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/model/intervalTree.ts#L775)) that has no relationship to `LanguageFeatureRegistry` scoring at all.
- In practice this makes the winner effectively arbitrary: it is not even stable across repeated computations of the same, unedited document.
## A candidate fix
We prototyped a fix and confirmed that it resolves the issue: tag each merged `Link` with the priority of the provider that produced it (mirroring `LanguageFeatureRegistry.ordered`'s ordering), and add a final defensive pass over the fully merged list that guarantees no two links in the result have intersecting or touching ranges, keeping only the highest-priority one.
Diff: https://github.com/microsoft/vscode/compare/main...knaka:vscode:fix/document-link-overlap-priority
Contributor guide
Assessment
This issue has not been assessed yet.