Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/editTelemetry/common/arcTracker.ts
3296 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
import { sumBy } from '../../../../base/common/arrays.js';
7
import { LineEdit } from '../../../../editor/common/core/edits/lineEdit.js';
8
import { AnnotatedStringEdit, BaseStringEdit, IEditData } from '../../../../editor/common/core/edits/stringEdit.js';
9
import { AbstractText } from '../../../../editor/common/core/text/abstractText.js';
10
11
/**
12
* The ARC (accepted and retained characters) counts how many characters inserted by the initial suggestion (trackedEdit)
13
* stay unmodified after a certain amount of time after acceptance.
14
*/
15
export class ArcTracker {
16
private _updatedTrackedEdit: AnnotatedStringEdit<IsTrackedEditData>;
17
private _trackedEdit: BaseStringEdit;
18
19
constructor(
20
private readonly _valueBeforeTrackedEdit: AbstractText,
21
trackedEdit: BaseStringEdit,
22
) {
23
this._trackedEdit = trackedEdit.removeCommonSuffixPrefix(_valueBeforeTrackedEdit.getValue());
24
this._updatedTrackedEdit = this._trackedEdit.mapData(() => new IsTrackedEditData(true));
25
}
26
27
getOriginalCharacterCount(): number {
28
return sumBy(this._trackedEdit.replacements, e => e.getNewLength());
29
}
30
31
/**
32
* edit must apply to _updatedTrackedEdit.apply(_valueBeforeTrackedEdit)
33
*/
34
handleEdits(edit: BaseStringEdit): void {
35
const e = edit.mapData(_d => new IsTrackedEditData(false));
36
const composedEdit = this._updatedTrackedEdit.compose(e); // (still) applies to _valueBeforeTrackedEdit
37
38
// TODO@hediet improve memory by using:
39
// composedEdit = const onlyTrackedEdit = composedEdit.decomposeSplit(e => !e.data.isTrackedEdit).e2;
40
41
this._updatedTrackedEdit = composedEdit;
42
}
43
44
getAcceptedRestrainedCharactersCount(): number {
45
const s = sumBy(this._updatedTrackedEdit.replacements, e => e.data.isTrackedEdit ? e.getNewLength() : 0);
46
return s;
47
}
48
49
getDebugState(): unknown {
50
return {
51
edits: this._updatedTrackedEdit.replacements.map(e => ({
52
range: e.replaceRange.toString(),
53
newText: e.newText,
54
isTrackedEdit: e.data.isTrackedEdit,
55
}))
56
};
57
}
58
59
public getLineCountInfo(): { deletedLineCounts: number; insertedLineCounts: number } {
60
const e = this._updatedTrackedEdit.toStringEdit(r => r.data.isTrackedEdit);
61
const le = LineEdit.fromStringEdit(e, this._valueBeforeTrackedEdit);
62
const deletedLineCount = sumBy(le.replacements, r => r.lineRange.length);
63
const insertedLineCount = sumBy(le.getNewLineRanges(), r => r.length);
64
return {
65
deletedLineCounts: deletedLineCount,
66
insertedLineCounts: insertedLineCount,
67
};
68
}
69
}
70
71
export class IsTrackedEditData implements IEditData<IsTrackedEditData> {
72
constructor(
73
public readonly isTrackedEdit: boolean
74
) { }
75
76
join(data: IsTrackedEditData): IsTrackedEditData | undefined {
77
if (this.isTrackedEdit !== data.isTrackedEdit) {
78
return undefined;
79
}
80
return this;
81
}
82
}
83
84