Skip to content

snippets: fix disambiguation of completions with identical prefixes#306608

Open
xingsy97 wants to merge 1 commit intomicrosoft:mainfrom
xingsy97:wt/fix-snippet-disambiguate
Open

snippets: fix disambiguation of completions with identical prefixes#306608
xingsy97 wants to merge 1 commit intomicrosoft:mainfrom
xingsy97:wt/fix-snippet-disambiguate

Conversation

@xingsy97
Copy link
Copy Markdown
Member

Problem

SnippetCompletionProvider._disambiguateSnippets() sorts completions and then compares adjacent labels to detect duplicates. The comparison uses item.label === suggestions[to].label, but label is a CompletionItemLabel object ({ label: string, description: string }), not a string. Since each SnippetCompletion creates a fresh object in its constructor, === always returns false (reference equality), and the disambiguation suffix is never appended.

When multiple snippets share the same prefix (e.g. two 'for' snippets from different sources), they appear with identical labels in the completion list with no way to distinguish them.

Fix

Compare the label.label string property instead of the label object reference.

Copilot AI review requested due to automatic review settings March 31, 2026 05:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes snippet completion disambiguation when multiple snippet completions share the same prefix by comparing the underlying label string (CompletionItemLabel.label) instead of the label object reference, so duplicates can be detected and renamed.

Changes:

  • Update duplicate-detection logic in _disambiguateSnippets() to compare item.label.label strings instead of item.label object identity.
Comments suppressed due to low confidence (1)

src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts:196

  • Now that duplicate snippet prefixes are actually detected, the if (to > i + 1) branch will run; however the subsequent i = to (next line) causes the outer for loop to skip the first non-duplicate entry after a run. This can miss disambiguation for a following duplicate group (e.g. labels a,a,b,b would never disambiguate b). Set the index so the next iteration starts at to (commonly by assigning i = to - 1 before the loop increment), or refactor to a while loop to avoid off-by-one issues.
			for (; to < suggestions.length && item.label.label === suggestions[to].label.label; to++) {
				suggestions[to].label.label = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[to].label.label, suggestions[to].snippet.name);
			}
			if (to > i + 1) {
				suggestions[i].label.label = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[i].label.label, suggestions[i].snippet.name);

Comment on lines +192 to 193
for (; to < suggestions.length && item.label.label === suggestions[to].label.label; to++) {
suggestions[to].label.label = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[to].label.label, suggestions[to].snippet.name);
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change fixes duplicate-prefix detection, but there doesn't appear to be test coverage asserting that multiple snippets with the same prefix get disambiguated (e.g. label becomes ", "). Consider adding a unit test in the existing snippetsService test suite that registers two snippets with the same prefix and asserts the resulting completion labels are distinct.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants