From 54bc991b2609b6f546bac33e43b363b42ebea1fa Mon Sep 17 00:00:00 2001 From: creazyfrog Date: Sun, 26 Apr 2026 01:28:54 -0700 Subject: [PATCH] fix(completions): sort JSDoc @param suggestions by declaration order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When triggering completions after `@param` in a JSDoc comment, all parameter suggestions were assigned the same sortText ("11"), causing them to be ordered alphabetically by name rather than by their position in the function signature. For example, `function foo(z, a)` would suggest `a` before `z`. Fix: expose the parameter index from the `mapDefined` callback and compose a unique sortText per parameter: sortText = SortText.LocationPriority + paramIndex.padStart(4, "0") This produces "110000", "110001", … so parameters are sorted by their declaration order while still being grouped within the same priority tier as other location-priority completions. The fix applies to both named parameters and destructuring parameters. Fixes #20183 Signed-off-by: creazyfrog --- src/services/completions.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 28d29136dab89..f38646a1120d7 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -944,10 +944,13 @@ function getJSDocParameterCompletions( const isJs = isSourceFileJS(sourceFile); const isSnippet = preferences.includeCompletionsWithSnippetText || undefined; const paramTagCount = countWhere(jsDoc.tags, tag => isJSDocParameterTag(tag) && tag.getEnd() <= position); - return mapDefined(func.parameters, param => { + return mapDefined(func.parameters, (param, paramIndex) => { if (getJSDocParameterTags(param).length) { return undefined; // Parameter is already annotated. } + // Sort completions by the parameter's declaration order so that + // `@param` suggestions appear in the same order as the function signature. + const sortText = (SortText.LocationPriority + String(paramIndex).padStart(4, "0")) as SortText; if (isIdentifier(param.name)) { // Named parameter const tabstopCounter = { tabstop: 1 }; const paramName = param.name.text; @@ -983,7 +986,7 @@ function getJSDocParameterCompletions( return { name: displayText, kind: ScriptElementKind.parameterElement, - sortText: SortText.LocationPriority, + sortText, insertText: isSnippet ? snippetText : undefined, isSnippet, }; @@ -1023,7 +1026,7 @@ function getJSDocParameterCompletions( return { name: displayText, kind: ScriptElementKind.parameterElement, - sortText: SortText.LocationPriority, + sortText, insertText: isSnippet ? snippetText : undefined, isSnippet, };