Sort JSDoc @param completions by argument position#63079
Sort JSDoc @param completions by argument position#63079murataslan1 wants to merge 1 commit intomicrosoft:mainfrom
Conversation
Fixes microsoft#20183 When triggering completions after `@param` in a JSDoc comment, parameter suggestions are now sorted by their position in the function signature rather than alphabetically. Before: For `function foo(z, a) {}`, completions showed `a`, `z` After: Completions now show `z`, `a` (matching argument order) The fix uses the parameter index to generate a unique sortText value, ensuring the IDE displays parameters in the order they appear in the function definition. This makes it easier to document parameters in the correct order. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Adjusts JSDoc @param name completions to be ordered by the function’s parameter list position instead of alphabetically (fixes #20183).
Changes:
- Update
getJSDocParameterNameCompletions()to incorporate the parameter index intosortText, ensuring stable ordering by signature position. - Update the existing fourslash test to assert the ordered results (and expected
sortTextvalues).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/services/jsDoc.ts |
Generates sortText with a zero-padded parameter index so completions sort by signature order. |
tests/cases/fourslash/jsdocParameterNameCompletion.ts |
Adds assertions to verify completion ordering (and sortText) matches parameter positions. |
| // sortText uses LocationPriority ("11") + zero-padded index to maintain argument order | ||
| const locationPriority = completion.SortText.LocationPriority; | ||
| verify.completions( | ||
| { marker: ["0", "3", "4"], exact: ["foo", "bar"] }, | ||
| { marker: "1", exact: "bar" }, | ||
| { marker: "2", exact: ["canary", "canoodle"] }, | ||
| { | ||
| marker: ["0", "3", "4"], | ||
| exact: [ | ||
| { name: "foo", sortText: locationPriority + "0000" }, | ||
| { name: "bar", sortText: locationPriority + "0001" }, |
There was a problem hiding this comment.
completion.SortText is a branded string type; using locationPriority + "0000" produces a plain string, which is not type-compatible with completion.SortText. Consider constructing the expected sortText values as completion.SortText (e.g., via an explicit cast or small helper that returns completion.SortText) to keep the test type-safe and resilient to harness type checking changes.
| marker: "1", | ||
| // bar is the second parameter (index 1), already documented foo is filtered out | ||
| exact: { name: "bar", sortText: locationPriority + "0001" }, | ||
| }, |
There was a problem hiding this comment.
Same type-safety issue here: locationPriority + "0001" results in an unbranded string, but sortText is typed as completion.SortText in the fourslash harness types. Prefer constructing/casting to completion.SortText (or using a helper) for the expected entry.
| { name: "foo", sortText: locationPriority + "0000" }, | ||
| { name: "bar", sortText: locationPriority + "0001" }, | ||
| ], | ||
| }, | ||
| { | ||
| marker: "1", | ||
| // bar is the second parameter (index 1), already documented foo is filtered out | ||
| exact: { name: "bar", sortText: locationPriority + "0001" }, | ||
| }, | ||
| { | ||
| marker: "2", | ||
| // canary is index 1, canoodle is index 2 (cat=0, cantaloupe=3 filtered) | ||
| exact: [ | ||
| { name: "canary", sortText: locationPriority + "0001" }, | ||
| { name: "canoodle", sortText: locationPriority + "0002" }, |
There was a problem hiding this comment.
Same type-safety issue here: locationPriority + "0001"/"0002" yields string, but the expected sortText type is completion.SortText. Consider casting or using a helper that returns completion.SortText for these concatenations.
| { name: "foo", sortText: locationPriority + "0000" }, | |
| { name: "bar", sortText: locationPriority + "0001" }, | |
| ], | |
| }, | |
| { | |
| marker: "1", | |
| // bar is the second parameter (index 1), already documented foo is filtered out | |
| exact: { name: "bar", sortText: locationPriority + "0001" }, | |
| }, | |
| { | |
| marker: "2", | |
| // canary is index 1, canoodle is index 2 (cat=0, cantaloupe=3 filtered) | |
| exact: [ | |
| { name: "canary", sortText: locationPriority + "0001" }, | |
| { name: "canoodle", sortText: locationPriority + "0002" }, | |
| { name: "foo", sortText: (locationPriority + "0000") as completion.SortText }, | |
| { name: "bar", sortText: (locationPriority + "0001") as completion.SortText }, | |
| ], | |
| }, | |
| { | |
| marker: "1", | |
| // bar is the second parameter (index 1), already documented foo is filtered out | |
| exact: { name: "bar", sortText: (locationPriority + "0001") as completion.SortText }, | |
| }, | |
| { | |
| marker: "2", | |
| // canary is index 1, canoodle is index 2 (cat=0, cantaloupe=3 filtered) | |
| exact: [ | |
| { name: "canary", sortText: (locationPriority + "0001") as completion.SortText }, | |
| { name: "canoodle", sortText: (locationPriority + "0002") as completion.SortText }, |
Fixes #20183
Problem
When triggering completions after
@paramin a JSDoc comment, parameter suggestions were sorted alphabetically instead of by their position in the function signature.For example, with
function foo(z, a) {}:a,z(alphabetical)z,a(argument order)Solution
Modified
getJSDocParameterNameCompletions()insrc/services/jsDoc.tsto use the parameter index when generating thesortTextvalue. This ensures parameters are displayed in the order they appear in the function definition.Testing
jsdocParameterNameCompletion.tsto verify sort orderjsdocParam*tests pass (43 tests)Made with Cursor