Skip to content
This repository was archived by the owner on May 20, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/extension/linkify/common/filePathLinkifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import { IStatCache } from './statCache';
const pathMatchRe = new RegExp(
[
// Inline code paths (exclude code-like characters $, {, }, that are common in code but rare in filenames)
/(?<!\[)`(?<inlineCodePath>[^`\s${}]+)`(?!\])/.source,
// Require at least one dot or path separator to avoid matching command names / other non-path text
/(?<!\[)`(?<inlineCodePath>(?=[^`\s${}]*[./\\])[^`\s${}]+)`(?!\])/.source,

// File paths rendered as plain text (exclude code-like characters)
/(?<![\[`()<])(?<plainTextPath>[^\s`*${}()]+\.[^\s`*${}()]+)(?![\]`])/.source
Expand Down
4 changes: 3 additions & 1 deletion src/extension/linkify/common/modelFilePathLinkifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ export class ModelFilePathLinkifier implements IContributedLinkifier {
descriptiveWithAnchor = textBasename === targetBasename;
} else {
// Text is truly descriptive (e.g., "widget initialization") - allow it
descriptiveWithAnchor = true;
// But reject text that looks like a command or path rather than a description
const textLooksLikeCommand = /[=\\/]|--\w/.test(text);
descriptiveWithAnchor = !textLooksLikeCommand;
}
}

Expand Down
39 changes: 39 additions & 0 deletions src/extension/linkify/test/node/filePathLinkifier.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,43 @@ suite('File Path Linkifier', () => {
'config.${TerminalSettingId' // Should remain as plain text
]);
});

test(`Should NOT linkify inline code that has no dot or path separator`, async () => {
// Command names, directory names, and other non-path text in backticks
// should not be linkified even if a workspace file/dir matches
const linkifier = createTestLinkifierService(
'code-insiders',
'test-byok-ext',
);

assertPartsEqual(
(await linkify(linkifier,
'`code-insiders` `test-byok-ext` `npm`',
)).parts,
[
'`code-insiders` `test-byok-ext` `npm`'
]
);
});

test(`Should still linkify inline code with dots or path separators`, async () => {
const linkifier = createTestLinkifierService(
'file.ts',
'src/file.ts',
'.env',
);

assertPartsEqual(
(await linkify(linkifier,
'`file.ts` `src/file.ts` `.env`',
)).parts,
[
new LinkifyLocationAnchor(workspaceFile('file.ts')),
` `,
new LinkifyLocationAnchor(workspaceFile('src/file.ts')),
` `,
new LinkifyLocationAnchor(workspaceFile('.env')),
]
);
});
});
18 changes: 18 additions & 0 deletions src/extension/linkify/test/node/modelFilePathLinkifier.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,24 @@ suite('Model File Path Linkifier', () => {
expect(anchor.title).toBe('src/file.ts#L1287-L1290');
assertPartsEqual([anchor], [expected]);
});

test('Should NOT linkify command-like text with anchor containing equals sign', async () => {
const service = createTestLinkifierService('src/common/spawnAsync.ts');
const result = await linkify(service, '[code-insiders --extensionDevelopmentPath=d:\\src\\test-byok-ext](src/common/spawnAsync.ts#L10)');
assertPartsEqual(result.parts, ['code-insiders --extensionDevelopmentPath=d:\\src\\test-byok-ext']);
});

test('Should NOT linkify command-like text with anchor containing flags', async () => {
const service = createTestLinkifierService('src/file.ts');
const result = await linkify(service, '[npm install --save-dev typescript](src/file.ts#L5)');
assertPartsEqual(result.parts, ['npm install --save-dev typescript']);
});

test('Should NOT linkify command-like text with anchor containing backslash', async () => {
const service = createTestLinkifierService('src/file.ts');
const result = await linkify(service, '[d:\\src\\test-byok-ext](src/file.ts#L5)');
assertPartsEqual(result.parts, ['d:\\src\\test-byok-ext']);
});
});

suite('Model File Path Linkifier Remote Workspace', () => {
Expand Down
Loading