Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/inlineEdits/common/editReason.ts
13400 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
7
export class EditReason {
8
public static create(metadata: ITextModelEditReasonMetadata | undefined): EditReason {
9
if (!metadata) {
10
return EditReason.unknown;
11
}
12
return new EditReason(metadata);
13
}
14
15
private constructor(
16
public readonly metadata: ITextModelEditReasonMetadata,
17
) {
18
}
19
20
public static readonly unknown = new EditReason({ source: 'unknown', name: undefined });
21
22
toKey(level: number): string {
23
return new TextModelEditReason(this.metadata, privateSymbol).toKey(level);
24
}
25
}
26
27
28
const privateSymbol = Symbol('TextModelEditReason');
29
30
export class TextModelEditReason {
31
constructor(
32
public readonly metadata: ITextModelEditReasonMetadata,
33
_privateCtorGuard: typeof privateSymbol,
34
) { }
35
36
public toString(): string {
37
return `${this.metadata.source}`;
38
}
39
40
public getType(): string {
41
const metadata = this.metadata;
42
switch (metadata.source) {
43
case 'cursor':
44
return metadata.kind;
45
case 'inlineCompletionAccept':
46
return metadata.source + (metadata.$nes ? ':nes' : '');
47
case 'unknown':
48
return metadata.name || 'unknown';
49
default:
50
return metadata.source;
51
}
52
}
53
54
/**
55
* Converts the metadata to a key string.
56
* Only includes properties/values that have `level` many `$` prefixes or less.
57
*/
58
public toKey(level: number): string {
59
const metadata = this.metadata;
60
const keys = Object.entries(metadata).filter(([key, value]) => {
61
const prefixCount = (key.match(/\$/g) || []).length;
62
return prefixCount <= level && value !== undefined && value !== null && value !== '';
63
}).map(([key, value]) => `${key}:${value}`);
64
return keys.join('-');
65
}
66
}
67
68
type TextModelEditReasonT<T> = TextModelEditReason & {
69
metadataT: T;
70
};
71
72
function createEditReason<T extends Record<string, any>>(metadata: T): TextModelEditReasonT<T> {
73
return new TextModelEditReason(metadata as any, privateSymbol) as any;
74
}
75
76
export const EditReasons = {
77
unknown(data: { name?: string | null }) {
78
return createEditReason({
79
source: 'unknown',
80
name: data.name,
81
} as const);
82
},
83
84
chatApplyEdits(data: { modelId: string | undefined }) {
85
return createEditReason({
86
source: 'Chat.applyEdits',
87
$modelId: data.modelId,
88
} as const);
89
},
90
91
inlineCompletionAccept(data: { nes: boolean; requestUuid: string; extensionId: string }) {
92
return createEditReason({
93
source: 'inlineCompletionAccept',
94
$nes: data.nes,
95
$extensionId: data.extensionId,
96
$$requestUuid: data.requestUuid,
97
} as const);
98
},
99
100
inlineCompletionPartialAccept(data: { nes: boolean; requestUuid: string; extensionId: string; type: 'word' | 'line' }) {
101
return createEditReason({
102
source: 'inlineCompletionPartialAccept',
103
type: data.type,
104
$extensionId: data.extensionId,
105
$$requestUuid: data.requestUuid,
106
} as const);
107
},
108
109
inlineChatApplyEdit(data: { modelId: string | undefined }) {
110
return createEditReason({
111
source: 'inlineChat.applyEdits',
112
$modelId: data.modelId,
113
} as const);
114
},
115
116
reloadFromDisk: () => createEditReason({ source: 'reloadFromDisk' } as const),
117
118
cursor(data: { kind: 'compositionType' | 'compositionEnd' | 'type' | 'paste' | 'cut' | 'executeCommands' | 'executeCommand'; detailedSource?: string | null }) {
119
return createEditReason({
120
source: 'cursor',
121
kind: data.kind,
122
detailedSource: data.detailedSource,
123
} as const);
124
},
125
126
setValue: () => createEditReason({ source: 'setValue' } as const),
127
eolChange: () => createEditReason({ source: 'eolChange' } as const),
128
applyEdits: () => createEditReason({ source: 'applyEdits' } as const),
129
snippet: () => createEditReason({ source: 'snippet' } as const),
130
suggest: (data: { extensionId: string | undefined }) => createEditReason({ source: 'suggest', $extensionId: data.extensionId } as const),
131
};
132
133
type Values<T> = T[keyof T];
134
type ITextModelEditReasonMetadata = Values<{ [TKey in keyof typeof EditReasons]: ReturnType<typeof EditReasons[TKey]>['metadataT'] }>;
135
136