@codingame/monaco-vscode-timeline-service-override 4.1.0 → 4.1.2
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/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
- package/external/tslib/tslib.es6.js +11 -0
- package/override/vs/platform/dialogs/common/dialogs.js +10 -0
- package/package.json +2 -2
- package/timeline.js +3 -3
- package/vscode/src/vs/workbench/contrib/localHistory/browser/localHistory.contribution.js +5 -0
- package/vscode/src/vs/workbench/contrib/localHistory/browser/localHistory.js +37 -0
- package/vscode/src/vs/workbench/contrib/localHistory/browser/localHistoryCommands.js +637 -0
- package/vscode/src/vs/workbench/contrib/localHistory/browser/localHistoryFileSystemProvider.js +89 -0
- package/vscode/src/vs/workbench/contrib/localHistory/browser/localHistoryTimeline.js +138 -0
- package/vscode/src/vs/workbench/contrib/timeline/browser/media/timelinePane.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/timeline/browser/timeline.contribution.js +120 -0
- package/vscode/src/vs/workbench/contrib/timeline/browser/timelinePane.js +1163 -0
- package/vscode/src/vs/workbench/contrib/timeline/common/timelineService.js +108 -0
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import { localize2WithPath, localizeWithPath } from 'vscode/vscode/vs/nls';
|
|
2
|
+
import { URI } from 'vscode/vscode/vs/base/common/uri';
|
|
3
|
+
import { Event } from 'vscode/vscode/vs/base/common/event';
|
|
4
|
+
import { Schemas } from 'vscode/vscode/vs/base/common/network';
|
|
5
|
+
import { toErrorMessage } from 'vscode/vscode/vs/base/common/errorMessage';
|
|
6
|
+
import { CancellationToken, CancellationTokenSource } from 'vscode/vscode/vs/base/common/cancellation';
|
|
7
|
+
import { IWorkingCopyHistoryService } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyHistory';
|
|
8
|
+
import { API_OPEN_DIFF_EDITOR_COMMAND_ID } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorCommands';
|
|
9
|
+
import { LocalHistoryFileSystemProvider } from './localHistoryFileSystemProvider.js';
|
|
10
|
+
import { RawContextKey, IContextKeyService, ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
|
|
11
|
+
import { registerAction2, Action2, MenuId, MenuRegistry } from 'vscode/vscode/vs/platform/actions/common/actions';
|
|
12
|
+
import { basenameOrAuthority, basename, dirname } from 'vscode/vscode/vs/base/common/resources';
|
|
13
|
+
import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands';
|
|
14
|
+
import { SaveSourceRegistry, EditorResourceAccessor, SideBySideEditor } from 'vscode/vscode/vs/workbench/common/editor';
|
|
15
|
+
import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
|
|
16
|
+
import { IWorkingCopyService } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyService';
|
|
17
|
+
import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
|
|
18
|
+
import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
|
|
19
|
+
import { ResourceContextKey, ActiveEditorContext } from 'vscode/vscode/vs/workbench/common/contextkeys';
|
|
20
|
+
import { IQuickInputService } from 'vscode/vscode/vs/platform/quickinput/common/quickInput';
|
|
21
|
+
import { getIconClasses } from 'vscode/vscode/vs/editor/common/services/getIconClasses';
|
|
22
|
+
import { IModelService } from 'vscode/vscode/vs/editor/common/services/model';
|
|
23
|
+
import { ILanguageService } from 'vscode/vscode/vs/editor/common/languages/language';
|
|
24
|
+
import { ILabelService } from 'vscode/vscode/vs/platform/label/common/label';
|
|
25
|
+
import { firstOrDefault } from 'vscode/vscode/vs/base/common/arrays';
|
|
26
|
+
import { LOCAL_HISTORY_MENU_CONTEXT_KEY, LOCAL_HISTORY_ICON_RESTORE, getLocalHistoryDateFormatter } from './localHistory.js';
|
|
27
|
+
import { IPathService } from 'vscode/vscode/vs/workbench/services/path/common/pathService';
|
|
28
|
+
import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
|
|
29
|
+
|
|
30
|
+
const LOCAL_HISTORY_CATEGORY = ( localize2WithPath(
|
|
31
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
32
|
+
'localHistory.category',
|
|
33
|
+
'Local History'
|
|
34
|
+
));
|
|
35
|
+
const COMPARE_WITH_FILE_LABEL = ( localize2WithPath(
|
|
36
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
37
|
+
'localHistory.compareWithFile',
|
|
38
|
+
'Compare with File'
|
|
39
|
+
));
|
|
40
|
+
registerAction2(class extends Action2 {
|
|
41
|
+
constructor() {
|
|
42
|
+
super({
|
|
43
|
+
id: 'workbench.action.localHistory.compareWithFile',
|
|
44
|
+
title: COMPARE_WITH_FILE_LABEL,
|
|
45
|
+
menu: {
|
|
46
|
+
id: MenuId.TimelineItemContext,
|
|
47
|
+
group: '1_compare',
|
|
48
|
+
order: 1,
|
|
49
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async run(accessor, item) {
|
|
54
|
+
const commandService = accessor.get(ICommandService);
|
|
55
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
56
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
57
|
+
if (entry) {
|
|
58
|
+
return commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, ...toDiffEditorArguments(entry, entry.workingCopy.resource));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
registerAction2(class extends Action2 {
|
|
63
|
+
constructor() {
|
|
64
|
+
super({
|
|
65
|
+
id: 'workbench.action.localHistory.compareWithPrevious',
|
|
66
|
+
title: ( localize2WithPath(
|
|
67
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
68
|
+
'localHistory.compareWithPrevious',
|
|
69
|
+
'Compare with Previous'
|
|
70
|
+
)),
|
|
71
|
+
menu: {
|
|
72
|
+
id: MenuId.TimelineItemContext,
|
|
73
|
+
group: '1_compare',
|
|
74
|
+
order: 2,
|
|
75
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async run(accessor, item) {
|
|
80
|
+
const commandService = accessor.get(ICommandService);
|
|
81
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
82
|
+
const editorService = accessor.get(IEditorService);
|
|
83
|
+
const { entry, previous } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
84
|
+
if (entry) {
|
|
85
|
+
if (!previous) {
|
|
86
|
+
return openEntry(entry, editorService);
|
|
87
|
+
}
|
|
88
|
+
return commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, ...toDiffEditorArguments(previous, entry));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
let itemSelectedForCompare = undefined;
|
|
93
|
+
const LocalHistoryItemSelectedForCompare = ( new RawContextKey('localHistoryItemSelectedForCompare', false, true));
|
|
94
|
+
registerAction2(class extends Action2 {
|
|
95
|
+
constructor() {
|
|
96
|
+
super({
|
|
97
|
+
id: 'workbench.action.localHistory.selectForCompare',
|
|
98
|
+
title: ( localize2WithPath(
|
|
99
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
100
|
+
'localHistory.selectForCompare',
|
|
101
|
+
'Select for Compare'
|
|
102
|
+
)),
|
|
103
|
+
menu: {
|
|
104
|
+
id: MenuId.TimelineItemContext,
|
|
105
|
+
group: '2_compare_with',
|
|
106
|
+
order: 2,
|
|
107
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async run(accessor, item) {
|
|
112
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
113
|
+
const contextKeyService = accessor.get(IContextKeyService);
|
|
114
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
115
|
+
if (entry) {
|
|
116
|
+
itemSelectedForCompare = item;
|
|
117
|
+
LocalHistoryItemSelectedForCompare.bindTo(contextKeyService).set(true);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
registerAction2(class extends Action2 {
|
|
122
|
+
constructor() {
|
|
123
|
+
super({
|
|
124
|
+
id: 'workbench.action.localHistory.compareWithSelected',
|
|
125
|
+
title: ( localize2WithPath(
|
|
126
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
127
|
+
'localHistory.compareWithSelected',
|
|
128
|
+
'Compare with Selected'
|
|
129
|
+
)),
|
|
130
|
+
menu: {
|
|
131
|
+
id: MenuId.TimelineItemContext,
|
|
132
|
+
group: '2_compare_with',
|
|
133
|
+
order: 1,
|
|
134
|
+
when: ( ContextKeyExpr.and(LOCAL_HISTORY_MENU_CONTEXT_KEY, LocalHistoryItemSelectedForCompare))
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
async run(accessor, item) {
|
|
139
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
140
|
+
const commandService = accessor.get(ICommandService);
|
|
141
|
+
if (!itemSelectedForCompare) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const selectedEntry = (await findLocalHistoryEntry(workingCopyHistoryService, itemSelectedForCompare)).entry;
|
|
145
|
+
if (!selectedEntry) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
149
|
+
if (entry) {
|
|
150
|
+
return commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, ...toDiffEditorArguments(selectedEntry, entry));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
registerAction2(class extends Action2 {
|
|
155
|
+
constructor() {
|
|
156
|
+
super({
|
|
157
|
+
id: 'workbench.action.localHistory.open',
|
|
158
|
+
title: ( localize2WithPath(
|
|
159
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
160
|
+
'localHistory.open',
|
|
161
|
+
'Show Contents'
|
|
162
|
+
)),
|
|
163
|
+
menu: {
|
|
164
|
+
id: MenuId.TimelineItemContext,
|
|
165
|
+
group: '3_contents',
|
|
166
|
+
order: 1,
|
|
167
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async run(accessor, item) {
|
|
172
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
173
|
+
const editorService = accessor.get(IEditorService);
|
|
174
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
175
|
+
if (entry) {
|
|
176
|
+
return openEntry(entry, editorService);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
const RESTORE_CONTENTS_LABEL = ( localize2WithPath(
|
|
181
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
182
|
+
'localHistory.restore',
|
|
183
|
+
'Restore Contents'
|
|
184
|
+
));
|
|
185
|
+
registerAction2(class extends Action2 {
|
|
186
|
+
constructor() {
|
|
187
|
+
super({
|
|
188
|
+
id: 'workbench.action.localHistory.restoreViaEditor',
|
|
189
|
+
title: RESTORE_CONTENTS_LABEL,
|
|
190
|
+
menu: {
|
|
191
|
+
id: MenuId.EditorTitle,
|
|
192
|
+
group: 'navigation',
|
|
193
|
+
order: -10,
|
|
194
|
+
when: ( ResourceContextKey.Scheme.isEqualTo(LocalHistoryFileSystemProvider.SCHEMA))
|
|
195
|
+
},
|
|
196
|
+
icon: LOCAL_HISTORY_ICON_RESTORE
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async run(accessor, uri) {
|
|
200
|
+
const { associatedResource, location } = LocalHistoryFileSystemProvider.fromLocalHistoryFileSystem(uri);
|
|
201
|
+
return restore(accessor, { uri: associatedResource, handle: basenameOrAuthority(location) });
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
registerAction2(class extends Action2 {
|
|
205
|
+
constructor() {
|
|
206
|
+
super({
|
|
207
|
+
id: 'workbench.action.localHistory.restore',
|
|
208
|
+
title: RESTORE_CONTENTS_LABEL,
|
|
209
|
+
menu: {
|
|
210
|
+
id: MenuId.TimelineItemContext,
|
|
211
|
+
group: '3_contents',
|
|
212
|
+
order: 2,
|
|
213
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async run(accessor, item) {
|
|
218
|
+
return restore(accessor, item);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const restoreSaveSource = SaveSourceRegistry.registerSource('localHistoryRestore.source', ( localizeWithPath(
|
|
222
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
223
|
+
'localHistoryRestore.source',
|
|
224
|
+
"File Restored"
|
|
225
|
+
)));
|
|
226
|
+
async function restore(accessor, item) {
|
|
227
|
+
const fileService = accessor.get(IFileService);
|
|
228
|
+
const dialogService = accessor.get(IDialogService);
|
|
229
|
+
const workingCopyService = accessor.get(IWorkingCopyService);
|
|
230
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
231
|
+
const editorService = accessor.get(IEditorService);
|
|
232
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
233
|
+
if (entry) {
|
|
234
|
+
const { confirmed } = await dialogService.confirm({
|
|
235
|
+
type: 'warning',
|
|
236
|
+
message: ( localizeWithPath(
|
|
237
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
238
|
+
'confirmRestoreMessage',
|
|
239
|
+
"Do you want to restore the contents of '{0}'?",
|
|
240
|
+
basename(entry.workingCopy.resource)
|
|
241
|
+
)),
|
|
242
|
+
detail: ( localizeWithPath(
|
|
243
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
244
|
+
'confirmRestoreDetail',
|
|
245
|
+
"Restoring will discard any unsaved changes."
|
|
246
|
+
)),
|
|
247
|
+
primaryButton: ( localizeWithPath(
|
|
248
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
249
|
+
{ key: 'restoreButtonLabel', comment: ['&& denotes a mnemonic'] },
|
|
250
|
+
"&&Restore"
|
|
251
|
+
))
|
|
252
|
+
});
|
|
253
|
+
if (!confirmed) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const workingCopies = workingCopyService.getAll(entry.workingCopy.resource);
|
|
257
|
+
if (workingCopies) {
|
|
258
|
+
for (const workingCopy of workingCopies) {
|
|
259
|
+
if (workingCopy.isDirty()) {
|
|
260
|
+
await workingCopy.revert({ soft: true });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
await fileService.cloneFile(entry.location, entry.workingCopy.resource);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
await dialogService.error(( localizeWithPath(
|
|
269
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
270
|
+
'unableToRestore',
|
|
271
|
+
"Unable to restore '{0}'.",
|
|
272
|
+
basename(entry.workingCopy.resource)
|
|
273
|
+
)), toErrorMessage(error));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (workingCopies) {
|
|
277
|
+
for (const workingCopy of workingCopies) {
|
|
278
|
+
await workingCopy.revert({ force: true });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
await editorService.openEditor({ resource: entry.workingCopy.resource });
|
|
282
|
+
await workingCopyHistoryService.addEntry({
|
|
283
|
+
resource: entry.workingCopy.resource,
|
|
284
|
+
source: restoreSaveSource
|
|
285
|
+
}, CancellationToken.None);
|
|
286
|
+
await closeEntry(entry, editorService);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
registerAction2(class extends Action2 {
|
|
290
|
+
constructor() {
|
|
291
|
+
super({
|
|
292
|
+
id: 'workbench.action.localHistory.restoreViaPicker',
|
|
293
|
+
title: ( localize2WithPath(
|
|
294
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
295
|
+
'localHistory.restoreViaPicker',
|
|
296
|
+
'Find Entry to Restore'
|
|
297
|
+
)),
|
|
298
|
+
f1: true,
|
|
299
|
+
category: LOCAL_HISTORY_CATEGORY
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async run(accessor) {
|
|
303
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
304
|
+
const quickInputService = accessor.get(IQuickInputService);
|
|
305
|
+
const modelService = accessor.get(IModelService);
|
|
306
|
+
const languageService = accessor.get(ILanguageService);
|
|
307
|
+
const labelService = accessor.get(ILabelService);
|
|
308
|
+
const editorService = accessor.get(IEditorService);
|
|
309
|
+
const fileService = accessor.get(IFileService);
|
|
310
|
+
const commandService = accessor.get(ICommandService);
|
|
311
|
+
const resourcePicker = quickInputService.createQuickPick();
|
|
312
|
+
let cts = ( new CancellationTokenSource());
|
|
313
|
+
resourcePicker.onDidHide(() => cts.dispose(true));
|
|
314
|
+
resourcePicker.busy = true;
|
|
315
|
+
resourcePicker.show();
|
|
316
|
+
const resources = await workingCopyHistoryService.getAll(cts.token);
|
|
317
|
+
resourcePicker.busy = false;
|
|
318
|
+
resourcePicker.placeholder = ( localizeWithPath(
|
|
319
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
320
|
+
'restoreViaPicker.filePlaceholder',
|
|
321
|
+
"Select the file to show local history for"
|
|
322
|
+
));
|
|
323
|
+
resourcePicker.matchOnLabel = true;
|
|
324
|
+
resourcePicker.matchOnDescription = true;
|
|
325
|
+
resourcePicker.items = ( resources.map(resource => ({
|
|
326
|
+
resource,
|
|
327
|
+
label: basenameOrAuthority(resource),
|
|
328
|
+
description: labelService.getUriLabel(dirname(resource), { relative: true }),
|
|
329
|
+
iconClasses: getIconClasses(modelService, languageService, resource)
|
|
330
|
+
}))).sort((r1, r2) => r1.resource.fsPath < r2.resource.fsPath ? -1 : 1);
|
|
331
|
+
await Event.toPromise(resourcePicker.onDidAccept);
|
|
332
|
+
resourcePicker.dispose();
|
|
333
|
+
const resource = firstOrDefault(resourcePicker.selectedItems)?.resource;
|
|
334
|
+
if (!resource) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const entryPicker = quickInputService.createQuickPick();
|
|
338
|
+
cts = ( new CancellationTokenSource());
|
|
339
|
+
entryPicker.onDidHide(() => cts.dispose(true));
|
|
340
|
+
entryPicker.busy = true;
|
|
341
|
+
entryPicker.show();
|
|
342
|
+
const entries = await workingCopyHistoryService.getEntries(resource, cts.token);
|
|
343
|
+
entryPicker.busy = false;
|
|
344
|
+
entryPicker.placeholder = ( localizeWithPath(
|
|
345
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
346
|
+
'restoreViaPicker.entryPlaceholder',
|
|
347
|
+
"Select the local history entry to open"
|
|
348
|
+
));
|
|
349
|
+
entryPicker.matchOnLabel = true;
|
|
350
|
+
entryPicker.matchOnDescription = true;
|
|
351
|
+
entryPicker.items = ( Array.from(entries).reverse().map(entry => ({
|
|
352
|
+
entry,
|
|
353
|
+
label: `$(circle-outline) ${SaveSourceRegistry.getSourceLabel(entry.source)}`,
|
|
354
|
+
description: toLocalHistoryEntryDateLabel(entry.timestamp)
|
|
355
|
+
})));
|
|
356
|
+
await Event.toPromise(entryPicker.onDidAccept);
|
|
357
|
+
entryPicker.dispose();
|
|
358
|
+
const selectedItem = firstOrDefault(entryPicker.selectedItems);
|
|
359
|
+
if (!selectedItem) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const resourceExists = await fileService.exists(selectedItem.entry.workingCopy.resource);
|
|
363
|
+
if (resourceExists) {
|
|
364
|
+
return commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, ...toDiffEditorArguments(selectedItem.entry, selectedItem.entry.workingCopy.resource));
|
|
365
|
+
}
|
|
366
|
+
return openEntry(selectedItem.entry, editorService);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
MenuRegistry.appendMenuItem(MenuId.TimelineTitle, { command: { id: 'workbench.action.localHistory.restoreViaPicker', title: ( localize2WithPath(
|
|
370
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
371
|
+
'localHistory.restoreViaPickerMenu',
|
|
372
|
+
'Local History: Find Entry to Restore...'
|
|
373
|
+
)) }, group: 'submenu', order: 1 });
|
|
374
|
+
registerAction2(class extends Action2 {
|
|
375
|
+
constructor() {
|
|
376
|
+
super({
|
|
377
|
+
id: 'workbench.action.localHistory.rename',
|
|
378
|
+
title: ( localize2WithPath(
|
|
379
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
380
|
+
'localHistory.rename',
|
|
381
|
+
'Rename'
|
|
382
|
+
)),
|
|
383
|
+
menu: {
|
|
384
|
+
id: MenuId.TimelineItemContext,
|
|
385
|
+
group: '5_edit',
|
|
386
|
+
order: 1,
|
|
387
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
async run(accessor, item) {
|
|
392
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
393
|
+
const quickInputService = accessor.get(IQuickInputService);
|
|
394
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
395
|
+
if (entry) {
|
|
396
|
+
const inputBox = quickInputService.createInputBox();
|
|
397
|
+
inputBox.title = ( localizeWithPath(
|
|
398
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
399
|
+
'renameLocalHistoryEntryTitle',
|
|
400
|
+
"Rename Local History Entry"
|
|
401
|
+
));
|
|
402
|
+
inputBox.ignoreFocusOut = true;
|
|
403
|
+
inputBox.placeholder = ( localizeWithPath(
|
|
404
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
405
|
+
'renameLocalHistoryPlaceholder',
|
|
406
|
+
"Enter the new name of the local history entry"
|
|
407
|
+
));
|
|
408
|
+
inputBox.value = SaveSourceRegistry.getSourceLabel(entry.source);
|
|
409
|
+
inputBox.show();
|
|
410
|
+
inputBox.onDidAccept(() => {
|
|
411
|
+
if (inputBox.value) {
|
|
412
|
+
workingCopyHistoryService.updateEntry(entry, { source: inputBox.value }, CancellationToken.None);
|
|
413
|
+
}
|
|
414
|
+
inputBox.dispose();
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
registerAction2(class extends Action2 {
|
|
420
|
+
constructor() {
|
|
421
|
+
super({
|
|
422
|
+
id: 'workbench.action.localHistory.delete',
|
|
423
|
+
title: ( localize2WithPath(
|
|
424
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
425
|
+
'localHistory.delete',
|
|
426
|
+
'Delete'
|
|
427
|
+
)),
|
|
428
|
+
menu: {
|
|
429
|
+
id: MenuId.TimelineItemContext,
|
|
430
|
+
group: '5_edit',
|
|
431
|
+
order: 2,
|
|
432
|
+
when: LOCAL_HISTORY_MENU_CONTEXT_KEY
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
async run(accessor, item) {
|
|
437
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
438
|
+
const editorService = accessor.get(IEditorService);
|
|
439
|
+
const dialogService = accessor.get(IDialogService);
|
|
440
|
+
const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item);
|
|
441
|
+
if (entry) {
|
|
442
|
+
const { confirmed } = await dialogService.confirm({
|
|
443
|
+
type: 'warning',
|
|
444
|
+
message: ( localizeWithPath(
|
|
445
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
446
|
+
'confirmDeleteMessage',
|
|
447
|
+
"Do you want to delete the local history entry of '{0}' from {1}?",
|
|
448
|
+
entry.workingCopy.name,
|
|
449
|
+
toLocalHistoryEntryDateLabel(entry.timestamp)
|
|
450
|
+
)),
|
|
451
|
+
detail: ( localizeWithPath(
|
|
452
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
453
|
+
'confirmDeleteDetail',
|
|
454
|
+
"This action is irreversible!"
|
|
455
|
+
)),
|
|
456
|
+
primaryButton: ( localizeWithPath(
|
|
457
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
458
|
+
{ key: 'deleteButtonLabel', comment: ['&& denotes a mnemonic'] },
|
|
459
|
+
"&&Delete"
|
|
460
|
+
)),
|
|
461
|
+
});
|
|
462
|
+
if (!confirmed) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
await workingCopyHistoryService.removeEntry(entry, CancellationToken.None);
|
|
466
|
+
await closeEntry(entry, editorService);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
registerAction2(class extends Action2 {
|
|
471
|
+
constructor() {
|
|
472
|
+
super({
|
|
473
|
+
id: 'workbench.action.localHistory.deleteAll',
|
|
474
|
+
title: ( localize2WithPath(
|
|
475
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
476
|
+
'localHistory.deleteAll',
|
|
477
|
+
'Delete All'
|
|
478
|
+
)),
|
|
479
|
+
f1: true,
|
|
480
|
+
category: LOCAL_HISTORY_CATEGORY
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
async run(accessor) {
|
|
484
|
+
const dialogService = accessor.get(IDialogService);
|
|
485
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
486
|
+
const { confirmed } = await dialogService.confirm({
|
|
487
|
+
type: 'warning',
|
|
488
|
+
message: ( localizeWithPath(
|
|
489
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
490
|
+
'confirmDeleteAllMessage',
|
|
491
|
+
"Do you want to delete all entries of all files in local history?"
|
|
492
|
+
)),
|
|
493
|
+
detail: ( localizeWithPath(
|
|
494
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
495
|
+
'confirmDeleteAllDetail',
|
|
496
|
+
"This action is irreversible!"
|
|
497
|
+
)),
|
|
498
|
+
primaryButton: ( localizeWithPath(
|
|
499
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
500
|
+
{ key: 'deleteAllButtonLabel', comment: ['&& denotes a mnemonic'] },
|
|
501
|
+
"&&Delete All"
|
|
502
|
+
)),
|
|
503
|
+
});
|
|
504
|
+
if (!confirmed) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
await workingCopyHistoryService.removeAll(CancellationToken.None);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
registerAction2(class extends Action2 {
|
|
511
|
+
constructor() {
|
|
512
|
+
super({
|
|
513
|
+
id: 'workbench.action.localHistory.create',
|
|
514
|
+
title: ( localize2WithPath(
|
|
515
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
516
|
+
'localHistory.create',
|
|
517
|
+
'Create Entry'
|
|
518
|
+
)),
|
|
519
|
+
f1: true,
|
|
520
|
+
category: LOCAL_HISTORY_CATEGORY,
|
|
521
|
+
precondition: ActiveEditorContext
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
async run(accessor) {
|
|
525
|
+
const workingCopyHistoryService = accessor.get(IWorkingCopyHistoryService);
|
|
526
|
+
const quickInputService = accessor.get(IQuickInputService);
|
|
527
|
+
const editorService = accessor.get(IEditorService);
|
|
528
|
+
const labelService = accessor.get(ILabelService);
|
|
529
|
+
const pathService = accessor.get(IPathService);
|
|
530
|
+
const resource = EditorResourceAccessor.getOriginalUri(editorService.activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY });
|
|
531
|
+
if (resource?.scheme !== pathService.defaultUriScheme && resource?.scheme !== Schemas.vscodeUserData) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const inputBox = quickInputService.createInputBox();
|
|
535
|
+
inputBox.title = ( localizeWithPath(
|
|
536
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
537
|
+
'createLocalHistoryEntryTitle',
|
|
538
|
+
"Create Local History Entry"
|
|
539
|
+
));
|
|
540
|
+
inputBox.ignoreFocusOut = true;
|
|
541
|
+
inputBox.placeholder = ( localizeWithPath(
|
|
542
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
543
|
+
'createLocalHistoryPlaceholder',
|
|
544
|
+
"Enter the new name of the local history entry for '{0}'",
|
|
545
|
+
labelService.getUriBasenameLabel(resource)
|
|
546
|
+
));
|
|
547
|
+
inputBox.show();
|
|
548
|
+
inputBox.onDidAccept(async () => {
|
|
549
|
+
const entrySource = inputBox.value;
|
|
550
|
+
inputBox.dispose();
|
|
551
|
+
if (entrySource) {
|
|
552
|
+
await workingCopyHistoryService.addEntry({ resource, source: inputBox.value }, CancellationToken.None);
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
async function openEntry(entry, editorService) {
|
|
558
|
+
const resource = LocalHistoryFileSystemProvider.toLocalHistoryFileSystem({ location: entry.location, associatedResource: entry.workingCopy.resource });
|
|
559
|
+
await editorService.openEditor({
|
|
560
|
+
resource,
|
|
561
|
+
label: ( localizeWithPath(
|
|
562
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
563
|
+
'localHistoryEditorLabel',
|
|
564
|
+
"{0} ({1} • {2})",
|
|
565
|
+
entry.workingCopy.name,
|
|
566
|
+
SaveSourceRegistry.getSourceLabel(entry.source),
|
|
567
|
+
toLocalHistoryEntryDateLabel(entry.timestamp)
|
|
568
|
+
))
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
async function closeEntry(entry, editorService) {
|
|
572
|
+
const resource = LocalHistoryFileSystemProvider.toLocalHistoryFileSystem({ location: entry.location, associatedResource: entry.workingCopy.resource });
|
|
573
|
+
const editors = editorService.findEditors(resource, { supportSideBySide: SideBySideEditor.ANY });
|
|
574
|
+
await editorService.closeEditors(editors, { preserveFocus: true });
|
|
575
|
+
}
|
|
576
|
+
function toDiffEditorArguments(arg1, arg2) {
|
|
577
|
+
const originalResource = LocalHistoryFileSystemProvider.toLocalHistoryFileSystem({ location: arg1.location, associatedResource: arg1.workingCopy.resource });
|
|
578
|
+
let label;
|
|
579
|
+
let modifiedResource;
|
|
580
|
+
if (URI.isUri(arg2)) {
|
|
581
|
+
const resource = arg2;
|
|
582
|
+
modifiedResource = resource;
|
|
583
|
+
label = ( localizeWithPath(
|
|
584
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
585
|
+
'localHistoryCompareToFileEditorLabel',
|
|
586
|
+
"{0} ({1} • {2}) ↔ {3}",
|
|
587
|
+
arg1.workingCopy.name,
|
|
588
|
+
SaveSourceRegistry.getSourceLabel(arg1.source),
|
|
589
|
+
toLocalHistoryEntryDateLabel(arg1.timestamp),
|
|
590
|
+
arg1.workingCopy.name
|
|
591
|
+
));
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
const modified = arg2;
|
|
595
|
+
modifiedResource = LocalHistoryFileSystemProvider.toLocalHistoryFileSystem({ location: modified.location, associatedResource: modified.workingCopy.resource });
|
|
596
|
+
label = ( localizeWithPath(
|
|
597
|
+
'vs/workbench/contrib/localHistory/browser/localHistoryCommands',
|
|
598
|
+
'localHistoryCompareToPreviousEditorLabel',
|
|
599
|
+
"{0} ({1} • {2}) ↔ {3} ({4} • {5})",
|
|
600
|
+
arg1.workingCopy.name,
|
|
601
|
+
SaveSourceRegistry.getSourceLabel(arg1.source),
|
|
602
|
+
toLocalHistoryEntryDateLabel(arg1.timestamp),
|
|
603
|
+
modified.workingCopy.name,
|
|
604
|
+
SaveSourceRegistry.getSourceLabel(modified.source),
|
|
605
|
+
toLocalHistoryEntryDateLabel(modified.timestamp)
|
|
606
|
+
));
|
|
607
|
+
}
|
|
608
|
+
return [
|
|
609
|
+
originalResource,
|
|
610
|
+
modifiedResource,
|
|
611
|
+
label,
|
|
612
|
+
undefined
|
|
613
|
+
];
|
|
614
|
+
}
|
|
615
|
+
async function findLocalHistoryEntry(workingCopyHistoryService, descriptor) {
|
|
616
|
+
const entries = await workingCopyHistoryService.getEntries(descriptor.uri, CancellationToken.None);
|
|
617
|
+
let currentEntry = undefined;
|
|
618
|
+
let previousEntry = undefined;
|
|
619
|
+
for (let i = 0; i < entries.length; i++) {
|
|
620
|
+
const entry = entries[i];
|
|
621
|
+
if (entry.id === descriptor.handle) {
|
|
622
|
+
currentEntry = entry;
|
|
623
|
+
previousEntry = entries[i - 1];
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
entry: currentEntry,
|
|
629
|
+
previous: previousEntry
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
const SEP = /\//g;
|
|
633
|
+
function toLocalHistoryEntryDateLabel(timestamp) {
|
|
634
|
+
return `${getLocalHistoryDateFormatter().format(timestamp).replace(SEP, '-')}`;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export { COMPARE_WITH_FILE_LABEL, findLocalHistoryEntry, toDiffEditorArguments };
|