Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/mergeEditor/browser/utils.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 { ArrayQueue, CompareResult } from '../../../../base/common/arrays.js';
7
import { onUnexpectedError } from '../../../../base/common/errors.js';
8
import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
9
import { IObservable, autorunOpts } from '../../../../base/common/observable.js';
10
import { CodeEditorWidget } from '../../../../editor/browser/widget/codeEditor/codeEditorWidget.js';
11
import { IModelDeltaDecoration } from '../../../../editor/common/model.js';
12
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
13
14
export function setStyle(
15
element: HTMLElement,
16
style: {
17
width?: number | string;
18
height?: number | string;
19
left?: number | string;
20
top?: number | string;
21
}
22
): void {
23
Object.entries(style).forEach(([key, value]) => {
24
element.style.setProperty(key, toSize(value));
25
});
26
}
27
28
function toSize(value: number | string): string {
29
return typeof value === 'number' ? `${value}px` : value;
30
}
31
32
export function applyObservableDecorations(editor: CodeEditorWidget, decorations: IObservable<IModelDeltaDecoration[]>): IDisposable {
33
const d = new DisposableStore();
34
let decorationIds: string[] = [];
35
d.add(autorunOpts({ debugName: () => `Apply decorations from ${decorations.debugName}` }, reader => {
36
const d = decorations.read(reader);
37
editor.changeDecorations(a => {
38
decorationIds = a.deltaDecorations(decorationIds, d);
39
});
40
}));
41
d.add({
42
dispose: () => {
43
editor.changeDecorations(a => {
44
decorationIds = a.deltaDecorations(decorationIds, []);
45
});
46
}
47
});
48
return d;
49
}
50
51
export function* leftJoin<TLeft, TRight>(
52
left: Iterable<TLeft>,
53
right: readonly TRight[],
54
compare: (left: TLeft, right: TRight) => CompareResult,
55
): IterableIterator<{ left: TLeft; rights: TRight[] }> {
56
const rightQueue = new ArrayQueue(right);
57
for (const leftElement of left) {
58
rightQueue.takeWhile(rightElement => CompareResult.isGreaterThan(compare(leftElement, rightElement)));
59
const equals = rightQueue.takeWhile(rightElement => CompareResult.isNeitherLessOrGreaterThan(compare(leftElement, rightElement)));
60
yield { left: leftElement, rights: equals || [] };
61
}
62
}
63
64
export function* join<TLeft, TRight>(
65
left: Iterable<TLeft>,
66
right: readonly TRight[],
67
compare: (left: TLeft, right: TRight) => CompareResult,
68
): IterableIterator<{ left?: TLeft; rights: TRight[] }> {
69
const rightQueue = new ArrayQueue(right);
70
for (const leftElement of left) {
71
const skipped = rightQueue.takeWhile(rightElement => CompareResult.isGreaterThan(compare(leftElement, rightElement)));
72
if (skipped) {
73
yield { rights: skipped };
74
}
75
const equals = rightQueue.takeWhile(rightElement => CompareResult.isNeitherLessOrGreaterThan(compare(leftElement, rightElement)));
76
yield { left: leftElement, rights: equals || [] };
77
}
78
}
79
80
export function elementAtOrUndefined<T>(arr: T[], index: number): T | undefined {
81
return arr[index];
82
}
83
84
export function setFields<T extends {}>(obj: T, fields: Partial<T>): T {
85
return Object.assign(obj, fields);
86
}
87
88
export function deepMerge<T extends {}>(source1: T, source2: Partial<T>): T {
89
const result = {} as any as T;
90
for (const key in source1) {
91
result[key] = source1[key];
92
}
93
for (const key in source2) {
94
const source2Value = source2[key];
95
if (typeof result[key] === 'object' && source2Value && typeof source2Value === 'object') {
96
result[key] = deepMerge<any>(result[key], source2Value);
97
} else {
98
result[key] = source2Value as any;
99
}
100
}
101
return result;
102
}
103
104
export class PersistentStore<T> {
105
private hasValue = false;
106
private value: Readonly<T> | undefined = undefined;
107
108
constructor(
109
private readonly key: string,
110
@IStorageService private readonly storageService: IStorageService
111
) { }
112
113
public get(): Readonly<T> | undefined {
114
if (!this.hasValue) {
115
const value = this.storageService.get(this.key, StorageScope.PROFILE);
116
if (value !== undefined) {
117
try {
118
this.value = JSON.parse(value) as any;
119
} catch (e) {
120
onUnexpectedError(e);
121
}
122
}
123
this.hasValue = true;
124
}
125
126
return this.value;
127
}
128
129
public set(newValue: T | undefined): void {
130
this.value = newValue;
131
132
this.storageService.store(
133
this.key,
134
JSON.stringify(this.value),
135
StorageScope.PROFILE,
136
StorageTarget.USER
137
);
138
}
139
}
140
141