@codingame/monaco-vscode-working-copy-service-override 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/workingCopy.js +2 -2
- package/external/tslib/tslib.es6.js +0 -11
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupService.js +0 -25
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupTracker.js +0 -45
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyHistoryService.js +0 -30
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.js +0 -454
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.js +0 -255
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.js +0 -618
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.js +0 -164
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
-
import { localizeWithPath } from 'vscode/vscode/vs/nls';
|
|
3
|
-
import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
|
|
4
|
-
import { assertIsDefined } from 'vscode/vscode/vs/base/common/types';
|
|
5
|
-
import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
|
|
6
|
-
import { Extensions } from 'vscode/vscode/vs/workbench/common/contributions';
|
|
7
|
-
import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
|
|
8
|
-
import { WorkingCopyHistoryTracker } from './workingCopyHistoryTracker.js';
|
|
9
|
-
import { Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
10
|
-
import { MAX_PARALLEL_HISTORY_IO_OPS } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyHistory';
|
|
11
|
-
import { FileOperationError, IFileService } from 'vscode/vscode/vs/platform/files/common/files';
|
|
12
|
-
import { IRemoteAgentService } from 'vscode/vscode/vs/workbench/services/remote/common/remoteAgentService';
|
|
13
|
-
import { URI } from 'vscode/vscode/vs/base/common/uri';
|
|
14
|
-
import { Limiter, DeferredPromise, RunOnceScheduler } from 'vscode/vscode/vs/base/common/async';
|
|
15
|
-
import { extname, joinPath, isEqual, dirname } from 'vscode/vscode/vs/base/common/resources';
|
|
16
|
-
import { IWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/common/environmentService';
|
|
17
|
-
import { hash } from 'vscode/vscode/vs/base/common/hash';
|
|
18
|
-
import { randomPath, indexOfPath } from 'vscode/vscode/vs/base/common/extpath';
|
|
19
|
-
import { CancellationToken, CancellationTokenSource } from 'vscode/vscode/vs/base/common/cancellation';
|
|
20
|
-
import { ResourceMap } from 'vscode/vscode/vs/base/common/map';
|
|
21
|
-
import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
|
|
22
|
-
import { ILabelService } from 'vscode/vscode/vs/platform/label/common/label';
|
|
23
|
-
import { VSBuffer } from 'vscode/vscode/vs/base/common/buffer';
|
|
24
|
-
import { ILogService } from 'vscode/vscode/vs/platform/log/common/log';
|
|
25
|
-
import { SaveSourceRegistry } from 'vscode/vscode/vs/workbench/common/editor';
|
|
26
|
-
import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
|
|
27
|
-
import { lastOrDefault } from 'vscode/vscode/vs/base/common/arrays';
|
|
28
|
-
import { escapeRegExpCharacters } from 'vscode/vscode/vs/base/common/strings';
|
|
29
|
-
|
|
30
|
-
var WorkingCopyHistoryService_1, NativeWorkingCopyHistoryService_1;
|
|
31
|
-
class WorkingCopyHistoryModel {
|
|
32
|
-
static { this.ENTRIES_FILE = 'entries.json'; }
|
|
33
|
-
static { this.FILE_SAVED_SOURCE = SaveSourceRegistry.registerSource('default.source', ( localizeWithPath(
|
|
34
|
-
'vs/workbench/services/workingCopy/common/workingCopyHistoryService',
|
|
35
|
-
'default.source',
|
|
36
|
-
"File Saved"
|
|
37
|
-
))); }
|
|
38
|
-
static { this.SETTINGS = {
|
|
39
|
-
MAX_ENTRIES: 'workbench.localHistory.maxFileEntries',
|
|
40
|
-
MERGE_PERIOD: 'workbench.localHistory.mergeWindow'
|
|
41
|
-
}; }
|
|
42
|
-
constructor(workingCopyResource, historyHome, entryAddedEmitter, entryChangedEmitter, entryReplacedEmitter, entryRemovedEmitter, options, fileService, labelService, logService, configurationService) {
|
|
43
|
-
this.historyHome = historyHome;
|
|
44
|
-
this.entryAddedEmitter = entryAddedEmitter;
|
|
45
|
-
this.entryChangedEmitter = entryChangedEmitter;
|
|
46
|
-
this.entryReplacedEmitter = entryReplacedEmitter;
|
|
47
|
-
this.entryRemovedEmitter = entryRemovedEmitter;
|
|
48
|
-
this.options = options;
|
|
49
|
-
this.fileService = fileService;
|
|
50
|
-
this.labelService = labelService;
|
|
51
|
-
this.logService = logService;
|
|
52
|
-
this.configurationService = configurationService;
|
|
53
|
-
this.entries = [];
|
|
54
|
-
this.whenResolved = undefined;
|
|
55
|
-
this.workingCopyResource = undefined;
|
|
56
|
-
this.workingCopyName = undefined;
|
|
57
|
-
this.historyEntriesFolder = undefined;
|
|
58
|
-
this.historyEntriesListingFile = undefined;
|
|
59
|
-
this.historyEntriesNameMatcher = undefined;
|
|
60
|
-
this.versionId = 0;
|
|
61
|
-
this.storedVersionId = this.versionId;
|
|
62
|
-
this.storeLimiter = ( new Limiter(1));
|
|
63
|
-
this.setWorkingCopy(workingCopyResource);
|
|
64
|
-
}
|
|
65
|
-
setWorkingCopy(workingCopyResource) {
|
|
66
|
-
this.workingCopyResource = workingCopyResource;
|
|
67
|
-
this.workingCopyName = this.labelService.getUriBasenameLabel(workingCopyResource);
|
|
68
|
-
this.historyEntriesNameMatcher = ( new RegExp(`[A-Za-z0-9]{4}${escapeRegExpCharacters(extname(workingCopyResource))}`));
|
|
69
|
-
this.historyEntriesFolder = this.toHistoryEntriesFolder(this.historyHome, workingCopyResource);
|
|
70
|
-
this.historyEntriesListingFile = joinPath(this.historyEntriesFolder, WorkingCopyHistoryModel.ENTRIES_FILE);
|
|
71
|
-
this.entries = [];
|
|
72
|
-
this.whenResolved = undefined;
|
|
73
|
-
}
|
|
74
|
-
toHistoryEntriesFolder(historyHome, workingCopyResource) {
|
|
75
|
-
return joinPath(historyHome, ( hash(( workingCopyResource.toString())).toString(16)));
|
|
76
|
-
}
|
|
77
|
-
async addEntry(source = WorkingCopyHistoryModel.FILE_SAVED_SOURCE, timestamp = Date.now(), token) {
|
|
78
|
-
let entryToReplace = undefined;
|
|
79
|
-
const lastEntry = lastOrDefault(this.entries);
|
|
80
|
-
if (lastEntry && lastEntry.source === source) {
|
|
81
|
-
const configuredReplaceInterval = this.configurationService.getValue(WorkingCopyHistoryModel.SETTINGS.MERGE_PERIOD, { resource: this.workingCopyResource });
|
|
82
|
-
if (timestamp - lastEntry.timestamp <= ((configuredReplaceInterval * 1000) )) {
|
|
83
|
-
entryToReplace = lastEntry;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
let entry;
|
|
87
|
-
if (entryToReplace) {
|
|
88
|
-
entry = await this.doReplaceEntry(entryToReplace, timestamp, token);
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
entry = await this.doAddEntry(source, timestamp, token);
|
|
92
|
-
}
|
|
93
|
-
if (this.options.flushOnChange && !token.isCancellationRequested) {
|
|
94
|
-
await this.store(token);
|
|
95
|
-
}
|
|
96
|
-
return entry;
|
|
97
|
-
}
|
|
98
|
-
async doAddEntry(source, timestamp, token) {
|
|
99
|
-
const workingCopyResource = assertIsDefined(this.workingCopyResource);
|
|
100
|
-
const workingCopyName = assertIsDefined(this.workingCopyName);
|
|
101
|
-
const historyEntriesFolder = assertIsDefined(this.historyEntriesFolder);
|
|
102
|
-
const id = `${randomPath(undefined, undefined, 4)}${extname(workingCopyResource)}`;
|
|
103
|
-
const location = joinPath(historyEntriesFolder, id);
|
|
104
|
-
await this.fileService.cloneFile(workingCopyResource, location);
|
|
105
|
-
const entry = {
|
|
106
|
-
id,
|
|
107
|
-
workingCopy: { resource: workingCopyResource, name: workingCopyName },
|
|
108
|
-
location,
|
|
109
|
-
timestamp,
|
|
110
|
-
source
|
|
111
|
-
};
|
|
112
|
-
this.entries.push(entry);
|
|
113
|
-
this.versionId++;
|
|
114
|
-
this.entryAddedEmitter.fire({ entry });
|
|
115
|
-
return entry;
|
|
116
|
-
}
|
|
117
|
-
async doReplaceEntry(entry, timestamp, token) {
|
|
118
|
-
const workingCopyResource = assertIsDefined(this.workingCopyResource);
|
|
119
|
-
await this.fileService.cloneFile(workingCopyResource, entry.location);
|
|
120
|
-
entry.timestamp = timestamp;
|
|
121
|
-
this.versionId++;
|
|
122
|
-
this.entryReplacedEmitter.fire({ entry });
|
|
123
|
-
return entry;
|
|
124
|
-
}
|
|
125
|
-
async removeEntry(entry, token) {
|
|
126
|
-
await this.resolveEntriesOnce();
|
|
127
|
-
if (token.isCancellationRequested) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
const index = this.entries.indexOf(entry);
|
|
131
|
-
if (index === -1) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
await this.deleteEntry(entry);
|
|
135
|
-
this.entries.splice(index, 1);
|
|
136
|
-
this.versionId++;
|
|
137
|
-
this.entryRemovedEmitter.fire({ entry });
|
|
138
|
-
if (this.options.flushOnChange && !token.isCancellationRequested) {
|
|
139
|
-
await this.store(token);
|
|
140
|
-
}
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
async updateEntry(entry, properties, token) {
|
|
144
|
-
await this.resolveEntriesOnce();
|
|
145
|
-
if (token.isCancellationRequested) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const index = this.entries.indexOf(entry);
|
|
149
|
-
if (index === -1) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
entry.source = properties.source;
|
|
153
|
-
this.versionId++;
|
|
154
|
-
this.entryChangedEmitter.fire({ entry });
|
|
155
|
-
if (this.options.flushOnChange && !token.isCancellationRequested) {
|
|
156
|
-
await this.store(token);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
async getEntries() {
|
|
160
|
-
await this.resolveEntriesOnce();
|
|
161
|
-
const configuredMaxEntries = this.configurationService.getValue(WorkingCopyHistoryModel.SETTINGS.MAX_ENTRIES, { resource: this.workingCopyResource });
|
|
162
|
-
if (this.entries.length > configuredMaxEntries) {
|
|
163
|
-
return this.entries.slice(this.entries.length - configuredMaxEntries);
|
|
164
|
-
}
|
|
165
|
-
return this.entries;
|
|
166
|
-
}
|
|
167
|
-
async hasEntries(skipResolve) {
|
|
168
|
-
if (!skipResolve) {
|
|
169
|
-
await this.resolveEntriesOnce();
|
|
170
|
-
}
|
|
171
|
-
return this.entries.length > 0;
|
|
172
|
-
}
|
|
173
|
-
resolveEntriesOnce() {
|
|
174
|
-
if (!this.whenResolved) {
|
|
175
|
-
this.whenResolved = this.doResolveEntries();
|
|
176
|
-
}
|
|
177
|
-
return this.whenResolved;
|
|
178
|
-
}
|
|
179
|
-
async doResolveEntries() {
|
|
180
|
-
const entries = await this.resolveEntriesFromDisk();
|
|
181
|
-
for (const entry of this.entries) {
|
|
182
|
-
entries.set(entry.id, entry);
|
|
183
|
-
}
|
|
184
|
-
this.entries = Array.from(( entries.values())).sort((entryA, entryB) => entryA.timestamp - entryB.timestamp);
|
|
185
|
-
}
|
|
186
|
-
async resolveEntriesFromDisk() {
|
|
187
|
-
const workingCopyResource = assertIsDefined(this.workingCopyResource);
|
|
188
|
-
const workingCopyName = assertIsDefined(this.workingCopyName);
|
|
189
|
-
const [entryListing, entryStats] = await Promise.all([
|
|
190
|
-
this.readEntriesFile(),
|
|
191
|
-
this.readEntriesFolder()
|
|
192
|
-
]);
|
|
193
|
-
const entries = ( new Map());
|
|
194
|
-
if (entryStats) {
|
|
195
|
-
for (const entryStat of entryStats) {
|
|
196
|
-
entries.set(entryStat.name, {
|
|
197
|
-
id: entryStat.name,
|
|
198
|
-
workingCopy: { resource: workingCopyResource, name: workingCopyName },
|
|
199
|
-
location: entryStat.resource,
|
|
200
|
-
timestamp: entryStat.mtime,
|
|
201
|
-
source: WorkingCopyHistoryModel.FILE_SAVED_SOURCE
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (entryListing) {
|
|
206
|
-
for (const entry of entryListing.entries) {
|
|
207
|
-
const existingEntry = entries.get(entry.id);
|
|
208
|
-
if (existingEntry) {
|
|
209
|
-
entries.set(entry.id, {
|
|
210
|
-
...existingEntry,
|
|
211
|
-
timestamp: entry.timestamp,
|
|
212
|
-
source: entry.source ?? existingEntry.source
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return entries;
|
|
218
|
-
}
|
|
219
|
-
async moveEntries(targetWorkingCopyResource, source, token) {
|
|
220
|
-
await this.store(token);
|
|
221
|
-
if (token.isCancellationRequested) {
|
|
222
|
-
return undefined;
|
|
223
|
-
}
|
|
224
|
-
const sourceHistoryEntriesFolder = assertIsDefined(this.historyEntriesFolder);
|
|
225
|
-
const targetHistoryFolder = this.toHistoryEntriesFolder(this.historyHome, targetWorkingCopyResource);
|
|
226
|
-
try {
|
|
227
|
-
await this.fileService.move(sourceHistoryEntriesFolder, targetHistoryFolder, true);
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
if (!((error instanceof FileOperationError && error.fileOperationResult === 1) )) {
|
|
231
|
-
this.traceError(error);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
this.setWorkingCopy(targetWorkingCopyResource);
|
|
235
|
-
await this.addEntry(source, undefined, token);
|
|
236
|
-
await this.store(token);
|
|
237
|
-
}
|
|
238
|
-
async store(token) {
|
|
239
|
-
if (!this.shouldStore()) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
await this.storeLimiter.queue(async () => {
|
|
243
|
-
if (token.isCancellationRequested || !this.shouldStore()) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
return this.doStore(token);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
shouldStore() {
|
|
250
|
-
return this.storedVersionId !== this.versionId;
|
|
251
|
-
}
|
|
252
|
-
async doStore(token) {
|
|
253
|
-
const historyEntriesFolder = assertIsDefined(this.historyEntriesFolder);
|
|
254
|
-
await this.resolveEntriesOnce();
|
|
255
|
-
if (token.isCancellationRequested) {
|
|
256
|
-
return undefined;
|
|
257
|
-
}
|
|
258
|
-
await this.cleanUpEntries();
|
|
259
|
-
const storedVersion = this.versionId;
|
|
260
|
-
if (this.entries.length === 0) {
|
|
261
|
-
try {
|
|
262
|
-
await this.fileService.del(historyEntriesFolder, { recursive: true });
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
this.traceError(error);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
await this.writeEntriesFile();
|
|
270
|
-
}
|
|
271
|
-
this.storedVersionId = storedVersion;
|
|
272
|
-
}
|
|
273
|
-
async cleanUpEntries() {
|
|
274
|
-
const configuredMaxEntries = this.configurationService.getValue(WorkingCopyHistoryModel.SETTINGS.MAX_ENTRIES, { resource: this.workingCopyResource });
|
|
275
|
-
if (this.entries.length <= configuredMaxEntries) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
const entriesToDelete = this.entries.slice(0, this.entries.length - configuredMaxEntries);
|
|
279
|
-
const entriesToKeep = this.entries.slice(this.entries.length - configuredMaxEntries);
|
|
280
|
-
for (const entryToDelete of entriesToDelete) {
|
|
281
|
-
await this.deleteEntry(entryToDelete);
|
|
282
|
-
}
|
|
283
|
-
this.entries = entriesToKeep;
|
|
284
|
-
for (const entry of entriesToDelete) {
|
|
285
|
-
this.entryRemovedEmitter.fire({ entry });
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async deleteEntry(entry) {
|
|
289
|
-
try {
|
|
290
|
-
await this.fileService.del(entry.location);
|
|
291
|
-
}
|
|
292
|
-
catch (error) {
|
|
293
|
-
this.traceError(error);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
async writeEntriesFile() {
|
|
297
|
-
const workingCopyResource = assertIsDefined(this.workingCopyResource);
|
|
298
|
-
const historyEntriesListingFile = assertIsDefined(this.historyEntriesListingFile);
|
|
299
|
-
const serializedModel = {
|
|
300
|
-
version: 1,
|
|
301
|
-
resource: ( workingCopyResource.toString()),
|
|
302
|
-
entries: ( this.entries.map(entry => {
|
|
303
|
-
return {
|
|
304
|
-
id: entry.id,
|
|
305
|
-
source: entry.source !== WorkingCopyHistoryModel.FILE_SAVED_SOURCE ? entry.source : undefined,
|
|
306
|
-
timestamp: entry.timestamp
|
|
307
|
-
};
|
|
308
|
-
}))
|
|
309
|
-
};
|
|
310
|
-
await this.fileService.writeFile(historyEntriesListingFile, VSBuffer.fromString(JSON.stringify(serializedModel)));
|
|
311
|
-
}
|
|
312
|
-
async readEntriesFile() {
|
|
313
|
-
const historyEntriesListingFile = assertIsDefined(this.historyEntriesListingFile);
|
|
314
|
-
let serializedModel = undefined;
|
|
315
|
-
try {
|
|
316
|
-
serializedModel = JSON.parse(( (await this.fileService.readFile(historyEntriesListingFile)).value.toString()));
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
if (!((error instanceof FileOperationError && error.fileOperationResult === 1) )) {
|
|
320
|
-
this.traceError(error);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return serializedModel;
|
|
324
|
-
}
|
|
325
|
-
async readEntriesFolder() {
|
|
326
|
-
const historyEntriesFolder = assertIsDefined(this.historyEntriesFolder);
|
|
327
|
-
const historyEntriesNameMatcher = assertIsDefined(this.historyEntriesNameMatcher);
|
|
328
|
-
let rawEntries = undefined;
|
|
329
|
-
try {
|
|
330
|
-
rawEntries = (await this.fileService.resolve(historyEntriesFolder, { resolveMetadata: true })).children;
|
|
331
|
-
}
|
|
332
|
-
catch (error) {
|
|
333
|
-
if (!((error instanceof FileOperationError && error.fileOperationResult === 1) )) {
|
|
334
|
-
this.traceError(error);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (!rawEntries) {
|
|
338
|
-
return undefined;
|
|
339
|
-
}
|
|
340
|
-
return rawEntries.filter(entry => !isEqual(entry.resource, this.historyEntriesListingFile) &&
|
|
341
|
-
historyEntriesNameMatcher.test(entry.name)
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
traceError(error) {
|
|
345
|
-
this.logService.trace('[Working Copy History Service]', error);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
let WorkingCopyHistoryService = class WorkingCopyHistoryService extends Disposable {
|
|
349
|
-
static { WorkingCopyHistoryService_1 = this; }
|
|
350
|
-
static { this.FILE_MOVED_SOURCE = SaveSourceRegistry.registerSource('moved.source', ( localizeWithPath(
|
|
351
|
-
'vs/workbench/services/workingCopy/common/workingCopyHistoryService',
|
|
352
|
-
'moved.source',
|
|
353
|
-
"File Moved"
|
|
354
|
-
))); }
|
|
355
|
-
static { this.FILE_RENAMED_SOURCE = SaveSourceRegistry.registerSource('renamed.source', ( localizeWithPath(
|
|
356
|
-
'vs/workbench/services/workingCopy/common/workingCopyHistoryService',
|
|
357
|
-
'renamed.source',
|
|
358
|
-
"File Renamed"
|
|
359
|
-
))); }
|
|
360
|
-
constructor(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, logService, configurationService) {
|
|
361
|
-
super();
|
|
362
|
-
this.fileService = fileService;
|
|
363
|
-
this.remoteAgentService = remoteAgentService;
|
|
364
|
-
this.environmentService = environmentService;
|
|
365
|
-
this.uriIdentityService = uriIdentityService;
|
|
366
|
-
this.labelService = labelService;
|
|
367
|
-
this.logService = logService;
|
|
368
|
-
this.configurationService = configurationService;
|
|
369
|
-
this._onDidAddEntry = this._register(( new Emitter()));
|
|
370
|
-
this.onDidAddEntry = this._onDidAddEntry.event;
|
|
371
|
-
this._onDidChangeEntry = this._register(( new Emitter()));
|
|
372
|
-
this.onDidChangeEntry = this._onDidChangeEntry.event;
|
|
373
|
-
this._onDidReplaceEntry = this._register(( new Emitter()));
|
|
374
|
-
this.onDidReplaceEntry = this._onDidReplaceEntry.event;
|
|
375
|
-
this._onDidMoveEntries = this._register(( new Emitter()));
|
|
376
|
-
this.onDidMoveEntries = this._onDidMoveEntries.event;
|
|
377
|
-
this._onDidRemoveEntry = this._register(( new Emitter()));
|
|
378
|
-
this.onDidRemoveEntry = this._onDidRemoveEntry.event;
|
|
379
|
-
this._onDidRemoveEntries = this._register(( new Emitter()));
|
|
380
|
-
this.onDidRemoveEntries = this._onDidRemoveEntries.event;
|
|
381
|
-
this.localHistoryHome = ( new DeferredPromise());
|
|
382
|
-
this.models = ( new ResourceMap(resource => this.uriIdentityService.extUri.getComparisonKey(resource)));
|
|
383
|
-
this.resolveLocalHistoryHome();
|
|
384
|
-
}
|
|
385
|
-
async resolveLocalHistoryHome() {
|
|
386
|
-
let historyHome = undefined;
|
|
387
|
-
try {
|
|
388
|
-
const remoteEnv = await this.remoteAgentService.getEnvironment();
|
|
389
|
-
if (remoteEnv) {
|
|
390
|
-
historyHome = remoteEnv.localHistoryHome;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
catch (error) {
|
|
394
|
-
this.logService.trace(error);
|
|
395
|
-
}
|
|
396
|
-
if (!historyHome) {
|
|
397
|
-
historyHome = this.environmentService.localHistoryHome;
|
|
398
|
-
}
|
|
399
|
-
this.localHistoryHome.complete(historyHome);
|
|
400
|
-
}
|
|
401
|
-
async moveEntries(source, target) {
|
|
402
|
-
const limiter = ( new Limiter(MAX_PARALLEL_HISTORY_IO_OPS));
|
|
403
|
-
const promises = [];
|
|
404
|
-
for (const [resource, model] of this.models) {
|
|
405
|
-
if (!this.uriIdentityService.extUri.isEqualOrParent(resource, source)) {
|
|
406
|
-
continue;
|
|
407
|
-
}
|
|
408
|
-
let targetResource;
|
|
409
|
-
if (this.uriIdentityService.extUri.isEqual(source, resource)) {
|
|
410
|
-
targetResource = target;
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
const index = indexOfPath(resource.path, source.path);
|
|
414
|
-
targetResource = joinPath(target, resource.path.substr(index + source.path.length + 1));
|
|
415
|
-
}
|
|
416
|
-
let saveSource;
|
|
417
|
-
if (this.uriIdentityService.extUri.isEqual(dirname(resource), dirname(targetResource))) {
|
|
418
|
-
saveSource = WorkingCopyHistoryService_1.FILE_RENAMED_SOURCE;
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
saveSource = WorkingCopyHistoryService_1.FILE_MOVED_SOURCE;
|
|
422
|
-
}
|
|
423
|
-
promises.push(limiter.queue(() => this.doMoveEntries(model, saveSource, resource, targetResource)));
|
|
424
|
-
}
|
|
425
|
-
if (!promises.length) {
|
|
426
|
-
return [];
|
|
427
|
-
}
|
|
428
|
-
const resources = await Promise.all(promises);
|
|
429
|
-
this._onDidMoveEntries.fire();
|
|
430
|
-
return resources;
|
|
431
|
-
}
|
|
432
|
-
async doMoveEntries(model, source, sourceWorkingCopyResource, targetWorkingCopyResource) {
|
|
433
|
-
await model.moveEntries(targetWorkingCopyResource, source, CancellationToken.None);
|
|
434
|
-
this.models.delete(sourceWorkingCopyResource);
|
|
435
|
-
this.models.set(targetWorkingCopyResource, model);
|
|
436
|
-
return targetWorkingCopyResource;
|
|
437
|
-
}
|
|
438
|
-
async addEntry({ resource, source, timestamp }, token) {
|
|
439
|
-
if (!this.fileService.hasProvider(resource)) {
|
|
440
|
-
return undefined;
|
|
441
|
-
}
|
|
442
|
-
const model = await this.getModel(resource);
|
|
443
|
-
if (token.isCancellationRequested) {
|
|
444
|
-
return undefined;
|
|
445
|
-
}
|
|
446
|
-
return model.addEntry(source, timestamp, token);
|
|
447
|
-
}
|
|
448
|
-
async updateEntry(entry, properties, token) {
|
|
449
|
-
const model = await this.getModel(entry.workingCopy.resource);
|
|
450
|
-
if (token.isCancellationRequested) {
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
return model.updateEntry(entry, properties, token);
|
|
454
|
-
}
|
|
455
|
-
async removeEntry(entry, token) {
|
|
456
|
-
const model = await this.getModel(entry.workingCopy.resource);
|
|
457
|
-
if (token.isCancellationRequested) {
|
|
458
|
-
return false;
|
|
459
|
-
}
|
|
460
|
-
return model.removeEntry(entry, token);
|
|
461
|
-
}
|
|
462
|
-
async removeAll(token) {
|
|
463
|
-
const historyHome = await this.localHistoryHome.p;
|
|
464
|
-
if (token.isCancellationRequested) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
this.models.clear();
|
|
468
|
-
await this.fileService.del(historyHome, { recursive: true });
|
|
469
|
-
this._onDidRemoveEntries.fire();
|
|
470
|
-
}
|
|
471
|
-
async getEntries(resource, token) {
|
|
472
|
-
const model = await this.getModel(resource);
|
|
473
|
-
if (token.isCancellationRequested) {
|
|
474
|
-
return [];
|
|
475
|
-
}
|
|
476
|
-
const entries = await model.getEntries();
|
|
477
|
-
return entries ?? [];
|
|
478
|
-
}
|
|
479
|
-
async getAll(token) {
|
|
480
|
-
const historyHome = await this.localHistoryHome.p;
|
|
481
|
-
if (token.isCancellationRequested) {
|
|
482
|
-
return [];
|
|
483
|
-
}
|
|
484
|
-
const all = ( new ResourceMap());
|
|
485
|
-
for (const [resource, model] of this.models) {
|
|
486
|
-
const hasInMemoryEntries = await model.hasEntries(true );
|
|
487
|
-
if (hasInMemoryEntries) {
|
|
488
|
-
all.set(resource, true);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
try {
|
|
492
|
-
const resolvedHistoryHome = await this.fileService.resolve(historyHome);
|
|
493
|
-
if (resolvedHistoryHome.children) {
|
|
494
|
-
const limiter = ( new Limiter(MAX_PARALLEL_HISTORY_IO_OPS));
|
|
495
|
-
const promises = [];
|
|
496
|
-
for (const child of resolvedHistoryHome.children) {
|
|
497
|
-
promises.push(limiter.queue(async () => {
|
|
498
|
-
if (token.isCancellationRequested) {
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
try {
|
|
502
|
-
const serializedModel = JSON.parse(( (await this.fileService.readFile(joinPath(child.resource, WorkingCopyHistoryModel.ENTRIES_FILE))).value.toString()));
|
|
503
|
-
if (serializedModel.entries.length > 0) {
|
|
504
|
-
all.set(( URI.parse(serializedModel.resource)), true);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
catch (error) {
|
|
508
|
-
}
|
|
509
|
-
}));
|
|
510
|
-
}
|
|
511
|
-
await Promise.all(promises);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
catch (error) {
|
|
515
|
-
}
|
|
516
|
-
return Array.from(( all.keys()));
|
|
517
|
-
}
|
|
518
|
-
async getModel(resource) {
|
|
519
|
-
const historyHome = await this.localHistoryHome.p;
|
|
520
|
-
let model = this.models.get(resource);
|
|
521
|
-
if (!model) {
|
|
522
|
-
model = ( new WorkingCopyHistoryModel(
|
|
523
|
-
resource,
|
|
524
|
-
historyHome,
|
|
525
|
-
this._onDidAddEntry,
|
|
526
|
-
this._onDidChangeEntry,
|
|
527
|
-
this._onDidReplaceEntry,
|
|
528
|
-
this._onDidRemoveEntry,
|
|
529
|
-
this.getModelOptions(),
|
|
530
|
-
this.fileService,
|
|
531
|
-
this.labelService,
|
|
532
|
-
this.logService,
|
|
533
|
-
this.configurationService
|
|
534
|
-
));
|
|
535
|
-
this.models.set(resource, model);
|
|
536
|
-
}
|
|
537
|
-
return model;
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
WorkingCopyHistoryService = WorkingCopyHistoryService_1 = ( __decorate([
|
|
541
|
-
( __param(0, IFileService)),
|
|
542
|
-
( __param(1, IRemoteAgentService)),
|
|
543
|
-
( __param(2, IWorkbenchEnvironmentService)),
|
|
544
|
-
( __param(3, IUriIdentityService)),
|
|
545
|
-
( __param(4, ILabelService)),
|
|
546
|
-
( __param(5, ILogService)),
|
|
547
|
-
( __param(6, IConfigurationService))
|
|
548
|
-
], WorkingCopyHistoryService));
|
|
549
|
-
let NativeWorkingCopyHistoryService = class NativeWorkingCopyHistoryService extends WorkingCopyHistoryService {
|
|
550
|
-
static { NativeWorkingCopyHistoryService_1 = this; }
|
|
551
|
-
static { this.STORE_ALL_INTERVAL = 5 * 60 * 1000; }
|
|
552
|
-
constructor(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, lifecycleService, logService, configurationService) {
|
|
553
|
-
super(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, logService, configurationService);
|
|
554
|
-
this.lifecycleService = lifecycleService;
|
|
555
|
-
this.isRemotelyStored = typeof this.environmentService.remoteAuthority === 'string';
|
|
556
|
-
this.storeAllCts = this._register(( new CancellationTokenSource()));
|
|
557
|
-
this.storeAllScheduler = this._register(( new RunOnceScheduler(
|
|
558
|
-
() => this.storeAll(this.storeAllCts.token),
|
|
559
|
-
NativeWorkingCopyHistoryService_1.STORE_ALL_INTERVAL
|
|
560
|
-
)));
|
|
561
|
-
this.registerListeners();
|
|
562
|
-
}
|
|
563
|
-
registerListeners() {
|
|
564
|
-
if (!this.isRemotelyStored) {
|
|
565
|
-
this._register(this.lifecycleService.onWillShutdown(e => this.onWillShutdown(e)));
|
|
566
|
-
this._register(Event.any(this.onDidAddEntry, this.onDidChangeEntry, this.onDidReplaceEntry, this.onDidRemoveEntry)(() => this.onDidChangeModels()));
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
getModelOptions() {
|
|
570
|
-
return { flushOnChange: this.isRemotelyStored };
|
|
571
|
-
}
|
|
572
|
-
onWillShutdown(e) {
|
|
573
|
-
this.storeAllScheduler.dispose();
|
|
574
|
-
this.storeAllCts.dispose(true);
|
|
575
|
-
e.join(this.storeAll(e.token), { id: 'join.workingCopyHistory', label: ( localizeWithPath(
|
|
576
|
-
'vs/workbench/services/workingCopy/common/workingCopyHistoryService',
|
|
577
|
-
'join.workingCopyHistory',
|
|
578
|
-
"Saving local history"
|
|
579
|
-
)) });
|
|
580
|
-
}
|
|
581
|
-
onDidChangeModels() {
|
|
582
|
-
if (!this.storeAllScheduler.isScheduled()) {
|
|
583
|
-
this.storeAllScheduler.schedule();
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
async storeAll(token) {
|
|
587
|
-
const limiter = ( new Limiter(MAX_PARALLEL_HISTORY_IO_OPS));
|
|
588
|
-
const promises = [];
|
|
589
|
-
const models = Array.from(( this.models.values()));
|
|
590
|
-
for (const model of models) {
|
|
591
|
-
promises.push(limiter.queue(async () => {
|
|
592
|
-
if (token.isCancellationRequested) {
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
try {
|
|
596
|
-
await model.store(token);
|
|
597
|
-
}
|
|
598
|
-
catch (error) {
|
|
599
|
-
this.logService.trace(error);
|
|
600
|
-
}
|
|
601
|
-
}));
|
|
602
|
-
}
|
|
603
|
-
await Promise.all(promises);
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
NativeWorkingCopyHistoryService = NativeWorkingCopyHistoryService_1 = ( __decorate([
|
|
607
|
-
( __param(0, IFileService)),
|
|
608
|
-
( __param(1, IRemoteAgentService)),
|
|
609
|
-
( __param(2, IWorkbenchEnvironmentService)),
|
|
610
|
-
( __param(3, IUriIdentityService)),
|
|
611
|
-
( __param(4, ILabelService)),
|
|
612
|
-
( __param(5, ILifecycleService)),
|
|
613
|
-
( __param(6, ILogService)),
|
|
614
|
-
( __param(7, IConfigurationService))
|
|
615
|
-
], NativeWorkingCopyHistoryService));
|
|
616
|
-
( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(WorkingCopyHistoryTracker, 3 );
|
|
617
|
-
|
|
618
|
-
export { NativeWorkingCopyHistoryService, WorkingCopyHistoryModel, WorkingCopyHistoryService };
|