From ddf20ecd6db0d47c3a0efffcc1f17e5e2e50472b Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 8 May 2018 09:52:46 -0700 Subject: [PATCH] Support '.' as a trigger character (#23890) * Support '.' as a trigger character * Add a CompletionsTriggerCharacter type * Add more trigger characters * Add another type CompletionsTriggerCharacter * Update API baselines --- src/harness/fourslash.ts | 15 +++++++++++---- src/server/protocol.ts | 4 +++- src/services/completions.ts | 10 +++++++--- src/services/types.ts | 4 +++- .../baselines/reference/api/tsserverlibrary.d.ts | 6 ++++-- tests/baselines/reference/api/typescript.d.ts | 3 ++- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ff14e5b770b..5e7dede93ee 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -957,7 +957,14 @@ namespace FourSlash { } public verifyCompletionsAt(markerName: string | ReadonlyArray, expected: ReadonlyArray, options?: FourSlashInterface.CompletionsAtOptions) { - this.verifyCompletions({ marker: markerName, exact: expected, isNewIdentifierLocation: options && options.isNewIdentifierLocation, preferences: options, triggerCharacter: options && options.triggerCharacter }); + this.verifyCompletions({ + marker: markerName, + exact: expected, + isNewIdentifierLocation: options && options.isNewIdentifierLocation, + preferences: options, + // TODO: GH#20090 + triggerCharacter: (options && options.triggerCharacter) as ts.CompletionsTriggerCharacter | undefined, + }); } public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) { @@ -4719,7 +4726,7 @@ namespace FourSlashInterface { readonly sourceDisplay?: string; }; export interface CompletionsAtOptions extends Partial { - triggerCharacter?: string; + triggerCharacter?: ts.CompletionsTriggerCharacter; isNewIdentifierLocation?: boolean; } @@ -4730,13 +4737,13 @@ namespace FourSlashInterface { readonly includes?: Many; readonly excludes?: Many; readonly preferences: ts.UserPreferences; - readonly triggerCharacter?: string; + readonly triggerCharacter?: ts.CompletionsTriggerCharacter; } export type Many = T | ReadonlyArray; export interface VerifyCompletionListContainsOptions extends ts.UserPreferences { - triggerCharacter?: string; + triggerCharacter?: ts.CompletionsTriggerCharacter; sourceDisplay: string; isRecommended?: true; insertText?: string; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 3eaa42bb103..289478e7453 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1765,6 +1765,8 @@ namespace ts.server.protocol { arguments: FormatOnKeyRequestArgs; } + export type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<"; + /** * Arguments for completions messages. */ @@ -1773,7 +1775,7 @@ namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; - triggerCharacter?: string; + triggerCharacter?: CompletionsTriggerCharacter; /** * @deprecated Use UserPreferences.includeCompletionsForModuleExports */ diff --git a/src/services/completions.ts b/src/services/completions.ts index ef1bd5ebd3c..4950d1370e1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -25,7 +25,7 @@ namespace ts.Completions { const enum GlobalsSearch { Continue, Success, Fail } - export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: string | undefined): CompletionInfo | undefined { + export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: CompletionsTriggerCharacter | undefined): CompletionInfo | undefined { const typeChecker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); if (isInReferenceComment(sourceFile, position)) { @@ -2208,8 +2208,12 @@ namespace ts.Completions { return !!type.getStringIndexType() || !!type.getNumberIndexType(); } - function isValidTrigger(sourceFile: SourceFile, triggerCharacter: string, contextToken: Node, position: number): boolean { + function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node, position: number): boolean { switch (triggerCharacter) { + case ".": + case "/": + case "@": + return true; case '"': case "'": case "`": @@ -2219,7 +2223,7 @@ namespace ts.Completions { // Opening JSX tag return contextToken.kind === SyntaxKind.LessThanToken && contextToken.parent.kind !== SyntaxKind.BinaryExpression; default: - return Debug.fail(triggerCharacter); + return Debug.assertNever(triggerCharacter); } } diff --git a/src/services/types.ts b/src/services/types.ts index d71b315f29a..c103d2f4ba0 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -358,9 +358,11 @@ namespace ts { export type OrganizeImportsScope = CombinedCodeFixScope; + export type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<"; + export interface GetCompletionsAtPositionOptions extends UserPreferences { /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ - triggerCharacter?: string; + triggerCharacter?: CompletionsTriggerCharacter; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1e2d3bbc605..5f86c40a919 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4539,9 +4539,10 @@ declare namespace ts { fileName: string; } type OrganizeImportsScope = CombinedCodeFixScope; + type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<"; interface GetCompletionsAtPositionOptions extends UserPreferences { /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ - triggerCharacter?: string; + triggerCharacter?: CompletionsTriggerCharacter; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */ @@ -6777,6 +6778,7 @@ declare namespace ts.server.protocol { command: CommandTypes.Formatonkey; arguments: FormatOnKeyRequestArgs; } + type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<"; /** * Arguments for completions messages. */ @@ -6785,7 +6787,7 @@ declare namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; - triggerCharacter?: string; + triggerCharacter?: CompletionsTriggerCharacter; /** * @deprecated Use UserPreferences.includeCompletionsForModuleExports */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b6dbb1d54dd..342d609d060 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4539,9 +4539,10 @@ declare namespace ts { fileName: string; } type OrganizeImportsScope = CombinedCodeFixScope; + type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<"; interface GetCompletionsAtPositionOptions extends UserPreferences { /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ - triggerCharacter?: string; + triggerCharacter?: CompletionsTriggerCharacter; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */