@opensumi/ide-editor 2.27.3-rc-1710489030.0 → 2.27.3-rc-1711022312.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.
Files changed (43) hide show
  1. package/lib/browser/diff/compare.d.ts +2 -1
  2. package/lib/browser/diff/compare.d.ts.map +1 -1
  3. package/lib/browser/diff/compare.js +26 -4
  4. package/lib/browser/diff/compare.js.map +1 -1
  5. package/lib/browser/doc-model/editor-document-model.d.ts.map +1 -1
  6. package/lib/browser/doc-model/editor-document-model.js +1 -1
  7. package/lib/browser/doc-model/editor-document-model.js.map +1 -1
  8. package/lib/browser/editor.contribution.d.ts +2 -0
  9. package/lib/browser/editor.contribution.d.ts.map +1 -1
  10. package/lib/browser/editor.contribution.js +34 -0
  11. package/lib/browser/editor.contribution.js.map +1 -1
  12. package/lib/browser/editor.module.less +49 -3
  13. package/lib/browser/merge-editor/MergeEditorFloatComponents.d.ts.map +1 -1
  14. package/lib/browser/merge-editor/MergeEditorFloatComponents.js +60 -1
  15. package/lib/browser/merge-editor/MergeEditorFloatComponents.js.map +1 -1
  16. package/lib/browser/merge-editor/merge-editor.contribution.d.ts +0 -1
  17. package/lib/browser/merge-editor/merge-editor.contribution.d.ts.map +1 -1
  18. package/lib/browser/merge-editor/merge-editor.contribution.js +2 -6
  19. package/lib/browser/merge-editor/merge-editor.contribution.js.map +1 -1
  20. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.service.d.ts +1 -3
  21. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.service.d.ts.map +1 -1
  22. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.service.js.map +1 -1
  23. package/lib/browser/preference/converter.d.ts.map +1 -1
  24. package/lib/browser/preference/converter.js +51 -2
  25. package/lib/browser/preference/converter.js.map +1 -1
  26. package/lib/browser/preference/schema.d.ts +17 -0
  27. package/lib/browser/preference/schema.d.ts.map +1 -1
  28. package/lib/browser/preference/schema.js +74 -19
  29. package/lib/browser/preference/schema.js.map +1 -1
  30. package/lib/browser/workbench-editor.service.d.ts.map +1 -1
  31. package/lib/browser/workbench-editor.service.js +3 -0
  32. package/lib/browser/workbench-editor.service.js.map +1 -1
  33. package/package.json +13 -13
  34. package/src/browser/diff/compare.ts +38 -21
  35. package/src/browser/doc-model/editor-document-model.ts +2 -1
  36. package/src/browser/editor.contribution.ts +36 -0
  37. package/src/browser/editor.module.less +49 -3
  38. package/src/browser/merge-editor/MergeEditorFloatComponents.tsx +101 -4
  39. package/src/browser/merge-editor/merge-editor.contribution.ts +4 -8
  40. package/src/browser/monaco-contrib/callHierarchy/callHierarchy.service.ts +1 -2
  41. package/src/browser/preference/converter.ts +56 -3
  42. package/src/browser/preference/schema.ts +75 -18
  43. package/src/browser/workbench-editor.service.ts +2 -0
@@ -3,9 +3,11 @@ import {
3
3
  CommandContribution,
4
4
  CommandRegistry,
5
5
  CommandService,
6
+ DIFF_EDITOR_COMMANDS,
6
7
  Deferred,
7
8
  Domain,
8
9
  EDITOR_COMMANDS,
10
+ PreferenceService,
9
11
  URI,
10
12
  getIcon,
11
13
  localize,
@@ -47,13 +49,16 @@ export class CompareService implements ICompareService {
47
49
  @Domain(MenuContribution, CommandContribution)
48
50
  export class CompareEditorContribution implements MenuContribution, CommandContribution {
49
51
  @Autowired(ICompareService)
50
- compareService: CompareService;
52
+ private compareService: CompareService;
53
+
54
+ @Autowired(PreferenceService)
55
+ private preferenceService: PreferenceService;
51
56
 
52
57
  registerMenus(menu: IMenuRegistry) {
53
58
  menu.registerMenuItems(MenuId.EditorTitle, [
54
59
  {
55
60
  command: {
56
- id: 'editor.diff.accept',
61
+ id: DIFF_EDITOR_COMMANDS.ACCEPT.id,
57
62
  label: localize('editor.action.accept'),
58
63
  },
59
64
  iconClass: getIcon('check'),
@@ -64,7 +69,7 @@ export class CompareEditorContribution implements MenuContribution, CommandContr
64
69
  menu.registerMenuItems(MenuId.EditorTitle, [
65
70
  {
66
71
  command: {
67
- id: 'editor.diff.revert',
72
+ id: DIFF_EDITOR_COMMANDS.REVERT.id,
68
73
  label: localize('editor.action.revert'),
69
74
  },
70
75
  iconClass: getIcon('rollback'),
@@ -72,28 +77,40 @@ export class CompareEditorContribution implements MenuContribution, CommandContr
72
77
  when: 'isInDiffEditor && diffResource =~ /%26comparing%3Dtrue$/',
73
78
  },
74
79
  ]);
80
+ menu.registerMenuItems(MenuId.EditorTitle, [
81
+ {
82
+ command: {
83
+ id: DIFF_EDITOR_COMMANDS.TOGGLE_COLLAPSE_UNCHANGED_REGIONS.id,
84
+ label: localize('diffEditor.action.toggleCollapseUnchangedRegions'),
85
+ },
86
+ toggledWhen: 'config.diffEditor.hideUnchangedRegions.enabled',
87
+ iconClass: 'codicon codicon-map',
88
+ group: 'navigation',
89
+ when: 'isInDiffEditor',
90
+ },
91
+ ]);
75
92
  }
76
93
 
77
94
  registerCommands(commands: CommandRegistry) {
78
- commands.registerCommand(
79
- { id: 'editor.diff.accept' },
80
- {
81
- execute: (uri: URI) => {
82
- if (uri && this.compareService.comparing.has(uri.toString())) {
83
- this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.accept);
84
- }
85
- },
95
+ commands.registerCommand(DIFF_EDITOR_COMMANDS.ACCEPT, {
96
+ execute: (uri: URI) => {
97
+ if (uri && this.compareService.comparing.has(uri.toString())) {
98
+ this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.accept);
99
+ }
86
100
  },
87
- );
88
- commands.registerCommand(
89
- { id: 'editor.diff.revert' },
90
- {
91
- execute: (uri: URI) => {
92
- if (uri && this.compareService.comparing.has(uri.toString())) {
93
- this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.revert);
94
- }
95
- },
101
+ });
102
+ commands.registerCommand(DIFF_EDITOR_COMMANDS.REVERT, {
103
+ execute: (uri: URI) => {
104
+ if (uri && this.compareService.comparing.has(uri.toString())) {
105
+ this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.revert);
106
+ }
107
+ },
108
+ });
109
+ commands.registerCommand(DIFF_EDITOR_COMMANDS.TOGGLE_COLLAPSE_UNCHANGED_REGIONS, {
110
+ execute: () => {
111
+ const enabled = this.preferenceService.get('diffEditor.hideUnchangedRegions.enabled');
112
+ this.preferenceService.set('diffEditor.hideUnchangedRegions.enabled', !enabled);
96
113
  },
97
- );
114
+ });
98
115
  }
99
116
  }
@@ -4,6 +4,7 @@ import { Autowired, Injectable } from '@opensumi/di';
4
4
  import {
5
5
  CommandService,
6
6
  Disposable,
7
+ EDITOR_COMMANDS,
7
8
  Emitter,
8
9
  IEventBus,
9
10
  ILogger,
@@ -686,7 +687,7 @@ export class EditorDocumentModel extends Disposable implements IEditorDocumentMo
686
687
  reject(err);
687
688
  }, formatOnSaveTimeout);
688
689
  }),
