Skip to content

Commit be220fa

Browse files
atscottAndrewKushnir
authored andcommitted
fix(language-service): Prioritize Angular-specific completions over DOM completions (#45293)
When authoring Angular templates, developers are likely to be most interested in the current Directive/Component inputs and outputs, then potential attributes which would match other directives to the element, and lastly the plethora of DOM events and attributes. This change ensures that Angular-specific information appears above DOM information by prepending the first printable ASCII characters to the sort text. Fixes angular/vscode-ng-language-service#1537 PR Close #45293
1 parent dc6094a commit be220fa

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

packages/language-service/src/attribute_completions.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,19 @@ function buildSnippet(insertSnippet: true|undefined, text: string): string|undef
374374
return insertSnippet ? `${text}="$1"` : undefined;
375375
}
376376

377+
/**
378+
* Used to ensure Angular completions appear before DOM completions. Inputs and Outputs are
379+
* prioritized first while attributes which would match an additional directive are prioritized
380+
* second.
381+
*
382+
* This sort priority is based on the ASCII table. Other than `space`, the `!` is the first
383+
* printable character in the ASCII ordering.
384+
*/
385+
enum AsciiSortPriority {
386+
First = '!',
387+
Second = '"',
388+
}
389+
377390
/**
378391
* Given an `AttributeCompletion`, add any available completions to a `ts.CompletionEntry` array of
379392
* results.
@@ -399,7 +412,7 @@ export function addAttributeCompletionEntries(
399412
entries.push({
400413
kind: unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
401414
name: completion.attribute,
402-
sortText: completion.attribute,
415+
sortText: AsciiSortPriority.Second + completion.attribute,
403416
replacementSpan,
404417
});
405418
break;
@@ -414,7 +427,7 @@ export function addAttributeCompletionEntries(
414427
name: prefix + completion.attribute,
415428
insertText: buildSnippet(insertSnippet, prefix + completion.attribute),
416429
isSnippet: insertSnippet,
417-
sortText: prefix + completion.attribute,
430+
sortText: AsciiSortPriority.Second + prefix + completion.attribute,
418431
replacementSpan,
419432
});
420433
break;
@@ -427,7 +440,7 @@ export function addAttributeCompletionEntries(
427440
name: `[${completion.propertyName}]`,
428441
insertText: buildSnippet(insertSnippet, `[${completion.propertyName}]`),
429442
isSnippet: insertSnippet,
430-
sortText: completion.propertyName,
443+
sortText: AsciiSortPriority.First + completion.propertyName,
431444
replacementSpan,
432445
});
433446
// If the directive supports banana-in-a-box for this input, offer that as well.
@@ -438,7 +451,7 @@ export function addAttributeCompletionEntries(
438451
insertText: buildSnippet(insertSnippet, `[(${completion.propertyName})]`),
439452
isSnippet: insertSnippet,
440453
// This completion should sort after the property binding.
441-
sortText: completion.propertyName + '_1',
454+
sortText: AsciiSortPriority.First + completion.propertyName + '_1',
442455
replacementSpan,
443456
});
444457
}
@@ -449,7 +462,7 @@ export function addAttributeCompletionEntries(
449462
insertText: buildSnippet(insertSnippet, completion.propertyName),
450463
isSnippet: insertSnippet,
451464
// This completion should sort after both property binding options (one-way and two-way).
452-
sortText: completion.propertyName + '_2',
465+
sortText: AsciiSortPriority.First + completion.propertyName + '_2',
453466
replacementSpan,
454467
});
455468
} else {
@@ -458,7 +471,7 @@ export function addAttributeCompletionEntries(
458471
name: completion.propertyName,
459472
insertText: buildSnippet(insertSnippet, completion.propertyName),
460473
isSnippet: insertSnippet,
461-
sortText: completion.propertyName,
474+
sortText: AsciiSortPriority.First + completion.propertyName,
462475
replacementSpan,
463476
});
464477
}
@@ -471,7 +484,7 @@ export function addAttributeCompletionEntries(
471484
name: `(${completion.eventName})`,
472485
insertText: buildSnippet(insertSnippet, `(${completion.eventName})`),
473486
isSnippet: insertSnippet,
474-
sortText: completion.eventName,
487+
sortText: AsciiSortPriority.First + completion.eventName,
475488
replacementSpan,
476489
});
477490
} else {
@@ -480,7 +493,7 @@ export function addAttributeCompletionEntries(
480493
name: completion.eventName,
481494
insertText: buildSnippet(insertSnippet, completion.eventName),
482495
isSnippet: insertSnippet,
483-
sortText: completion.eventName,
496+
sortText: AsciiSortPriority.First + completion.eventName,
484497
replacementSpan,
485498
});
486499
}

0 commit comments

Comments
 (0)