@opensumi/ide-editor 3.9.1-next-1749175927.0 → 3.9.1-next-1749196667.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/lib/browser/base-editor-wrapper.d.ts +58 -0
- package/lib/browser/base-editor-wrapper.d.ts.map +1 -0
- package/lib/browser/base-editor-wrapper.js +203 -0
- package/lib/browser/base-editor-wrapper.js.map +1 -0
- package/lib/browser/decoration-applier.d.ts.map +1 -1
- package/lib/browser/decoration-applier.js.map +1 -1
- package/lib/browser/editor-collection.service.d.ts +21 -57
- package/lib/browser/editor-collection.service.d.ts.map +1 -1
- package/lib/browser/editor-collection.service.js +42 -206
- package/lib/browser/editor-collection.service.js.map +1 -1
- package/lib/browser/editor.contribution.d.ts.map +1 -1
- package/lib/browser/editor.contribution.js +1 -0
- package/lib/browser/editor.contribution.js.map +1 -1
- package/lib/browser/editor.less +25 -0
- package/lib/browser/editor.view.js +1 -1
- package/lib/browser/editor.view.js.map +1 -1
- package/lib/browser/multi-diff/multi-diff-editor.d.ts +10 -7
- package/lib/browser/multi-diff/multi-diff-editor.d.ts.map +1 -1
- package/lib/browser/multi-diff/multi-diff-editor.js +60 -7
- package/lib/browser/multi-diff/multi-diff-editor.js.map +1 -1
- package/lib/browser/multi-diff/multi-diff-resource.d.ts.map +1 -1
- package/lib/browser/multi-diff/multi-diff-resource.js.map +1 -1
- package/lib/browser/workbench-editor.service.js +1 -1
- package/lib/browser/workbench-editor.service.js.map +1 -1
- package/lib/common/editor.d.ts +2 -0
- package/lib/common/editor.d.ts.map +1 -1
- package/lib/common/editor.js.map +1 -1
- package/lib/common/multi-diff.d.ts +6 -1
- package/lib/common/multi-diff.d.ts.map +1 -1
- package/lib/common/multi-diff.js.map +1 -1
- package/package.json +14 -14
- package/src/browser/base-editor-wrapper.ts +254 -0
- package/src/browser/decoration-applier.ts +1 -0
- package/src/browser/editor-collection.service.ts +48 -263
- package/src/browser/editor.contribution.ts +2 -0
- package/src/browser/editor.less +25 -0
- package/src/browser/editor.view.tsx +1 -1
- package/src/browser/multi-diff/multi-diff-editor.ts +91 -10
- package/src/browser/multi-diff/multi-diff-resource.ts +0 -1
- package/src/browser/workbench-editor.service.ts +1 -1
- package/src/common/editor.ts +2 -0
- package/src/common/multi-diff.ts +8 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
|
|
2
|
+
import { IRange } from '@opensumi/ide-core-browser';
|
|
3
|
+
import { Disposable, ISelection, URI, WithEventBus, isEmptyObject, objects } from '@opensumi/ide-core-common';
|
|
4
|
+
import * as monaco from '@opensumi/ide-monaco';
|
|
5
|
+
import { IConfigurationService } from '@opensumi/monaco-editor-core/esm/vs/platform/configuration/common/configuration';
|
|
6
|
+
|
|
7
|
+
import { EditorType, IDecorationApplyOptions, IEditor, IUndoStopOptions } from '../common';
|
|
8
|
+
import { IEditorDocumentModel } from '../common/editor';
|
|
9
|
+
|
|
10
|
+
import { MonacoEditorDecorationApplier } from './decoration-applier';
|
|
11
|
+
import { getConvertedMonacoOptions, isEditorOption } from './preference/converter';
|
|
12
|
+
import { IEditorFeatureRegistry } from './types';
|
|
13
|
+
|
|
14
|
+
import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
|
|
15
|
+
|
|
16
|
+
export type ISumiEditor = IEditor;
|
|
17
|
+
|
|
18
|
+
export function insertSnippetWithMonacoEditor(
|
|
19
|
+
editor: IMonacoCodeEditor,
|
|
20
|
+
template: string,
|
|
21
|
+
ranges: IRange[],
|
|
22
|
+
opts: IUndoStopOptions,
|
|
23
|
+
) {
|
|
24
|
+
const snippetController = editor.getContribution('snippetController2') as any;
|
|
25
|
+
const selections: ISelection[] = ranges.map(
|
|
26
|
+
(r) => new monaco.Selection(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn),
|
|
27
|
+
);
|
|
28
|
+
editor.setSelections(selections);
|
|
29
|
+
editor.focus();
|
|
30
|
+
|
|
31
|
+
snippetController.insert(template, 0, 0, opts.undoStopBefore, opts.undoStopAfter);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { removeUndefined } = objects;
|
|
35
|
+
|
|
36
|
+
function updateOptionsWithMonacoEditor(
|
|
37
|
+
monacoEditor: IMonacoCodeEditor,
|
|
38
|
+
editorOptions: monaco.editor.IEditorOptions,
|
|
39
|
+
modelOptions: monaco.editor.ITextModelUpdateOptions,
|
|
40
|
+
) {
|
|
41
|
+
monacoEditor.updateOptions(editorOptions);
|
|
42
|
+
if (monacoEditor.getModel()) {
|
|
43
|
+
monacoEditor.getModel()!.updateOptions(modelOptions);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Injectable({ multiple: true })
|
|
48
|
+
export abstract class BaseMonacoEditorWrapper extends WithEventBus implements IEditor {
|
|
49
|
+
public abstract readonly currentDocumentModel: IEditorDocumentModel | null;
|
|
50
|
+
|
|
51
|
+
public get currentUri(): URI | null {
|
|
52
|
+
return this.currentDocumentModel ? this.currentDocumentModel.uri : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public getId() {
|
|
56
|
+
return this.monacoEditor.getId();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getSelections() {
|
|
60
|
+
return this.monacoEditor.getSelections() || [];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public onFocus = this.monacoEditor.onDidFocusEditorWidget;
|
|
64
|
+
|
|
65
|
+
public onBlur = this.monacoEditor.onDidBlurEditorWidget;
|
|
66
|
+
|
|
67
|
+
protected _specialEditorOptions: any = {};
|
|
68
|
+
|
|
69
|
+
protected _specialModelOptions: monaco.editor.ITextModelUpdateOptions = {};
|
|
70
|
+
|
|
71
|
+
protected _editorOptionsFromContribution: any = {};
|
|
72
|
+
|
|
73
|
+
@Autowired(IEditorFeatureRegistry)
|
|
74
|
+
protected readonly editorFeatureRegistry: IEditorFeatureRegistry;
|
|
75
|
+
|
|
76
|
+
@Autowired(IConfigurationService)
|
|
77
|
+
protected readonly configurationService: IConfigurationService;
|
|
78
|
+
|
|
79
|
+
protected readonly decorationApplier: MonacoEditorDecorationApplier;
|
|
80
|
+
|
|
81
|
+
private _disableSelectionEmitter = false;
|
|
82
|
+
|
|
83
|
+
protected disableSelectionEmitter() {
|
|
84
|
+
this._disableSelectionEmitter = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected enableSelectionEmitter() {
|
|
88
|
+
this._disableSelectionEmitter = false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Autowired(INJECTOR_TOKEN)
|
|
92
|
+
private injector: Injector;
|
|
93
|
+
|
|
94
|
+
constructor(public readonly monacoEditor: IMonacoCodeEditor, private type: EditorType) {
|
|
95
|
+
super();
|
|
96
|
+
this.decorationApplier = this.injector.get(MonacoEditorDecorationApplier, [this.monacoEditor]);
|
|
97
|
+
this.addDispose(this.monacoEditor.onDidChangeModel(this.onDidChangeModel.bind(this)));
|
|
98
|
+
this.addDispose(
|
|
99
|
+
this.monacoEditor.onDidChangeModelLanguage(() => {
|
|
100
|
+
this._doUpdateOptions();
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
this.addDispose(
|
|
104
|
+
this.configurationService.onDidChangeConfiguration((e) => {
|
|
105
|
+
const changedEditorKeys = Array.from(e.affectedKeys.values()).filter((key) => isEditorOption(key));
|
|
106
|
+
if (changedEditorKeys.length > 0) {
|
|
107
|
+
this._doUpdateOptions();
|
|
108
|
+
}
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private async onDidChangeModel() {
|
|
114
|
+
this._editorOptionsFromContribution = {};
|
|
115
|
+
const uri = this.currentUri;
|
|
116
|
+
if (uri) {
|
|
117
|
+
Promise.resolve(this.editorFeatureRegistry.runProvideEditorOptionsForUri(uri)).then((options) => {
|
|
118
|
+
if (!this.currentUri || !uri.isEqual(this.currentUri)) {
|
|
119
|
+
return; // uri可能已经变了
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (options && Object.keys(options).length > 0) {
|
|
123
|
+
this._editorOptionsFromContribution = options;
|
|
124
|
+
if (!isEmptyObject(this._editorOptionsFromContribution)) {
|
|
125
|
+
this._doUpdateOptions();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public getType() {
|
|
133
|
+
return this.type;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
updateOptions(
|
|
137
|
+
editorOptions: monaco.editor.IEditorOptions = {},
|
|
138
|
+
modelOptions: monaco.editor.ITextModelUpdateOptions = {},
|
|
139
|
+
) {
|
|
140
|
+
this._specialEditorOptions = removeUndefined({ ...this._specialEditorOptions, ...editorOptions });
|
|
141
|
+
this._specialModelOptions = removeUndefined({ ...this._specialModelOptions, ...modelOptions });
|
|
142
|
+
this._doUpdateOptions();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private _doUpdateOptions() {
|
|
146
|
+
const { editorOptions, modelOptions } = this._calculateFinalOptions();
|
|
147
|
+
updateOptionsWithMonacoEditor(this.monacoEditor, editorOptions, modelOptions);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 合并所有的选项
|
|
152
|
+
* 优先关系: (从高到底)
|
|
153
|
+
* 1. 当前编辑器的特殊选项(通过调用 updateOptions或者启动时传入)
|
|
154
|
+
* 2. 来自 featureRegistry 的根据 当前uri 提供的选项
|
|
155
|
+
* 3. 来自偏好设置的选项
|
|
156
|
+
*/
|
|
157
|
+
private _calculateFinalOptions() {
|
|
158
|
+
const uriStr = this.currentUri ? this.currentUri.toString() : undefined;
|
|
159
|
+
const languageId = this.currentDocumentModel ? this.currentDocumentModel.languageId : undefined;
|
|
160
|
+
const options = getConvertedMonacoOptions(this.configurationService, uriStr, languageId, undefined);
|
|
161
|
+
const basicEditorOptions: Partial<monaco.editor.IEditorOptions> = {
|
|
162
|
+
readOnly: this.currentDocumentModel?.readonly || false,
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
let editorOptions = {
|
|
166
|
+
...basicEditorOptions,
|
|
167
|
+
...options.editorOptions,
|
|
168
|
+
...this._editorOptionsFromContribution,
|
|
169
|
+
...this._specialEditorOptions,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (this.type !== EditorType.CODE) {
|
|
173
|
+
editorOptions = {
|
|
174
|
+
...editorOptions,
|
|
175
|
+
...options.diffOptions,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
editorOptions,
|
|
181
|
+
modelOptions: { ...options.modelOptions, ...this._specialModelOptions },
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
insertSnippet(template: string, ranges: IRange[], opts: IUndoStopOptions) {
|
|
186
|
+
insertSnippetWithMonacoEditor(this.monacoEditor, template, ranges, opts);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
applyDecoration(key: string, options: IDecorationApplyOptions[]) {
|
|
190
|
+
this.decorationApplier.applyDecoration(key, options);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
onSelectionsChanged(listener) {
|
|
194
|
+
return this.monacoEditor.onDidChangeCursorSelection((e) => {
|
|
195
|
+
if (!this._disableSelectionEmitter) {
|
|
196
|
+
listener({
|
|
197
|
+
selections: this.getSelections(),
|
|
198
|
+
source: e.source,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
onVisibleRangesChanged(listener) {
|
|
205
|
+
const disposer = new Disposable();
|
|
206
|
+
const monacoEditor = this.monacoEditor;
|
|
207
|
+
disposer.addDispose(
|
|
208
|
+
monacoEditor.onDidScrollChange((e) => {
|
|
209
|
+
listener(this.monacoEditor.getVisibleRanges());
|
|
210
|
+
}),
|
|
211
|
+
);
|
|
212
|
+
disposer.addDispose(
|
|
213
|
+
monacoEditor.onDidLayoutChange((e) => {
|
|
214
|
+
listener(this.monacoEditor.getVisibleRanges());
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
217
|
+
return disposer;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
setSelections(selections) {
|
|
221
|
+
return this.monacoEditor.setSelections(selections as any);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
setSelection(selection) {
|
|
225
|
+
return this.monacoEditor.setSelection(selection as any);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public async save(): Promise<void> {
|
|
229
|
+
if (this.currentDocumentModel) {
|
|
230
|
+
await this.currentDocumentModel.save();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
onConfigurationChanged(listener) {
|
|
235
|
+
const monacoEditor = this.monacoEditor;
|
|
236
|
+
return monacoEditor.onDidChangeConfiguration((e) => {
|
|
237
|
+
listener();
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
@Injectable({ multiple: true })
|
|
242
|
+
export class DiffEditorPart extends BaseMonacoEditorWrapper implements IEditor {
|
|
243
|
+
get currentDocumentModel() {
|
|
244
|
+
return this.getDocumentModel();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
constructor(
|
|
248
|
+
monacoEditor: IMonacoCodeEditor,
|
|
249
|
+
private getDocumentModel: () => IEditorDocumentModel | null,
|
|
250
|
+
type: EditorType,
|
|
251
|
+
) {
|
|
252
|
+
super(monacoEditor, type);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -34,6 +34,7 @@ export class MonacoEditorDecorationApplier extends Disposable {
|
|
|
34
34
|
constructor(private editor: IMonacoCodeEditor) {
|
|
35
35
|
super();
|
|
36
36
|
this.applyDecorationFromProvider();
|
|
37
|
+
|
|
37
38
|
this.editor.onDidChangeModel(() => {
|
|
38
39
|
this.clearDecorations();
|
|
39
40
|
this.applyDecorationFromProvider();
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
|
|
2
|
-
import {
|
|
2
|
+
import { IContextKeyService, PreferenceService } from '@opensumi/ide-core-browser';
|
|
3
3
|
import { ResourceContextKey } from '@opensumi/ide-core-browser/lib/contextkey';
|
|
4
4
|
import { MonacoService } from '@opensumi/ide-core-browser/lib/monaco';
|
|
5
5
|
import {
|
|
6
|
-
Disposable,
|
|
7
6
|
Emitter,
|
|
8
7
|
Event,
|
|
9
8
|
Emitter as EventEmitter,
|
|
10
9
|
ILineChange,
|
|
11
|
-
ISelection,
|
|
12
10
|
OnEvent,
|
|
13
11
|
URI,
|
|
14
12
|
WithEventBus,
|
|
15
|
-
isEmptyObject,
|
|
16
|
-
objects,
|
|
17
13
|
} from '@opensumi/ide-core-common';
|
|
18
14
|
import * as monaco from '@opensumi/ide-monaco';
|
|
19
15
|
import { IConfigurationService } from '@opensumi/monaco-editor-core/esm/vs/platform/configuration/common/configuration';
|
|
@@ -24,21 +20,19 @@ import {
|
|
|
24
20
|
EditorCollectionService,
|
|
25
21
|
EditorType,
|
|
26
22
|
ICodeEditor,
|
|
27
|
-
IDecorationApplyOptions,
|
|
28
23
|
IDiffEditor,
|
|
29
24
|
IEditor,
|
|
30
|
-
IResource,
|
|
31
25
|
IResourceOpenOptions,
|
|
32
|
-
IUndoStopOptions,
|
|
33
26
|
ResourceDecorationNeedChangeEvent,
|
|
34
27
|
} from '../common';
|
|
35
|
-
import {
|
|
28
|
+
import { IEditorDocumentModelRef, isTextEditorViewState } from '../common/editor';
|
|
29
|
+
import { IMultiDiffEditor } from '../common/multi-diff';
|
|
36
30
|
|
|
37
|
-
import {
|
|
31
|
+
import { BaseMonacoEditorWrapper, DiffEditorPart, ISumiEditor } from './base-editor-wrapper';
|
|
38
32
|
import { EditorDocumentModelContentChangedEvent, IEditorDocumentModelService } from './doc-model/types';
|
|
39
33
|
import { EditorFeatureRegistryImpl } from './feature';
|
|
40
34
|
import { BrowserMultiDiffEditor } from './multi-diff/multi-diff-editor';
|
|
41
|
-
import { getConvertedMonacoOptions, isDiffEditorOption
|
|
35
|
+
import { getConvertedMonacoOptions, isDiffEditorOption } from './preference/converter';
|
|
42
36
|
import { IConvertedMonacoOptions, IEditorFeatureRegistry } from './types';
|
|
43
37
|
|
|
44
38
|
import type {
|
|
@@ -47,8 +41,6 @@ import type {
|
|
|
47
41
|
} from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
|
|
48
42
|
import type { IDiffEditorConstructionOptions } from '@opensumi/monaco-editor-core/esm/vs/editor/browser/editorBrowser';
|
|
49
43
|
|
|
50
|
-
const { removeUndefined } = objects;
|
|
51
|
-
|
|
52
44
|
@Injectable()
|
|
53
45
|
export class EditorCollectionServiceImpl extends WithEventBus implements EditorCollectionService {
|
|
54
46
|
@Autowired()
|
|
@@ -65,12 +57,23 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
65
57
|
|
|
66
58
|
private _editors: Set<ISumiEditor> = new Set();
|
|
67
59
|
private _diffEditors: Set<IDiffEditor> = new Set();
|
|
60
|
+
private _multiDiffEditors: Set<IMultiDiffEditor> = new Set();
|
|
68
61
|
|
|
69
62
|
private _onCodeEditorCreate = new Emitter<ICodeEditor>();
|
|
70
63
|
private _onDiffEditorCreate = new Emitter<IDiffEditor>();
|
|
64
|
+
private _onMultiDiffEditorCreate = new Emitter<IMultiDiffEditor>();
|
|
65
|
+
|
|
66
|
+
private _onCodeEditorChange = new Emitter<void>();
|
|
67
|
+
private _onDiffEditorChange = new Emitter<void>();
|
|
68
|
+
private _onMultiDiffEditorChange = new Emitter<void>();
|
|
71
69
|
|
|
72
70
|
public onCodeEditorCreate = this._onCodeEditorCreate.event;
|
|
73
71
|
public onDiffEditorCreate = this._onDiffEditorCreate.event;
|
|
72
|
+
public onMultiDiffEditorCreate = this._onMultiDiffEditorCreate.event;
|
|
73
|
+
|
|
74
|
+
public onCodeEditorChange = this._onCodeEditorChange.event;
|
|
75
|
+
public onDiffEditorChange = this._onDiffEditorChange.event;
|
|
76
|
+
public onMultiDiffEditorChange = this._onMultiDiffEditorChange.event;
|
|
74
77
|
|
|
75
78
|
@Autowired(IEditorDocumentModelService)
|
|
76
79
|
documentModelService: IEditorDocumentModelService;
|
|
@@ -128,7 +131,7 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
128
131
|
}
|
|
129
132
|
});
|
|
130
133
|
if (this._editors.size !== beforeSize) {
|
|
131
|
-
|
|
134
|
+
this._onCodeEditorChange.fire();
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
137
|
|
|
@@ -141,7 +144,7 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
141
144
|
}
|
|
142
145
|
});
|
|
143
146
|
if (this._editors.size !== beforeSize) {
|
|
144
|
-
|
|
147
|
+
this._onCodeEditorChange.fire();
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
|
|
@@ -154,11 +157,11 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
154
157
|
return editor;
|
|
155
158
|
}
|
|
156
159
|
|
|
157
|
-
createMultiDiffEditor(dom: HTMLElement, options?: any, overrides?: { [key: string]: any }) {
|
|
160
|
+
public createMultiDiffEditor(dom: HTMLElement, options?: any, overrides?: { [key: string]: any }) {
|
|
158
161
|
const convertedOptions = getConvertedMonacoOptions(this.configurationService);
|
|
159
162
|
const monacoMultiDiffEditorWidget = this.monacoService.createMultiDiffEditorWidget(dom, overrides);
|
|
160
163
|
const mergedOptions: IConvertedMonacoOptions = { ...convertedOptions.diffOptions, ...options };
|
|
161
|
-
const editor = this.injector.get(BrowserMultiDiffEditor, [monacoMultiDiffEditorWidget, mergedOptions]);
|
|
164
|
+
const editor = this.injector.get(BrowserMultiDiffEditor, [monacoMultiDiffEditorWidget, mergedOptions, this]);
|
|
162
165
|
return editor;
|
|
163
166
|
}
|
|
164
167
|
|
|
@@ -187,7 +190,7 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
187
190
|
}
|
|
188
191
|
});
|
|
189
192
|
if (this._diffEditors.size !== beforeSize) {
|
|
190
|
-
|
|
193
|
+
this._onDiffEditorChange.fire();
|
|
191
194
|
}
|
|
192
195
|
}
|
|
193
196
|
|
|
@@ -197,11 +200,36 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
197
200
|
this._diffEditors.delete(diffEditor);
|
|
198
201
|
});
|
|
199
202
|
if (this._diffEditors.size !== beforeSize) {
|
|
200
|
-
|
|
203
|
+
this._onDiffEditorChange.fire();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public listMultiDiffEditors(): IMultiDiffEditor[] {
|
|
208
|
+
return Array.from(this._multiDiffEditors.values());
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public addMultiDiffEditors(multiDiffEditors: IMultiDiffEditor[]) {
|
|
212
|
+
const beforeSize = this._multiDiffEditors.size;
|
|
213
|
+
multiDiffEditors.forEach((multiDiffEditor) => {
|
|
214
|
+
if (!this._multiDiffEditors.has(multiDiffEditor)) {
|
|
215
|
+
this._multiDiffEditors.add(multiDiffEditor);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
if (this._multiDiffEditors.size !== beforeSize) {
|
|
219
|
+
this._onMultiDiffEditorChange.fire();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
public removeMultiDiffEditors(multiDiffEditors: IMultiDiffEditor[]) {
|
|
224
|
+
const beforeSize = this._multiDiffEditors.size;
|
|
225
|
+
multiDiffEditors.forEach((multiDiffEditor) => {
|
|
226
|
+
this._multiDiffEditors.delete(multiDiffEditor);
|
|
227
|
+
});
|
|
228
|
+
if (this._multiDiffEditors.size !== beforeSize) {
|
|
229
|
+
this._onMultiDiffEditorChange.fire();
|
|
201
230
|
}
|
|
202
231
|
}
|
|
203
232
|
|
|
204
|
-
// 将docModel的变更事件反映至resource的dirty装饰
|
|
205
233
|
@OnEvent(EditorDocumentModelContentChangedEvent)
|
|
206
234
|
onDocModelContentChangedEvent(e: EditorDocumentModelContentChangedEvent) {
|
|
207
235
|
this.eventBus.fire(
|
|
@@ -216,230 +244,6 @@ export class EditorCollectionServiceImpl extends WithEventBus implements EditorC
|
|
|
216
244
|
}
|
|
217
245
|
}
|
|
218
246
|
|
|
219
|
-
export type ISumiEditor = IEditor;
|
|
220
|
-
|
|
221
|
-
export function insertSnippetWithMonacoEditor(
|
|
222
|
-
editor: IMonacoCodeEditor,
|
|
223
|
-
template: string,
|
|
224
|
-
ranges: IRange[],
|
|
225
|
-
opts: IUndoStopOptions,
|
|
226
|
-
) {
|
|
227
|
-
const snippetController = editor.getContribution('snippetController2') as any;
|
|
228
|
-
const selections: ISelection[] = ranges.map(
|
|
229
|
-
(r) => new monaco.Selection(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn),
|
|
230
|
-
);
|
|
231
|
-
editor.setSelections(selections);
|
|
232
|
-
editor.focus();
|
|
233
|
-
|
|
234
|
-
snippetController.insert(template, 0, 0, opts.undoStopBefore, opts.undoStopAfter);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function updateOptionsWithMonacoEditor(
|
|
238
|
-
monacoEditor: IMonacoCodeEditor,
|
|
239
|
-
editorOptions: monaco.editor.IEditorOptions,
|
|
240
|
-
modelOptions: monaco.editor.ITextModelUpdateOptions,
|
|
241
|
-
) {
|
|
242
|
-
monacoEditor.updateOptions(editorOptions);
|
|
243
|
-
if (monacoEditor.getModel()) {
|
|
244
|
-
monacoEditor.getModel()!.updateOptions(modelOptions);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
@Injectable({ multiple: true })
|
|
249
|
-
export abstract class BaseMonacoEditorWrapper extends WithEventBus implements IEditor {
|
|
250
|
-
public abstract readonly currentDocumentModel: IEditorDocumentModel | null;
|
|
251
|
-
|
|
252
|
-
public get currentUri(): URI | null {
|
|
253
|
-
return this.currentDocumentModel ? this.currentDocumentModel.uri : null;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
public getId() {
|
|
257
|
-
return this.monacoEditor.getId();
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
getSelections() {
|
|
261
|
-
return this.monacoEditor.getSelections() || [];
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
public onFocus = this.monacoEditor.onDidFocusEditorWidget;
|
|
265
|
-
|
|
266
|
-
public onBlur = this.monacoEditor.onDidBlurEditorWidget;
|
|
267
|
-
|
|
268
|
-
protected _specialEditorOptions: any = {};
|
|
269
|
-
|
|
270
|
-
protected _specialModelOptions: monaco.editor.ITextModelUpdateOptions = {};
|
|
271
|
-
|
|
272
|
-
protected _editorOptionsFromContribution: any = {};
|
|
273
|
-
|
|
274
|
-
@Autowired(IEditorFeatureRegistry)
|
|
275
|
-
protected readonly editorFeatureRegistry: IEditorFeatureRegistry;
|
|
276
|
-
|
|
277
|
-
@Autowired(IConfigurationService)
|
|
278
|
-
protected readonly configurationService: IConfigurationService;
|
|
279
|
-
|
|
280
|
-
protected readonly decorationApplier: MonacoEditorDecorationApplier;
|
|
281
|
-
|
|
282
|
-
private _disableSelectionEmitter = false;
|
|
283
|
-
|
|
284
|
-
protected disableSelectionEmitter() {
|
|
285
|
-
this._disableSelectionEmitter = true;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
protected enableSelectionEmitter() {
|
|
289
|
-
this._disableSelectionEmitter = false;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
@Autowired(INJECTOR_TOKEN)
|
|
293
|
-
private injector: Injector;
|
|
294
|
-
|
|
295
|
-
constructor(public readonly monacoEditor: IMonacoCodeEditor, private type: EditorType) {
|
|
296
|
-
super();
|
|
297
|
-
this.decorationApplier = this.injector.get(MonacoEditorDecorationApplier, [this.monacoEditor]);
|
|
298
|
-
this.addDispose(this.monacoEditor.onDidChangeModel(this.onDidChangeModel.bind(this)));
|
|
299
|
-
this.addDispose(
|
|
300
|
-
this.monacoEditor.onDidChangeModelLanguage(() => {
|
|
301
|
-
this._doUpdateOptions();
|
|
302
|
-
}),
|
|
303
|
-
);
|
|
304
|
-
this.addDispose(
|
|
305
|
-
this.configurationService.onDidChangeConfiguration((e) => {
|
|
306
|
-
const changedEditorKeys = Array.from(e.affectedKeys.values()).filter((key) => isEditorOption(key));
|
|
307
|
-
if (changedEditorKeys.length > 0) {
|
|
308
|
-
this._doUpdateOptions();
|
|
309
|
-
}
|
|
310
|
-
}),
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private async onDidChangeModel() {
|
|
315
|
-
this._editorOptionsFromContribution = {};
|
|
316
|
-
const uri = this.currentUri;
|
|
317
|
-
if (uri) {
|
|
318
|
-
Promise.resolve(this.editorFeatureRegistry.runProvideEditorOptionsForUri(uri)).then((options) => {
|
|
319
|
-
if (!this.currentUri || !uri.isEqual(this.currentUri)) {
|
|
320
|
-
return; // uri可能已经变了
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (options && Object.keys(options).length > 0) {
|
|
324
|
-
this._editorOptionsFromContribution = options;
|
|
325
|
-
if (!isEmptyObject(this._editorOptionsFromContribution)) {
|
|
326
|
-
this._doUpdateOptions();
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
public getType() {
|
|
334
|
-
return this.type;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
updateOptions(
|
|
338
|
-
editorOptions: monaco.editor.IEditorOptions = {},
|
|
339
|
-
modelOptions: monaco.editor.ITextModelUpdateOptions = {},
|
|
340
|
-
) {
|
|
341
|
-
this._specialEditorOptions = removeUndefined({ ...this._specialEditorOptions, ...editorOptions });
|
|
342
|
-
this._specialModelOptions = removeUndefined({ ...this._specialModelOptions, ...modelOptions });
|
|
343
|
-
this._doUpdateOptions();
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
private _doUpdateOptions() {
|
|
347
|
-
const { editorOptions, modelOptions } = this._calculateFinalOptions();
|
|
348
|
-
updateOptionsWithMonacoEditor(this.monacoEditor, editorOptions, modelOptions);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* 合并所有的选项
|
|
353
|
-
* 优先关系: (从高到底)
|
|
354
|
-
* 1. 当前编辑器的特殊选项(通过调用 updateOptions或者启动时传入)
|
|
355
|
-
* 2. 来自 featureRegistry 的根据 当前uri 提供的选项
|
|
356
|
-
* 3. 来自偏好设置的选项
|
|
357
|
-
*/
|
|
358
|
-
private _calculateFinalOptions() {
|
|
359
|
-
const uriStr = this.currentUri ? this.currentUri.toString() : undefined;
|
|
360
|
-
const languageId = this.currentDocumentModel ? this.currentDocumentModel.languageId : undefined;
|
|
361
|
-
const options = getConvertedMonacoOptions(this.configurationService, uriStr, languageId, undefined);
|
|
362
|
-
const basicEditorOptions: Partial<monaco.editor.IEditorOptions> = {
|
|
363
|
-
readOnly: this.currentDocumentModel?.readonly || false,
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
let editorOptions = {
|
|
367
|
-
...basicEditorOptions,
|
|
368
|
-
...options.editorOptions,
|
|
369
|
-
...this._editorOptionsFromContribution,
|
|
370
|
-
...this._specialEditorOptions,
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
if (this.type !== EditorType.CODE) {
|
|
374
|
-
editorOptions = {
|
|
375
|
-
...editorOptions,
|
|
376
|
-
...options.diffOptions,
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
return {
|
|
381
|
-
editorOptions,
|
|
382
|
-
modelOptions: { ...options.modelOptions, ...this._specialModelOptions },
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
insertSnippet(template: string, ranges: IRange[], opts: IUndoStopOptions) {
|
|
387
|
-
insertSnippetWithMonacoEditor(this.monacoEditor, template, ranges, opts);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
applyDecoration(key: string, options: IDecorationApplyOptions[]) {
|
|
391
|
-
this.decorationApplier.applyDecoration(key, options);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
onSelectionsChanged(listener) {
|
|
395
|
-
return this.monacoEditor.onDidChangeCursorSelection((e) => {
|
|
396
|
-
if (!this._disableSelectionEmitter) {
|
|
397
|
-
listener({
|
|
398
|
-
selections: this.getSelections(),
|
|
399
|
-
source: e.source,
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
onVisibleRangesChanged(listener) {
|
|
406
|
-
const disposer = new Disposable();
|
|
407
|
-
const monacoEditor = this.monacoEditor;
|
|
408
|
-
disposer.addDispose(
|
|
409
|
-
monacoEditor.onDidScrollChange((e) => {
|
|
410
|
-
listener(this.monacoEditor.getVisibleRanges());
|
|
411
|
-
}),
|
|
412
|
-
);
|
|
413
|
-
disposer.addDispose(
|
|
414
|
-
monacoEditor.onDidLayoutChange((e) => {
|
|
415
|
-
listener(this.monacoEditor.getVisibleRanges());
|
|
416
|
-
}),
|
|
417
|
-
);
|
|
418
|
-
return disposer;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
setSelections(selections) {
|
|
422
|
-
return this.monacoEditor.setSelections(selections as any);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
setSelection(selection) {
|
|
426
|
-
return this.monacoEditor.setSelection(selection as any);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
public async save(): Promise<void> {
|
|
430
|
-
if (this.currentDocumentModel) {
|
|
431
|
-
await this.currentDocumentModel.save();
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
onConfigurationChanged(listener) {
|
|
436
|
-
const monacoEditor = this.monacoEditor;
|
|
437
|
-
return monacoEditor.onDidChangeConfiguration((e) => {
|
|
438
|
-
listener();
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
247
|
@Injectable({ multiple: true })
|
|
444
248
|
export class BrowserCodeEditor extends BaseMonacoEditorWrapper implements ICodeEditor {
|
|
445
249
|
@Autowired(EditorCollectionService)
|
|
@@ -568,9 +372,6 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
|
|
|
568
372
|
@Autowired(EditorCollectionService)
|
|
569
373
|
private collectionService: EditorCollectionServiceImpl;
|
|
570
374
|
|
|
571
|
-
@Autowired(AppConfig)
|
|
572
|
-
private appConfig: AppConfig;
|
|
573
|
-
|
|
574
375
|
private originalDocModelRef: IEditorDocumentModelRef | null;
|
|
575
376
|
|
|
576
377
|
private modifiedDocModelRef: IEditorDocumentModelRef | null;
|
|
@@ -837,7 +638,6 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
|
|
|
837
638
|
}
|
|
838
639
|
|
|
839
640
|
// utils
|
|
840
|
-
|
|
841
641
|
function bindPreventNavigation(div: HTMLElement) {
|
|
842
642
|
div.addEventListener('mousewheel', preventNavigation as any);
|
|
843
643
|
}
|
|
@@ -853,18 +653,3 @@ function preventNavigation(this: HTMLDivElement, e: WheelEvent) {
|
|
|
853
653
|
e.stopPropagation();
|
|
854
654
|
}
|
|
855
655
|
}
|
|
856
|
-
|
|
857
|
-
@Injectable({ multiple: true })
|
|
858
|
-
export class DiffEditorPart extends BaseMonacoEditorWrapper implements IEditor {
|
|
859
|
-
get currentDocumentModel() {
|
|
860
|
-
return this.getDocumentModel();
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
constructor(
|
|
864
|
-
monacoEditor: IMonacoCodeEditor,
|
|
865
|
-
private getDocumentModel: () => IEditorDocumentModel | null,
|
|
866
|
-
type: EditorType,
|
|
867
|
-
) {
|
|
868
|
-
super(monacoEditor, type);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
@@ -1246,6 +1246,7 @@ export class EditorContribution
|
|
|
1246
1246
|
title: string;
|
|
1247
1247
|
multiDiffSourceUri: UriComponents;
|
|
1248
1248
|
resources: { originalUri?: UriComponents; modifiedUri?: UriComponents }[];
|
|
1249
|
+
editorOptions?: IResourceOpenOptions;
|
|
1249
1250
|
}) => {
|
|
1250
1251
|
const sources: MultiDiffEditorItem[] = [];
|
|
1251
1252
|
for (const { originalUri, modifiedUri } of options.resources) {
|
|
@@ -1262,6 +1263,7 @@ export class EditorContribution
|
|
|
1262
1263
|
this.multiDiffResolver.registerSources(multiDiffSourceUri, sources);
|
|
1263
1264
|
await this.workbenchEditorService.open(multiDiffSourceUri, {
|
|
1264
1265
|
label: options.title,
|
|
1266
|
+
...options.editorOptions,
|
|
1265
1267
|
});
|
|
1266
1268
|
},
|
|
1267
1269
|
},
|