diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b6cc2e4d8fd..62c81fca2ac 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -546,7 +546,15 @@ namespace ts.server.protocol { command: CommandTypes.GetApplicableRefactors; arguments: GetApplicableRefactorsRequestArgs; } - export type GetApplicableRefactorsRequestArgs = FileLocationOrRangeRequestArgs; + export type GetApplicableRefactorsRequestArgs = FileLocationOrRangeRequestArgs & { + triggerReason?: RefactorTriggerReason; + }; + + export type RefactorTriggerReason = RefactorInvokedReason; + + export interface RefactorInvokedReason { + kind: 'invoked'; + } /** * Response is a list of available refactorings. diff --git a/src/server/session.ts b/src/server/session.ts index 3f0321074a9..780c7ab5085 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1970,7 +1970,7 @@ namespace ts.server { private getApplicableRefactors(args: protocol.GetApplicableRefactorsRequestArgs): protocol.ApplicableRefactorInfo[] { const { file, project } = this.getFileAndProject(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file)!; - return project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); + return project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file), args.triggerReason); } private getEditsForRefactor(args: protocol.GetEditsForRefactorRequestArgs, simplifiedResult: boolean): RefactorEditInfo | protocol.RefactorEditInfo { diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts index c7c3a04e8d3..1256de9cfbe 100644 --- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -16,8 +16,8 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { } function getAvailableActions(context: RefactorContext): readonly ApplicableRefactorInfo[] { - const { file, startPosition } = context; - const info = getConvertibleArrowFunctionAtPosition(file, startPosition); + const { file, startPosition, triggerReason } = context; + const info = getConvertibleArrowFunctionAtPosition(file, startPosition, triggerReason); if (!info) return emptyArray; return [{ @@ -70,7 +70,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { return { renameFilename: undefined, renameLocation: undefined, edits }; } - function getConvertibleArrowFunctionAtPosition(file: SourceFile, startPosition: number): Info | undefined { + function getConvertibleArrowFunctionAtPosition(file: SourceFile, startPosition: number, triggerReason?: RefactorTriggerReason): Info | undefined { const node = getTokenAtPosition(file, startPosition); const func = getContainingFunction(node); if (!func || !isArrowFunction(func) || (!rangeContainsRange(func, node) || rangeContainsRange(func.body, node))) return undefined; diff --git a/src/services/services.ts b/src/services/services.ts index 28cf22ec473..5cfeb2b7542 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2140,7 +2140,7 @@ namespace ts { return Rename.getRenameInfo(program, getValidSourceFile(fileName), position, options); } - function getRefactorContext(file: SourceFile, positionOrRange: number | TextRange, preferences: UserPreferences, formatOptions?: FormatCodeSettings): RefactorContext { + function getRefactorContext(file: SourceFile, positionOrRange: number | TextRange, preferences: UserPreferences, formatOptions?: FormatCodeSettings, triggerReason?: RefactorTriggerReason): RefactorContext { const [startPosition, endPosition] = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end]; return { file, @@ -2151,6 +2151,7 @@ namespace ts { formatContext: formatting.getFormatContext(formatOptions!, host), // TODO: GH#18217 cancellationToken, preferences, + triggerReason, }; } @@ -2158,10 +2159,10 @@ namespace ts { return SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName)); } - function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions): ApplicableRefactorInfo[] { + function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions, triggerReason: RefactorTriggerReason): ApplicableRefactorInfo[] { synchronizeHostData(); const file = getValidSourceFile(fileName); - return refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences)); + return refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences, undefined, triggerReason)); } function getEditsForRefactor( diff --git a/src/services/types.ts b/src/services/types.ts index fd8ade8f8e6..ff85050def7 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -475,7 +475,7 @@ namespace ts { /** @deprecated `fileName` will be ignored */ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; - getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; + getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[]; getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[]; @@ -741,6 +741,12 @@ namespace ts { commands?: CodeActionCommand[]; } + export type RefactorTriggerReason = RefactorInvokedReason; + + export interface RefactorInvokedReason { + kind: 'invoked'; + } + export interface TextInsertion { newText: string; /** The position in newText the caret should point to after the insertion. */ @@ -1404,5 +1410,6 @@ namespace ts { program: Program; cancellationToken?: CancellationToken; preferences: UserPreferences; + triggerReason?: RefactorTriggerReason; } }