Path: blob/main/extensions/copilot/src/platform/inlineEdits/common/editReason.ts
13400 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/456export class EditReason {7public static create(metadata: ITextModelEditReasonMetadata | undefined): EditReason {8if (!metadata) {9return EditReason.unknown;10}11return new EditReason(metadata);12}1314private constructor(15public readonly metadata: ITextModelEditReasonMetadata,16) {17}1819public static readonly unknown = new EditReason({ source: 'unknown', name: undefined });2021toKey(level: number): string {22return new TextModelEditReason(this.metadata, privateSymbol).toKey(level);23}24}252627const privateSymbol = Symbol('TextModelEditReason');2829export class TextModelEditReason {30constructor(31public readonly metadata: ITextModelEditReasonMetadata,32_privateCtorGuard: typeof privateSymbol,33) { }3435public toString(): string {36return `${this.metadata.source}`;37}3839public getType(): string {40const metadata = this.metadata;41switch (metadata.source) {42case 'cursor':43return metadata.kind;44case 'inlineCompletionAccept':45return metadata.source + (metadata.$nes ? ':nes' : '');46case 'unknown':47return metadata.name || 'unknown';48default:49return metadata.source;50}51}5253/**54* Converts the metadata to a key string.55* Only includes properties/values that have `level` many `$` prefixes or less.56*/57public toKey(level: number): string {58const metadata = this.metadata;59const keys = Object.entries(metadata).filter(([key, value]) => {60const prefixCount = (key.match(/\$/g) || []).length;61return prefixCount <= level && value !== undefined && value !== null && value !== '';62}).map(([key, value]) => `${key}:${value}`);63return keys.join('-');64}65}6667type TextModelEditReasonT<T> = TextModelEditReason & {68metadataT: T;69};7071function createEditReason<T extends Record<string, any>>(metadata: T): TextModelEditReasonT<T> {72return new TextModelEditReason(metadata as any, privateSymbol) as any;73}7475export const EditReasons = {76unknown(data: { name?: string | null }) {77return createEditReason({78source: 'unknown',79name: data.name,80} as const);81},8283chatApplyEdits(data: { modelId: string | undefined }) {84return createEditReason({85source: 'Chat.applyEdits',86$modelId: data.modelId,87} as const);88},8990inlineCompletionAccept(data: { nes: boolean; requestUuid: string; extensionId: string }) {91return createEditReason({92source: 'inlineCompletionAccept',93$nes: data.nes,94$extensionId: data.extensionId,95$$requestUuid: data.requestUuid,96} as const);97},9899inlineCompletionPartialAccept(data: { nes: boolean; requestUuid: string; extensionId: string; type: 'word' | 'line' }) {100return createEditReason({101source: 'inlineCompletionPartialAccept',102type: data.type,103$extensionId: data.extensionId,104$$requestUuid: data.requestUuid,105} as const);106},107108inlineChatApplyEdit(data: { modelId: string | undefined }) {109return createEditReason({110source: 'inlineChat.applyEdits',111$modelId: data.modelId,112} as const);113},114115reloadFromDisk: () => createEditReason({ source: 'reloadFromDisk' } as const),116117cursor(data: { kind: 'compositionType' | 'compositionEnd' | 'type' | 'paste' | 'cut' | 'executeCommands' | 'executeCommand'; detailedSource?: string | null }) {118return createEditReason({119source: 'cursor',120kind: data.kind,121detailedSource: data.detailedSource,122} as const);123},124125setValue: () => createEditReason({ source: 'setValue' } as const),126eolChange: () => createEditReason({ source: 'eolChange' } as const),127applyEdits: () => createEditReason({ source: 'applyEdits' } as const),128snippet: () => createEditReason({ source: 'snippet' } as const),129suggest: (data: { extensionId: string | undefined }) => createEditReason({ source: 'suggest', $extensionId: data.extensionId } as const),130};131132type Values<T> = T[keyof T];133type ITextModelEditReasonMetadata = Values<{ [TKey in keyof typeof EditReasons]: ReturnType<typeof EditReasons[TKey]>['metadataT'] }>;134135136