Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(language-service): Prioritize Angular-specific completions over DOM completions #45293

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 21 additions & 8 deletions packages/language-service/src/attribute_completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,19 @@ function buildSnippet(insertSnippet: true|undefined, text: string): string|undef
return insertSnippet ? `${text}="$1"` : undefined;
}

/**
* Used to ensure Angular completions appear before DOM completions. Inputs and Outputs are
* prioritized first while attributes which would match an additional directive are prioritized
* second.
*
* This sort priority is based on the ASCII table. Other than `space`, the `!` is the first
* printable character in the ASCII ordering.
*/
enum AsciiSortPriority {
First = '!',
Second = '"',
}

/**
* Given an `AttributeCompletion`, add any available completions to a `ts.CompletionEntry` array of
* results.
Expand All @@ -399,7 +412,7 @@ export function addAttributeCompletionEntries(
entries.push({
kind: unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
name: completion.attribute,
sortText: completion.attribute,
sortText: AsciiSortPriority.Second + completion.attribute,
replacementSpan,
});
break;
Expand All @@ -414,7 +427,7 @@ export function addAttributeCompletionEntries(
name: prefix + completion.attribute,
insertText: buildSnippet(insertSnippet, prefix + completion.attribute),
isSnippet: insertSnippet,
sortText: prefix + completion.attribute,
sortText: AsciiSortPriority.Second + prefix + completion.attribute,
replacementSpan,
});
break;
Expand All @@ -427,7 +440,7 @@ export function addAttributeCompletionEntries(
name: `[${completion.propertyName}]`,
insertText: buildSnippet(insertSnippet, `[${completion.propertyName}]`),
isSnippet: insertSnippet,
sortText: completion.propertyName,
sortText: AsciiSortPriority.First + completion.propertyName,
replacementSpan,
});
// If the directive supports banana-in-a-box for this input, offer that as well.
Expand All @@ -438,7 +451,7 @@ export function addAttributeCompletionEntries(
insertText: buildSnippet(insertSnippet, `[(${completion.propertyName})]`),
isSnippet: insertSnippet,
// This completion should sort after the property binding.
sortText: completion.propertyName + '_1',
sortText: AsciiSortPriority.First + completion.propertyName + '_1',
replacementSpan,
});
}
Expand All @@ -449,7 +462,7 @@ export function addAttributeCompletionEntries(
insertText: buildSnippet(insertSnippet, completion.propertyName),
isSnippet: insertSnippet,
// This completion should sort after both property binding options (one-way and two-way).
sortText: completion.propertyName + '_2',
sortText: AsciiSortPriority.First + completion.propertyName + '_2',
replacementSpan,
});
} else {
Expand All @@ -458,7 +471,7 @@ export function addAttributeCompletionEntries(
name: completion.propertyName,
insertText: buildSnippet(insertSnippet, completion.propertyName),
isSnippet: insertSnippet,
sortText: completion.propertyName,
sortText: AsciiSortPriority.First + completion.propertyName,
replacementSpan,
});
}
Expand All @@ -471,7 +484,7 @@ export function addAttributeCompletionEntries(
name: `(${completion.eventName})`,
insertText: buildSnippet(insertSnippet, `(${completion.eventName})`),
isSnippet: insertSnippet,
sortText: completion.eventName,
sortText: AsciiSortPriority.First + completion.eventName,
replacementSpan,
});
} else {
Expand All @@ -480,7 +493,7 @@ export function addAttributeCompletionEntries(
name: completion.eventName,
insertText: buildSnippet(insertSnippet, completion.eventName),
isSnippet: insertSnippet,
sortText: completion.eventName,
sortText: AsciiSortPriority.First + completion.eventName,
replacementSpan,
});
}
Expand Down