689
- this.commandService.executeCommand('editor.action.formatDocument'),
690
+ this.commandService.executeCommand(EDITOR_COMMANDS.FORMAT_DOCUMENT.id),
690
691
  ]);
691
692
  } catch (err) {
692
693
  if (err.name === 'FormatOnSaveTimeoutError') {
@@ -16,6 +16,7 @@ import {
16
16
  IEventBus,
17
17
  IOpenerService,
18
18
  IPreferenceSettingsService,
19
+ IQuickInputService,
19
20
  IQuickOpenHandlerRegistry,
20
21
  KeybindingContribution,
21
22
  KeybindingRegistry,
@@ -172,6 +173,12 @@ export class EditorContribution
172
173
  @Autowired(IEditorDocumentModelContentRegistry)
173
174
  contentRegistry: IEditorDocumentModelContentRegistry;
174
175
 
176
+ @Autowired(IQuickInputService)
177
+ private readonly quickInputService: IQuickInputService;
178
+
179
+ @Autowired(CommandService)
180
+ private readonly commandService: CommandService;
181
+
175
182
  registerComponent(registry: ComponentRegistry) {
176
183
  registry.register('@opensumi/ide-editor', {
177
184
  id: 'ide-editor',
@@ -502,6 +509,35 @@ export class EditorContribution
502
509
  },
503
510
  });
504
511
 
512
+ commands.registerCommand(EDITOR_COMMANDS.OPEN_MERGEEDITOR_DEV, {
513
+ execute: async () => {
514
+ try {
515
+ const value = await this.quickInputService.open({ value: '' });
516
+ if (!value) {
517
+ return;
518
+ }
519
+
520
+ const toArgs = JSON.parse(value);
521
+
522
+ /**
523
+ * @example
524
+ * {
525
+ * input1: {
526
+ * uri: 'current 分支的 uri'
527
+ * },
528
+ * input2: {
529
+ * uri: 'incoming 分支的 uri'
530
+ * },
531
+ * output: '中间视图的文件 uri',
532
+ * base: '共同祖先分支的文件 uri'
533
+ * }
534
+ */
535
+
536
+ this.commandService.executeCommand(EDITOR_COMMANDS.OPEN_MERGEEDITOR.id, toArgs);
537
+ } catch (error) {}
538
+ },
539
+ });
540
+
505
541
  commands.registerCommand(EDITOR_COMMANDS.OPEN_MERGEEDITOR, {
506
542
  execute: (args: unknown) => {
507
543
  const validatedArgs = IRelaxedOpenMergeEditorArgs.validate(args);
@@ -571,8 +571,54 @@
571
571
 
572
572
  // -------------- styles for merge editor component starts --------------
573
573
  .merge_editor_float_container {
574
- position: absolute;
575
- right: 50px;
576
- bottom: 30px;
574
+ display: flex;
575
+ background: var(--kt-panelTab-activeBackground);
576
+ box-shadow: inset 1px 1px 3px 0px var(--kt-panelTab-border);
577
+ padding: 16px 28px;
578
+ justify-content: end;
579
+ white-space: nowrap;
580
+ .merge_conflict_bottom_btn {
581
+ border: 1px solid var(--kt-button-disableForeground);
582
+ border-radius: 8px;
583
+ padding: 5px 16px;
584
+ background: var(--editor-background);
585
+ margin: 0 4px;
586
+ line-height: 22px;
587
+ justify-content: end;
588
+ white-space: nowrap;
589
+ cursor: pointer;
590
+ :global {
591
+ .kt-icon {
592
+ font-size: 12px;
593
+ }
594
+ }
595
+ :first-child {
596
+ margin-right: 8px;
597
+ }
598
+ }
599
+
600
+ .magic_btn {
601
+ background-image: radial-gradient(circle at -21% -22%, #19cfff, #8429ff);
602
+ border: none;
603
+ font-weight: 500;
604
+ span {
605
+ color: #fff;
606
+ }
607
+ :global {
608
+ .kt-icon {
609
+ color: #fff;
610
+ font-size: 12px;
611
+ margin-right: 8px;
612
+ }
613
+ }
614
+ }
615
+
616
+ .line_vertical {
617
+ background-color: var(--design-border-color-common);
618
+ width: 1px;
619
+ min-width: 1px;
620
+ height: 24px;
621
+ margin: 4px;
622
+ }
577
623
  }
578
624
  // -------------- styles for merge editor component ends --------------
@@ -1,11 +1,14 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
 
3
- import { Button } from '@opensumi/ide-components';
3
+ import { Button, Icon } from '@opensumi/ide-components';
4
4
  import {
5
+ AINativeConfigService,
5
6
  CommandRegistry,
6
7
  CommandService,
8
+ IContextKeyService,
7
9
  SCM_COMMANDS,
8
10
  URI,
11
+ Uri,
9
12
  localize,
10
13
  useInjectable,
11
14
  } from '@opensumi/ide-core-browser';
@@ -14,9 +17,31 @@ import styles from '../editor.module.less';
14
17
  import { ReactEditorComponent } from '../types';
15
18
 
16
19
  export const MergeEditorFloatComponents: ReactEditorComponent<{ uri: URI }> = ({ resource }) => {
20
+ const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
17
21
  const commandService = useInjectable<CommandService>(CommandService);
18
22
  const commandRegistry = useInjectable<CommandRegistry>(CommandRegistry);
23
+ const contextKeyService = useInjectable<IContextKeyService>(IContextKeyService);
19
24
 
25
+ const [isVisiable, setIsVisiable] = useState(false);
26
+
27
+ const gitMergeChangesSet = new Set(['git.mergeChanges']);
28
+
29
+ useEffect(() => {
30
+ const run = () => {
31
+ const mergeChanges = contextKeyService.getValue<Uri[]>('git.mergeChanges') || [];
32
+ setIsVisiable(mergeChanges.some((value) => value.toString() === resource.uri.toString()));
33
+ };
34
+
35
+ const disposed = contextKeyService.onDidChangeContext(({ payload }) => {
36
+ if (payload.affectsSome(gitMergeChangesSet)) {
37
+ run();
38
+ }
39
+ });
40
+ run();
41
+ return () => disposed.dispose();
42
+ }, [resource]);
43
+
44
+ const [isAiResolving, setIsAiResolving] = useState(false);
20
45
  const handleOpenMergeEditor = useCallback(async () => {
21
46
  const { uri } = resource;
22
47
 
@@ -27,11 +52,83 @@ export const MergeEditorFloatComponents: ReactEditorComponent<{ uri: URI }> = ({
27
52
  });
28
53
  }, [resource]);
29
54
 
55
+ const isSupportAiResolve = useCallback(
56
+ () => aiNativeConfigService.capabilities.supportsConflictResolve,
57
+ [aiNativeConfigService],
58
+ );
59
+
60
+ const handlePrev = () => {
61
+ commandService.tryExecuteCommand('merge-conflict.previous');
62
+ };
63
+
64
+ const handleNext = () => {
65
+ commandService.tryExecuteCommand('merge-conflict.next');
66
+ };
67
+
68
+ const handleAIResolve = useCallback(async () => {
69
+ setIsAiResolving(true);
70
+ if (isAiResolving) {
71
+ await commandService.executeCommand('merge-conflict.ai.all-accept-stop', resource.uri);
72
+ } else {
73
+ await commandService.executeCommand('merge-conflict.ai.all-accept', resource.uri);
74
+ }
75
+ setIsAiResolving(false);
76
+ }, [resource, isAiResolving]);
77
+
78
+ const handleReset = useCallback(() => {
79
+ commandService.executeCommand('merge-conflict.ai.all-reset', resource.uri);
80
+ }, [resource]);
81
+
82
+ if (!isVisiable) {
83
+ return null;
84
+ }
85
+
30
86
  return (
31
87
  <div className={styles.merge_editor_float_container}>
32
- <Button size='large' onClick={handleOpenMergeEditor}>
33
- {localize('mergeEditor.open.in.editor')}
88
+ <div id='merge.editor.action.button.accept'>
89
+ <Button className={styles.merge_conflict_bottom_btn} size='large' onClick={handlePrev}>
90
+ <Icon icon={'left'} />
91
+ <span>{localize('mergeEditor.conflict.prev')}</span>
92
+ </Button>
93
+ <Button className={styles.merge_conflict_bottom_btn} size='large' onClick={handleNext}>
94
+ <span>{localize('mergeEditor.conflict.next')}</span>
95
+ <Icon icon={'right'} />
96
+ </Button>
97
+ </div>
98
+ <span className={styles.line_vertical}></span>
99
+ <Button
100
+ id='merge.editor.open.tradition'
101
+ className={styles.merge_conflict_bottom_btn}
102
+ size='large'
103
+ onClick={handleOpenMergeEditor}
104
+ >
105
+ <Icon icon={'swap'} />
106
+ <span>{localize('mergeEditor.open.3way')}</span>
107
+ </Button>
108
+ <Button id='merge.editor.rest' className={styles.merge_conflict_bottom_btn} size='large' onClick={handleReset}>
109
+ <Icon icon={'discard'} />
110
+ <span>{localize('mergeEditor.reset')}</span>
34
111
  </Button>
112
+ {isSupportAiResolve() && (
113
+ <Button
114
+ id='merge.editor.conflict.resolve.all'
115
+ size='large'
116
+ className={`${styles.merge_conflict_bottom_btn} ${styles.magic_btn}`}
117
+ onClick={handleAIResolve}
118
+ >
119
+ {isAiResolving ? (
120
+ <>
121
+ <Icon icon={'circle-pause'} />
122
+ <span>{localize('mergeEditor.conflict.resolve.all.stop')}</span>
123
+ </>
124
+ ) : (
125
+ <>
126
+ <Icon icon={'magic-wand'} />
127
+ <span>{localize('mergeEditor.conflict.resolve.all')}</span>
128
+ </>
129
+ )}
130
+ </Button>
131
+ )}
35
132
  </div>
36
133
  );
37
134
  };
@@ -1,5 +1,5 @@
1
1
  import { Autowired } from '@opensumi/di';
2
- import { Disposable, Domain, IContextKeyService, Schemes, Uri } from '@opensumi/ide-core-browser';
2
+ import { Disposable, Domain, Schemes } from '@opensumi/ide-core-browser';
3
3
 
4
4
  import { ResourceService } from '../../common';
5
5
  import { BrowserEditorContribution, EditorComponentRegistry, EditorOpenType } from '../types';
@@ -14,9 +14,6 @@ export class MergeEditorContribution extends Disposable implements BrowserEditor
14
14
  @Autowired()
15
15
  private readonly mergeEditorResourceProvider: MergeEditorResourceProvider;
16
16
 
17
- @Autowired(IContextKeyService)
18
- private readonly contextKeyService: IContextKeyService;
19
-
20
17
  registerResource(resourceService: ResourceService): void {
21
18
  resourceService.registerResourceProvider(this.mergeEditorResourceProvider);
22
19
  }
@@ -30,15 +27,14 @@ export class MergeEditorContribution extends Disposable implements BrowserEditor
30
27
 
31
28
  registry.registerEditorSideWidget({
32
29
  id: MERGE_EDITOR_FLOATING_WIDGET,
33
- component: MergeEditorFloatComponents as any,
30
+ component: MergeEditorFloatComponents,
34
31
  displaysOnResource: (resource) => {
35
32
  const { uri } = resource;
36
33
  if (uri.scheme !== Schemes.file) {
37
34
  return false;
38
35
  }
39
-
40
- const mergeChanges = this.contextKeyService.getValue<Uri[]>('git.mergeChanges') || [];
41
- return mergeChanges.some((value) => value.toString() === uri.toString());
36
+ // 由于存在时序问题,具体是否显示的逻辑由组件内部处理
37
+ return true;
42
38
  },
43
39
  });
44
40
  }
@@ -17,13 +17,12 @@ import {
17
17
  IncomingCall,
18
18
  OutgoingCall,
19
19
  } from '@opensumi/ide-monaco/lib/browser/contrib/callHierarchy';
20
- import { ITextModel, Position } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
20
+ import { ITextModel, Position, ProviderResult } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
21
21
 
22
22
  import { IEditorDocumentModelService } from '../../doc-model/types';
23
23
 
24
24
  const { isNonEmptyArray } = arrays;
25
25
 
26
- declare type ProviderResult<T> = T | undefined | null | Thenable<T | undefined | null>;
27
26
  /* ---------------------------------------------------------------------------------------------
28
27
  * Copyright (c) Microsoft Corporation. All rights reserved.
29
28
  * Licensed under the MIT License. See License.txt in the project root for license information.
@@ -42,7 +42,14 @@ export function getConvertedMonacoOptions(
42
42
  editorOptions[key] = value;
43
43
  } else {
44
44
  const converter: IMonacoOptionsConverter = editorOptionsConverters.get(key)! as IMonacoOptionsConverter;
45
- editorOptions[converter.monaco] = converter.convert ? converter.convert(value) : value;
45
+ if (!editorOptions[converter.monaco]) {
46
+ editorOptions[converter.monaco] = converter.convert ? converter.convert(value) : value;
47
+ } else {
48
+ editorOptions[converter.monaco] = {
49
+ ...editorOptions[converter.monaco],
50
+ ...(converter.convert ? converter.convert(value) : value),
51
+ };
52
+ }
46
53
  }
47
54
  });
48
55
 
@@ -74,7 +81,14 @@ export function getConvertedMonacoOptions(
74
81
  editorOptions[key] = value;
75
82
  } else {
76
83
  const converter: IMonacoOptionsConverter = diffEditorOptionsConverters.get(key)! as IMonacoOptionsConverter;
77
- diffOptions[converter.monaco] = converter.convert ? converter.convert(value) : value;
84
+ if (diffOptions[converter.monaco]) {
85
+ diffOptions[converter.monaco] = {
86
+ ...diffOptions[converter.monaco],
87
+ ...(converter.convert ? converter.convert(value) : value),
88
+ };
89
+ } else {
90
+ diffOptions[converter.monaco] = converter.convert ? converter.convert(value) : value;
91
+ }
78
92
  }
79
93
  });
80
94
 
@@ -786,7 +800,6 @@ export const diffEditorOptionsConverters: Map<KaitianPreferenceKey, NoConverter
786
800
  * Defaults to false.
787
801
  */
788
802
  ['diffEditor.originalEditable', { monaco: 'originalEditable' }],
789
-
790
803
  [
791
804
  'diffEditor.minimap',
792
805
  {
@@ -796,6 +809,46 @@ export const diffEditorOptionsConverters: Map<KaitianPreferenceKey, NoConverter
796
809
  }),
797
810
  },
798
811
  ],
812
+
813
+ /**
814
+ * Controls whether the diff editor shows unchanged regions.
815
+ */
816
+ [
817
+ 'diffEditor.hideUnchangedRegions.enabled',
818
+ { monaco: 'hideUnchangedRegions', convert: (value) => ({ enabled: value }) },
819
+ ],
820
+ /**
821
+ * Controls how many lines are used for unchanged regions.
822
+ */
823
+ [
824
+ 'diffEditor.hideUnchangedRegions.revealLineCount',
825
+ { monaco: 'hideUnchangedRegions', convert: (value) => ({ revealLineCount: value }) },
826
+ ],
827
+ /**
828
+ * Controls how many lines are used as a minimum for unchanged regions.
829
+ */
830
+ [
831
+ 'diffEditor.hideUnchangedRegions.minimumLineCount',
832
+ { monaco: 'hideUnchangedRegions', convert: (value) => ({ minimumLineCount: value }) },
833
+ ],
834
+ /**
835
+ * Controls how many lines are used as context when comparing unchanged regions.
836
+ */
837
+ [
838
+ 'diffEditor.hideUnchangedRegions.contextLineCount',
839
+ { monaco: 'hideUnchangedRegions', convert: (value) => ({ contextLineCount: value }) },
840
+ ],
841
+ /**
842
+ * Controls whether the diff editor should show detected code moves.
843
+ */
844
+ ['diffEditor.experimental.showMoves', { monaco: 'experimental', convert: (value) => ({ showMoves: value }) }],
845
+ /**
846
+ * Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted.
847
+ */
848
+ [
849
+ 'diffEditor.experimental.showEmptyDecorations',
850
+ { monaco: 'experimental', convert: (value) => ({ showEmptyDecorations: value }) },
851
+ ],
799
852
  ]);
800
853
 
801
854
  function isContainOptionKey(key: string, optionMap: Map<KaitianPreferenceKey, NoConverter | IMonacoOptionsConverter>) {
@@ -137,7 +137,7 @@ export const EDITOR_DEFAULTS = {
137
137
  extraEditorClassName: '',
138
138
  disableMonospaceOptimizations: false,
139
139
  rulers: [],
140
- ariaLabel: localize('editorViewAccessibleLabel', 'Editor content'),
140
+ ariaLabel: localize('editorViewAccessibleLabel', 'Editor Content'),
141
141
  renderLineNumbers: 0,
142
142
  renderCustomLineNumbers: null,
143
143
  renderFinalNewline: true,
@@ -239,6 +239,24 @@ export const EDITOR_DEFAULTS = {
239
239
  },
240
240
  };
241
241
 
242
+ export const DIFF_EDITOR_DEFAULTS = {
243
+ renderIndicators: true,
244
+ minimap: false,
245
+ renderSideBySide: true,
246
+ ignoreTrimWhitespace: false,
247
+ hideUnchangedRegions: {
248
+ enabled: true,
249
+ revealLineCount: 20,
250
+ minimumLineCount: 3,
251
+ contextLineCount: 3,
252
+ },
253
+ experimental: {
254
+ showMoves: false,
255
+ showEmptyDecorations: true,
256
+ collapseUnchangedRegions: true,
257
+ },
258
+ };
259
+
242
260
  const monacoEditorSchema: PreferenceSchemaProperties = {
243
261
  'editor.ariaLabel': {
244
262
  type: 'string',
@@ -1412,15 +1430,6 @@ const monacoEditorSchema: PreferenceSchemaProperties = {
1412
1430
  default: EDITOR_MODEL_DEFAULTS.largeFileOptimizations,
1413
1431
  description: '%editor.configuration.largeFileOptimizations%',
1414
1432
  },
1415
- 'diffEditor.renderIndicators': {
1416
- type: 'boolean',
1417
- default: true,
1418
- description: '%editor.configuration.renderIndicators%',
1419
- },
1420
- 'diffEditor.minimap': {
1421
- type: 'boolean',
1422
- default: false,
1423
- },
1424
1433
  'editor.defaultFormatter': {
1425
1434
  type: 'string',
1426
1435
  description: '%editor.configuration.defaultFormatter%',
@@ -1430,6 +1439,15 @@ const monacoEditorSchema: PreferenceSchemaProperties = {
1430
1439
  default: true,
1431
1440
  description: '%editor.configuration.unicodeHighlight.ambiguousCharacters%',
1432
1441
  },
1442
+ 'diffEditor.renderIndicators': {
1443
+ type: 'boolean',
1444
+ default: DIFF_EDITOR_DEFAULTS.renderIndicators,
1445
+ description: '%editor.configuration.renderIndicators%',
1446
+ },
1447
+ 'diffEditor.minimap': {
1448
+ type: 'boolean',
1449
+ default: DIFF_EDITOR_DEFAULTS.minimap,
1450
+ },
1433
1451
  };
1434
1452
 
1435
1453
  const customEditorSchema: PreferenceSchemaProperties = {
@@ -1622,25 +1640,64 @@ const customEditorSchema: PreferenceSchemaProperties = {
1622
1640
  type: 'string',
1623
1641
  },
1624
1642
  },
1625
- 'diffEditor.renderSideBySide': {
1643
+ 'editor.experimental.stickyScroll.enabled': {
1644
+ type: 'boolean',
1645
+ default: false,
1646
+ description: '%editor.configuration.experimental.stickyScroll.enabled%',
1647
+ },
1648
+ 'editor.mouseBackForwardToNavigate': {
1626
1649
  type: 'boolean',
1627
1650
  default: true,
1651
+ description: '%editor.configuration.mouseBackForwardToNavigate%',
1652
+ },
1653
+ 'diffEditor.renderSideBySide': {
1654
+ type: 'boolean',
1655
+ default: DIFF_EDITOR_DEFAULTS.renderSideBySide,
1628
1656
  description: '%diffEditor.configuration.renderSideBySide%',
1629
1657
  },
1630
1658
  'diffEditor.ignoreTrimWhitespace': {
1631
1659
  type: 'boolean',
1632
- default: false,
1660
+ default: DIFF_EDITOR_DEFAULTS.ignoreTrimWhitespace,
1633
1661
  description: '%diffEditor.configuration.ignoreTrimWhitespace%',
1634
1662
  },
1635
- 'editor.experimental.stickyScroll.enabled': {
1663
+ 'diffEditor.hideUnchangedRegions.enabled': {
1636
1664
  type: 'boolean',
1637
- default: false,
1638
- description: '%editor.configuration.experimental.stickyScroll.enabled%',
1665
+ default: DIFF_EDITOR_DEFAULTS.hideUnchangedRegions.enabled,
1666
+ description: 'Controls whether the diff editor shows unchanged regions.',
1639
1667
  },
1640
- 'editor.mouseBackForwardToNavigate': {
1668
+ 'diffEditor.hideUnchangedRegions.revealLineCount': {
1669
+ type: 'integer',
1670
+ default: DIFF_EDITOR_DEFAULTS.hideUnchangedRegions.revealLineCount,
1671
+ description: 'Controls how many lines are used for unchanged regions.',
1672
+ minimum: 1,
1673
+ },
1674
+ 'diffEditor.hideUnchangedRegions.minimumLineCount': {
1675
+ type: 'integer',
1676
+ default: DIFF_EDITOR_DEFAULTS.hideUnchangedRegions.minimumLineCount,
1677
+ description: 'Controls how many lines are used as a minimum for unchanged regions.',
1678
+ minimum: 1,
1679
+ },
1680
+ 'diffEditor.hideUnchangedRegions.contextLineCount': {
1681
+ type: 'integer',
1682
+ default: DIFF_EDITOR_DEFAULTS.hideUnchangedRegions.contextLineCount,
1683
+ description: 'Controls how many lines are used as context when comparing unchanged regions.',
1684
+ minimum: 1,
1685
+ },
1686
+ 'diffEditor.experimental.showMoves': {
1641
1687
  type: 'boolean',
1642
- default: true,
1643
- description: '%editor.configuration.mouseBackForwardToNavigate%',
1688
+ default: DIFF_EDITOR_DEFAULTS.experimental.showMoves,
1689
+ description: 'Controls whether the diff editor should show detected code moves.',
1690
+ },
1691
+ 'diffEditor.experimental.showEmptyDecorations': {
1692
+ type: 'boolean',
1693
+ default: DIFF_EDITOR_DEFAULTS.experimental.showEmptyDecorations,
1694
+ description:
1695
+ 'Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted.',
1696
+ },
1697
+ 'diffEditor.experimental.collapseUnchangedRegions': {
1698
+ type: 'boolean',
1699
+ default: DIFF_EDITOR_DEFAULTS.experimental.collapseUnchangedRegions,
1700
+ description: 'Controls whether the diff editor shows unchanged regions.',
1644
1701
  },
1645
1702
  };
1646
1703
 
@@ -1503,6 +1503,8 @@ export class EditorGroup extends WithEventBus implements IGridEditorGroup {
1503
1503
  const query = uri.getParsedQuery();
1504
1504
  this.doDisposeDocRef(new URI(query.original));
1505
1505
  this.doDisposeDocRef(new URI(query.modified));
1506
+ } else if (uri.scheme === 'mergeEditor') {
1507
+ this.mergeEditor.dispose();
1506
1508
  } else {
1507
1509
  this.doDisposeDocRef(uri);
1508
1510
  }