Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffActions.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 { IBulkEditService, ResourceTextEdit } from '../../../../../editor/browser/services/bulkEditService.js';
7
import { localize, localize2 } from '../../../../../nls.js';
8
import { Action2, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js';
9
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
10
import { ContextKeyExpr, ContextKeyExpression } from '../../../../../platform/contextkey/common/contextkey.js';
11
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
12
import { ActiveEditorContext } from '../../../../common/contextkeys.js';
13
import { DiffElementCellViewModelBase, NotebookDocumentMetadataViewModel, SideBySideDiffElementViewModel } from './diffElementViewModel.js';
14
import { INotebookTextDiffEditor, NOTEBOOK_DIFF_CELL_IGNORE_WHITESPACE_KEY, NOTEBOOK_DIFF_CELL_INPUT, NOTEBOOK_DIFF_CELL_PROPERTY, NOTEBOOK_DIFF_CELL_PROPERTY_EXPANDED, NOTEBOOK_DIFF_HAS_UNCHANGED_CELLS, NOTEBOOK_DIFF_ITEM_DIFF_STATE, NOTEBOOK_DIFF_ITEM_KIND, NOTEBOOK_DIFF_METADATA, NOTEBOOK_DIFF_UNCHANGED_CELLS_HIDDEN } from './notebookDiffEditorBrowser.js';
15
import { NotebookTextDiffEditor } from './notebookDiffEditor.js';
16
import { NotebookDiffEditorInput } from '../../common/notebookDiffEditorInput.js';
17
import { nextChangeIcon, openAsTextIcon, previousChangeIcon, renderOutputIcon, revertIcon, toggleWhitespace } from '../notebookIcons.js';
18
import { IEditorService } from '../../../../services/editor/common/editorService.js';
19
import { Registry } from '../../../../../platform/registry/common/platform.js';
20
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../../../platform/configuration/common/configurationRegistry.js';
21
import { ICommandActionTitle } from '../../../../../platform/action/common/action.js';
22
import { DEFAULT_EDITOR_ASSOCIATION } from '../../../../common/editor.js';
23
import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
24
import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';
25
import { CellEditType, ICellEditOperation, NOTEBOOK_DIFF_EDITOR_ID } from '../../common/notebookCommon.js';
26
import { ITextResourceConfigurationService } from '../../../../../editor/common/services/textResourceConfiguration.js';
27
import { NotebookMultiTextDiffEditor } from './notebookMultiDiffEditor.js';
28
import { Codicon } from '../../../../../base/common/codicons.js';
29
import type { URI } from '../../../../../base/common/uri.js';
30
import { TextEditorSelectionRevealType, type ITextEditorOptions } from '../../../../../platform/editor/common/editor.js';
31
import product from '../../../../../platform/product/common/product.js';
32
import { ctxHasEditorModification, ctxHasRequestInProgress } from '../../../chat/browser/chatEditing/chatEditingEditorContextKeys.js';
33
34
// ActiveEditorContext.isEqualTo(SearchEditorConstants.SearchEditorID)
35
36
registerAction2(class extends Action2 {
37
constructor() {
38
super({
39
id: 'notebook.diff.openFile',
40
icon: Codicon.goToFile,
41
title: localize2('notebook.diff.openFile', 'Open File'),
42
precondition: ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
43
menu: [{
44
id: MenuId.EditorTitle,
45
group: 'navigation',
46
when: ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
47
}]
48
});
49
}
50
51
async run(accessor: ServicesAccessor): Promise<void> {
52
const editorService = accessor.get(IEditorService);
53
54
const activeEditor = editorService.activeEditorPane;
55
if (!activeEditor) {
56
return;
57
}
58
if (activeEditor instanceof NotebookTextDiffEditor || activeEditor instanceof NotebookMultiTextDiffEditor) {
59
const diffEditorInput = activeEditor.input as NotebookDiffEditorInput;
60
const resource = diffEditorInput.modified.resource;
61
await editorService.openEditor({ resource });
62
}
63
}
64
});
65
66
registerAction2(class extends Action2 {
67
constructor() {
68
super({
69
id: 'notebook.diff.cell.toggleCollapseUnchangedRegions',
70
title: localize2('notebook.diff.cell.toggleCollapseUnchangedRegions', 'Toggle Collapse Unchanged Regions'),
71
icon: Codicon.map,
72
toggled: ContextKeyExpr.has('config.diffEditor.hideUnchangedRegions.enabled'),
73
precondition: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID),
74
menu: {
75
id: MenuId.EditorTitle,
76
group: 'navigation',
77
when: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID),
78
},
79
});
80
}
81
82
run(accessor: ServicesAccessor, ...args: unknown[]): void {
83
const configurationService = accessor.get(IConfigurationService);
84
const newValue = !configurationService.getValue<boolean>('diffEditor.hideUnchangedRegions.enabled');
85
configurationService.updateValue('diffEditor.hideUnchangedRegions.enabled', newValue);
86
}
87
});
88
89
90
registerAction2(class extends Action2 {
91
constructor() {
92
super({
93
id: 'notebook.diff.switchToText',
94
icon: openAsTextIcon,
95
title: localize2('notebook.diff.switchToText', 'Open Text Diff Editor'),
96
precondition: ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
97
menu: [{
98
id: MenuId.EditorTitle,
99
group: 'navigation',
100
when: ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
101
}]
102
});
103
}
104
105
async run(accessor: ServicesAccessor): Promise<void> {
106
const editorService = accessor.get(IEditorService);
107
108
const activeEditor = editorService.activeEditorPane;
109
if (!activeEditor) {
110
return;
111
}
112
if (activeEditor instanceof NotebookTextDiffEditor || activeEditor instanceof NotebookMultiTextDiffEditor) {
113
const diffEditorInput = activeEditor.input as NotebookDiffEditorInput;
114
115
await editorService.openEditor(
116
{
117
original: { resource: diffEditorInput.original.resource },
118
modified: { resource: diffEditorInput.resource },
119
label: diffEditorInput.getName(),
120
options: {
121
preserveFocus: false,
122
override: DEFAULT_EDITOR_ASSOCIATION.id
123
}
124
});
125
}
126
}
127
});
128
129
130
registerAction2(class extends Action2 {
131
constructor() {
132
super({
133
id: 'notebook.diffEditor.showUnchangedCells',
134
title: localize2('showUnchangedCells', 'Show Unchanged Cells'),
135
icon: Codicon.unfold,
136
precondition: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.has(NOTEBOOK_DIFF_HAS_UNCHANGED_CELLS.key)),
137
menu: {
138
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.has(NOTEBOOK_DIFF_HAS_UNCHANGED_CELLS.key), ContextKeyExpr.equals(NOTEBOOK_DIFF_UNCHANGED_CELLS_HIDDEN.key, true)),
139
id: MenuId.EditorTitle,
140
order: 22,
141
group: 'navigation',
142
},
143
});
144
}
145
146
run(accessor: ServicesAccessor, ...args: unknown[]): void {
147
const activeEditor = accessor.get(IEditorService).activeEditorPane;
148
if (!activeEditor) {
149
return;
150
}
151
if (activeEditor instanceof NotebookMultiTextDiffEditor) {
152
activeEditor.showUnchanged();
153
}
154
}
155
});
156
157
registerAction2(class extends Action2 {
158
constructor() {
159
super({
160
id: 'notebook.diffEditor.hideUnchangedCells',
161
title: localize2('hideUnchangedCells', 'Hide Unchanged Cells'),
162
icon: Codicon.fold,
163
precondition: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.has(NOTEBOOK_DIFF_HAS_UNCHANGED_CELLS.key)),
164
menu: {
165
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.has(NOTEBOOK_DIFF_HAS_UNCHANGED_CELLS.key), ContextKeyExpr.equals(NOTEBOOK_DIFF_UNCHANGED_CELLS_HIDDEN.key, false)),
166
id: MenuId.EditorTitle,
167
order: 22,
168
group: 'navigation',
169
},
170
});
171
}
172
173
run(accessor: ServicesAccessor, ...args: unknown[]): void {
174
const activeEditor = accessor.get(IEditorService).activeEditorPane;
175
if (!activeEditor) {
176
return;
177
}
178
if (activeEditor instanceof NotebookMultiTextDiffEditor) {
179
activeEditor.hideUnchanged();
180
}
181
}
182
});
183
184
registerAction2(class GoToFileAction extends Action2 {
185
constructor() {
186
super({
187
id: 'notebook.diffEditor.2.goToCell',
188
title: localize2('goToCell', 'Go To Cell'),
189
icon: Codicon.goToFile,
190
menu: {
191
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_KIND.key, 'Cell'), ContextKeyExpr.notEquals(NOTEBOOK_DIFF_ITEM_DIFF_STATE.key, 'delete')),
192
id: MenuId.MultiDiffEditorFileToolbar,
193
order: 0,
194
group: 'navigation',
195
},
196
});
197
}
198
199
async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
200
const uri = args[0] as URI;
201
const editorService = accessor.get(IEditorService);
202
const activeEditorPane = editorService.activeEditorPane;
203
if (!(activeEditorPane instanceof NotebookMultiTextDiffEditor)) {
204
return;
205
}
206
207
await editorService.openEditor({
208
resource: uri,
209
options: {
210
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,
211
} satisfies ITextEditorOptions,
212
});
213
}
214
});
215
216
217
registerAction2(class extends Action2 {
218
constructor() {
219
super(
220
{
221
id: 'notebook.diff.revertMetadata',
222
title: localize('notebook.diff.revertMetadata', "Revert Notebook Metadata"),
223
icon: revertIcon,
224
f1: false,
225
menu: {
226
id: MenuId.NotebookDiffDocumentMetadata,
227
when: NOTEBOOK_DIFF_METADATA,
228
},
229
precondition: NOTEBOOK_DIFF_METADATA
230
231
}
232
);
233
}
234
run(accessor: ServicesAccessor, context?: NotebookDocumentMetadataViewModel) {
235
if (!context) {
236
return;
237
}
238
239
const editorService = accessor.get(IEditorService);
240
const activeEditorPane = editorService.activeEditorPane;
241
if (!(activeEditorPane instanceof NotebookTextDiffEditor)) {
242
return;
243
}
244
245
context.modifiedDocumentTextModel.applyEdits([{
246
editType: CellEditType.DocumentMetadata,
247
metadata: context.originalMetadata.metadata,
248
}], true, undefined, () => undefined, undefined, true);
249
}
250
});
251
252
const revertInput = localize('notebook.diff.cell.revertInput', "Revert Input");
253
254
registerAction2(class extends Action2 {
255
constructor() {
256
super({
257
id: 'notebook.diffEditor.2.cell.revertInput',
258
title: revertInput,
259
icon: revertIcon,
260
menu: {
261
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_KIND.key, 'Cell'), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_DIFF_STATE.key, 'modified')),
262
id: MenuId.MultiDiffEditorFileToolbar,
263
order: 2,
264
group: 'navigation',
265
},
266
});
267
}
268
269
async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
270
const uri = args[0] as URI;
271
const editorService = accessor.get(IEditorService);
272
const activeEditorPane = editorService.activeEditorPane;
273
if (!(activeEditorPane instanceof NotebookMultiTextDiffEditor)) {
274
return;
275
}
276
277
const item = activeEditorPane.getDiffElementViewModel(uri);
278
if (item && item instanceof SideBySideDiffElementViewModel) {
279
const modified = item.modified;
280
const original = item.original;
281
282
if (!original || !modified) {
283
return;
284
}
285
286
const bulkEditService = accessor.get(IBulkEditService);
287
await bulkEditService.apply([
288
new ResourceTextEdit(modified.uri, { range: modified.textModel.getFullModelRange(), text: original.textModel.getValue() }),
289
], { quotableLabel: 'Revert Notebook Cell Content Change' });
290
}
291
}
292
});
293
294
const revertOutputs = localize('notebook.diff.cell.revertOutputs', "Revert Outputs");
295
296
registerAction2(class extends Action2 {
297
constructor() {
298
super(
299
{
300
id: 'notebook.diffEditor.2.cell.revertOutputs',
301
title: revertOutputs,
302
icon: revertIcon,
303
f1: false,
304
menu: {
305
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_KIND.key, 'Output'), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_DIFF_STATE.key, 'modified')),
306
id: MenuId.MultiDiffEditorFileToolbar,
307
order: 2,
308
group: 'navigation',
309
},
310
}
311
);
312
}
313
async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
314
const uri = args[0] as URI;
315
const editorService = accessor.get(IEditorService);
316
const activeEditorPane = editorService.activeEditorPane;
317
if (!(activeEditorPane instanceof NotebookMultiTextDiffEditor)) {
318
return;
319
}
320
321
const item = activeEditorPane.getDiffElementViewModel(uri);
322
if (item && item instanceof SideBySideDiffElementViewModel) {
323
const original = item.original;
324
325
const modifiedCellIndex = item.modifiedDocument.cells.findIndex(cell => cell.handle === item.modified.handle);
326
if (modifiedCellIndex === -1) {
327
return;
328
}
329
330
item.mainDocumentTextModel.applyEdits([{
331
editType: CellEditType.Output, index: modifiedCellIndex, outputs: original.outputs
332
}], true, undefined, () => undefined, undefined, true);
333
}
334
}
335
});
336
337
const revertMetadata = localize('notebook.diff.cell.revertMetadata', "Revert Metadata");
338
339
registerAction2(class extends Action2 {
340
constructor() {
341
super(
342
{
343
id: 'notebook.diffEditor.2.cell.revertMetadata',
344
title: revertMetadata,
345
icon: revertIcon,
346
f1: false,
347
menu: {
348
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_KIND.key, 'Metadata'), ContextKeyExpr.equals(NOTEBOOK_DIFF_ITEM_DIFF_STATE.key, 'modified')),
349
id: MenuId.MultiDiffEditorFileToolbar,
350
order: 2,
351
group: 'navigation',
352
},
353
}
354
);
355
}
356
async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
357
const uri = args[0] as URI;
358
const editorService = accessor.get(IEditorService);
359
const activeEditorPane = editorService.activeEditorPane;
360
if (!(activeEditorPane instanceof NotebookMultiTextDiffEditor)) {
361
return;
362
}
363
364
const item = activeEditorPane.getDiffElementViewModel(uri);
365
if (item && item instanceof SideBySideDiffElementViewModel) {
366
const original = item.original;
367
368
const modifiedCellIndex = item.modifiedDocument.cells.findIndex(cell => cell.handle === item.modified.handle);
369
if (modifiedCellIndex === -1) {
370
return;
371
}
372
373
item.mainDocumentTextModel.applyEdits([{
374
editType: CellEditType.Metadata, index: modifiedCellIndex, metadata: original.metadata
375
}], true, undefined, () => undefined, undefined, true);
376
}
377
}
378
});
379
380
381
registerAction2(class extends Action2 {
382
constructor() {
383
super(
384
{
385
id: 'notebook.diff.cell.revertMetadata',
386
title: revertMetadata,
387
icon: revertIcon,
388
f1: false,
389
menu: {
390
id: MenuId.NotebookDiffCellMetadataTitle,
391
when: NOTEBOOK_DIFF_CELL_PROPERTY
392
},
393
precondition: NOTEBOOK_DIFF_CELL_PROPERTY
394
}
395
);
396
}
397
run(accessor: ServicesAccessor, context?: DiffElementCellViewModelBase) {
398
if (!context) {
399
return;
400
}
401
402
if (!(context instanceof SideBySideDiffElementViewModel)) {
403
return;
404
}
405
406
const original = context.original;
407
const modified = context.modified;
408
409
const modifiedCellIndex = context.mainDocumentTextModel.cells.indexOf(modified.textModel);
410
if (modifiedCellIndex === -1) {
411
return;
412
}
413
414
const rawEdits: ICellEditOperation[] = [{ editType: CellEditType.Metadata, index: modifiedCellIndex, metadata: original.metadata }];
415
if (context.original.language && context.modified.language !== context.original.language) {
416
rawEdits.push({ editType: CellEditType.CellLanguage, index: modifiedCellIndex, language: context.original.language });
417
}
418
419
context.modifiedDocument.applyEdits(rawEdits, true, undefined, () => undefined, undefined, true);
420
}
421
});
422
423
// registerAction2(class extends Action2 {
424
// constructor() {
425
// super(
426
// {
427
// id: 'notebook.diff.cell.switchOutputRenderingStyle',
428
// title: localize('notebook.diff.cell.switchOutputRenderingStyle', "Switch Outputs Rendering"),
429
// icon: renderOutputIcon,
430
// f1: false,
431
// menu: {
432
// id: MenuId.NotebookDiffCellOutputsTitle
433
// }
434
// }
435
// );
436
// }
437
// run(accessor: ServicesAccessor, context?: DiffElementViewModelBase) {
438
// if (!context) {
439
// return;
440
// }
441
442
// context.renderOutput = true;
443
// }
444
// });
445
446
447
registerAction2(class extends Action2 {
448
constructor() {
449
super(
450
{
451
id: 'notebook.diff.cell.switchOutputRenderingStyleToText',
452
title: localize('notebook.diff.cell.switchOutputRenderingStyleToText', "Switch Output Rendering"),
453
icon: renderOutputIcon,
454
f1: false,
455
menu: {
456
id: MenuId.NotebookDiffCellOutputsTitle,
457
when: NOTEBOOK_DIFF_CELL_PROPERTY_EXPANDED
458
}
459
}
460
);
461
}
462
run(accessor: ServicesAccessor, context?: DiffElementCellViewModelBase) {
463
if (!context) {
464
return;
465
}
466
467
context.renderOutput = !context.renderOutput;
468
}
469
});
470
471
registerAction2(class extends Action2 {
472
constructor() {
473
super(
474
{
475
id: 'notebook.diff.cell.revertOutputs',
476
title: localize('notebook.diff.cell.revertOutputs', "Revert Outputs"),
477
icon: revertIcon,
478
f1: false,
479
menu: {
480
id: MenuId.NotebookDiffCellOutputsTitle,
481
when: NOTEBOOK_DIFF_CELL_PROPERTY
482
},
483
precondition: NOTEBOOK_DIFF_CELL_PROPERTY
484
}
485
);
486
}
487
run(accessor: ServicesAccessor, context?: DiffElementCellViewModelBase) {
488
if (!context) {
489
return;
490
}
491
492
if (!(context instanceof SideBySideDiffElementViewModel)) {
493
return;
494
}
495
496
const original = context.original;
497
const modified = context.modified;
498
499
const modifiedCellIndex = context.mainDocumentTextModel.cells.indexOf(modified.textModel);
500
if (modifiedCellIndex === -1) {
501
return;
502
}
503
504
context.mainDocumentTextModel.applyEdits([{
505
editType: CellEditType.Output, index: modifiedCellIndex, outputs: original.outputs
506
}], true, undefined, () => undefined, undefined, true);
507
}
508
});
509
510
511
registerAction2(class extends Action2 {
512
constructor() {
513
super(
514
{
515
id: 'notebook.toggle.diff.cell.ignoreTrimWhitespace',
516
title: localize('ignoreTrimWhitespace.label', "Show Leading/Trailing Whitespace Differences"),
517
icon: toggleWhitespace,
518
f1: false,
519
menu: {
520
id: MenuId.NotebookDiffCellInputTitle,
521
when: NOTEBOOK_DIFF_CELL_INPUT,
522
order: 1,
523
},
524
precondition: NOTEBOOK_DIFF_CELL_INPUT,
525
toggled: ContextKeyExpr.equals(NOTEBOOK_DIFF_CELL_IGNORE_WHITESPACE_KEY, false),
526
}
527
);
528
}
529
run(accessor: ServicesAccessor, context?: DiffElementCellViewModelBase) {
530
const cell = context;
531
if (!cell?.modified) {
532
return;
533
}
534
const uri = cell.modified.uri;
535
const configService = accessor.get(ITextResourceConfigurationService);
536
const key = 'diffEditor.ignoreTrimWhitespace';
537
const val = configService.getValue(uri, key);
538
configService.updateValue(uri, key, !val);
539
}
540
});
541
542
registerAction2(class extends Action2 {
543
constructor() {
544
super(
545
{
546
id: 'notebook.diff.cell.revertInput',
547
title: revertInput,
548
icon: revertIcon,
549
f1: false,
550
menu: {
551
id: MenuId.NotebookDiffCellInputTitle,
552
when: NOTEBOOK_DIFF_CELL_INPUT,
553
order: 2
554
},
555
precondition: NOTEBOOK_DIFF_CELL_INPUT
556
557
}
558
);
559
}
560
run(accessor: ServicesAccessor, context?: DiffElementCellViewModelBase) {
561
if (!context) {
562
return;
563
}
564
565
const original = context.original;
566
const modified = context.modified;
567
568
if (!original || !modified) {
569
return;
570
}
571
572
const bulkEditService = accessor.get(IBulkEditService);
573
return bulkEditService.apply([
574
new ResourceTextEdit(modified.uri, { range: modified.textModel.getFullModelRange(), text: original.textModel.getValue() }),
575
], { quotableLabel: 'Revert Notebook Cell Content Change' });
576
}
577
});
578
579
class ToggleRenderAction extends Action2 {
580
constructor(id: string, title: string | ICommandActionTitle, precondition: ContextKeyExpression | undefined, toggled: ContextKeyExpression | undefined, order: number, private readonly toggleOutputs?: boolean, private readonly toggleMetadata?: boolean) {
581
super({
582
id: id,
583
title,
584
precondition: precondition,
585
menu: [{
586
id: MenuId.EditorTitle,
587
group: 'notebook',
588
when: precondition,
589
order: order,
590
}],
591
toggled: toggled
592
});
593
}
594
595
async run(accessor: ServicesAccessor): Promise<void> {
596
const configurationService = accessor.get(IConfigurationService);
597
598
if (this.toggleOutputs !== undefined) {
599
const oldValue = configurationService.getValue('notebook.diff.ignoreOutputs');
600
configurationService.updateValue('notebook.diff.ignoreOutputs', !oldValue);
601
}
602
603
if (this.toggleMetadata !== undefined) {
604
const oldValue = configurationService.getValue('notebook.diff.ignoreMetadata');
605
configurationService.updateValue('notebook.diff.ignoreMetadata', !oldValue);
606
}
607
}
608
}
609
610
registerAction2(class extends ToggleRenderAction {
611
constructor() {
612
super('notebook.diff.showOutputs',
613
localize2('notebook.diff.showOutputs', 'Show Outputs Differences'),
614
ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
615
ContextKeyExpr.notEquals('config.notebook.diff.ignoreOutputs', true),
616
2,
617
true,
618
undefined
619
);
620
}
621
});
622
623
registerAction2(class extends ToggleRenderAction {
624
constructor() {
625
super('notebook.diff.showMetadata',
626
localize2('notebook.diff.showMetadata', 'Show Metadata Differences'),
627
ContextKeyExpr.or(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID), ActiveEditorContext.isEqualTo(NotebookMultiTextDiffEditor.ID)),
628
ContextKeyExpr.notEquals('config.notebook.diff.ignoreMetadata', true),
629
1,
630
undefined,
631
true
632
);
633
}
634
});
635
636
registerAction2(class extends Action2 {
637
constructor() {
638
super(
639
{
640
id: 'notebook.diff.action.previous',
641
title: localize('notebook.diff.action.previous.title', "Show Previous Change"),
642
icon: previousChangeIcon,
643
f1: false,
644
keybinding: {
645
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.F3,
646
weight: KeybindingWeight.WorkbenchContrib,
647
when: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID)
648
},
649
menu: {
650
id: MenuId.EditorTitle,
651
group: 'navigation',
652
when: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID)
653
}
654
}
655
);
656
}
657
run(accessor: ServicesAccessor) {
658
const editorService: IEditorService = accessor.get(IEditorService);
659
if (editorService.activeEditorPane?.getId() !== NOTEBOOK_DIFF_EDITOR_ID) {
660
return;
661
}
662
663
const editor = editorService.activeEditorPane.getControl() as INotebookTextDiffEditor | undefined;
664
editor?.previousChange();
665
}
666
});
667
668
registerAction2(class extends Action2 {
669
constructor() {
670
super(
671
{
672
id: 'notebook.diff.action.next',
673
title: localize('notebook.diff.action.next.title', "Show Next Change"),
674
icon: nextChangeIcon,
675
f1: false,
676
keybinding: {
677
primary: KeyMod.Alt | KeyCode.F3,
678
weight: KeybindingWeight.WorkbenchContrib,
679
when: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID)
680
},
681
menu: {
682
id: MenuId.EditorTitle,
683
group: 'navigation',
684
when: ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID)
685
}
686
}
687
);
688
}
689
run(accessor: ServicesAccessor) {
690
const editorService: IEditorService = accessor.get(IEditorService);
691
if (editorService.activeEditorPane?.getId() !== NOTEBOOK_DIFF_EDITOR_ID) {
692
return;
693
}
694
695
const editor = editorService.activeEditorPane.getControl() as INotebookTextDiffEditor | undefined;
696
editor?.nextChange();
697
}
698
});
699
700
registerAction2(class extends Action2 {
701
constructor() {
702
super(
703
{
704
id: 'notebook.diff.inline.toggle',
705
title: localize('notebook.diff.inline.toggle.title', "Toggle Inline View"),
706
menu: {
707
id: MenuId.EditorTitle,
708
group: '1_diff',
709
order: 10,
710
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(NotebookTextDiffEditor.ID),
711
ContextKeyExpr.equals('config.notebook.diff.experimental.toggleInline', true),
712
ctxHasEditorModification.negate(), ctxHasRequestInProgress.negate())
713
}
714
}
715
);
716
}
717
run(accessor: ServicesAccessor) {
718
const editorService: IEditorService = accessor.get(IEditorService);
719
if (editorService.activeEditorPane?.getId() !== NOTEBOOK_DIFF_EDITOR_ID) {
720
return;
721
}
722
723
const editor = editorService.activeEditorPane.getControl() as INotebookTextDiffEditor | undefined;
724
editor?.toggleInlineView();
725
}
726
});
727
728
729
730
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({
731
id: 'notebook',
732
order: 100,
733
type: 'object',
734
'properties': {
735
'notebook.diff.ignoreMetadata': {
736
type: 'boolean',
737
default: false,
738
markdownDescription: localize('notebook.diff.ignoreMetadata', "Hide Metadata Differences")
739
},
740
'notebook.diff.ignoreOutputs': {
741
type: 'boolean',
742
default: false,
743
markdownDescription: localize('notebook.diff.ignoreOutputs', "Hide Outputs Differences")
744
},
745
'notebook.diff.experimental.toggleInline': {
746
type: 'boolean',
747
default: typeof product.quality === 'string' && product.quality !== 'stable', // only enable as default in insiders
748
markdownDescription: localize('notebook.diff.toggleInline', "Enable the command to toggle the experimental notebook inline diff editor.")
749
},
750
}
751
});
752
753