@theia/editor 1.59.0-next.62 → 1.59.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/editor-frontend-module.d.ts.map +1 -1
- package/lib/browser/editor-frontend-module.js +1 -0
- package/lib/browser/editor-frontend-module.js.map +1 -1
- package/lib/browser/editor-generated-preference-schema.js +20 -20
- package/lib/browser/editor-generated-preference-schema.js.map +1 -1
- package/lib/browser/editor-linenumber-contribution.d.ts.map +1 -1
- package/lib/browser/editor-linenumber-contribution.js +1 -0
- package/lib/browser/editor-linenumber-contribution.js.map +1 -1
- package/lib/browser/editor-manager.d.ts +18 -2
- package/lib/browser/editor-manager.d.ts.map +1 -1
- package/lib/browser/editor-manager.js +65 -20
- package/lib/browser/editor-manager.js.map +1 -1
- package/lib/browser/editor-preferences.js +3 -3
- package/lib/browser/editor-preferences.js.map +1 -1
- package/package.json +5 -5
- package/src/browser/editor-frontend-module.ts +4 -2
- package/src/browser/editor-generated-preference-schema.ts +20 -20
- package/src/browser/editor-linenumber-contribution.ts +1 -0
- package/src/browser/editor-manager.ts +78 -23
- package/src/browser/editor-preferences.ts +3 -3
|
@@ -14,12 +14,11 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { injectable, postConstruct, inject } from '@theia/core/shared/inversify';
|
|
17
|
+
import { injectable, postConstruct, inject, named } from '@theia/core/shared/inversify';
|
|
18
18
|
import URI from '@theia/core/lib/common/uri';
|
|
19
|
-
import { RecursivePartial, Emitter, Event, MaybePromise, CommandService, nls } from '@theia/core/lib/common';
|
|
19
|
+
import { RecursivePartial, Emitter, Event, MaybePromise, CommandService, nls, ContributionProvider, Prioritizeable, Disposable } from '@theia/core/lib/common';
|
|
20
20
|
import {
|
|
21
|
-
WidgetOpenerOptions, NavigatableWidgetOpenHandler, NavigatableWidgetOptions, Widget, PreferenceService, CommonCommands, getDefaultHandler,
|
|
22
|
-
defaultHandlerPriority
|
|
21
|
+
WidgetOpenerOptions, NavigatableWidgetOpenHandler, NavigatableWidgetOptions, Widget, PreferenceService, CommonCommands, getDefaultHandler, defaultHandlerPriority
|
|
23
22
|
} from '@theia/core/lib/browser';
|
|
24
23
|
import { EditorWidget } from './editor-widget';
|
|
25
24
|
import { Range, Position, Location, TextEditor } from './editor';
|
|
@@ -33,7 +32,13 @@ export interface WidgetId {
|
|
|
33
32
|
export interface EditorOpenerOptions extends WidgetOpenerOptions {
|
|
34
33
|
selection?: RecursivePartial<Range>;
|
|
35
34
|
preview?: boolean;
|
|
36
|
-
counter?: number
|
|
35
|
+
counter?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const EditorSelectionResolver = Symbol('EditorSelectionResolver');
|
|
39
|
+
export interface EditorSelectionResolver {
|
|
40
|
+
priority?: number;
|
|
41
|
+
resolveSelection(widget: EditorWidget, options: EditorOpenerOptions, uri?: URI): Promise<RecursivePartial<Range> | undefined>;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
@injectable()
|
|
@@ -60,9 +65,19 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
60
65
|
@inject(CommandService) protected readonly commands: CommandService;
|
|
61
66
|
@inject(PreferenceService) protected readonly preferenceService: PreferenceService;
|
|
62
67
|
|
|
68
|
+
@inject(ContributionProvider) @named(EditorSelectionResolver)
|
|
69
|
+
protected readonly resolverContributions: ContributionProvider<EditorSelectionResolver>;
|
|
70
|
+
protected selectionResolvers: EditorSelectionResolver[] = [];
|
|
71
|
+
|
|
63
72
|
@postConstruct()
|
|
64
73
|
protected override init(): void {
|
|
65
74
|
super.init();
|
|
75
|
+
|
|
76
|
+
this.selectionResolvers = Prioritizeable.prioritizeAllSync(
|
|
77
|
+
this.resolverContributions.getContributions(),
|
|
78
|
+
resolver => resolver.priority ?? 0
|
|
79
|
+
).map(p => p.value);
|
|
80
|
+
|
|
66
81
|
this.shell.onDidChangeActiveWidget(() => this.updateActiveEditor());
|
|
67
82
|
this.shell.onDidChangeCurrentWidget(() => this.updateCurrentEditor());
|
|
68
83
|
this.shell.onDidDoubleClickMainArea(() =>
|
|
@@ -91,6 +106,26 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
91
106
|
this.updateCurrentEditor();
|
|
92
107
|
}
|
|
93
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Registers a dynamic selection resolver.
|
|
111
|
+
* The resolver is added to the sorted list of selection resolvers and can later be disposed to remove it.
|
|
112
|
+
*
|
|
113
|
+
* @param resolver The selection resolver to register.
|
|
114
|
+
* @returns A Disposable that unregisters the resolver when disposed.
|
|
115
|
+
*/
|
|
116
|
+
public registerSelectionResolver(resolver: EditorSelectionResolver): Disposable {
|
|
117
|
+
this.selectionResolvers.push(resolver);
|
|
118
|
+
this.selectionResolvers.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
119
|
+
return {
|
|
120
|
+
dispose: () => {
|
|
121
|
+
const index = this.selectionResolvers.indexOf(resolver);
|
|
122
|
+
if (index !== -1) {
|
|
123
|
+
this.selectionResolvers.splice(index, 1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
94
129
|
override getByUri(uri: URI, options?: EditorOpenerOptions): Promise<EditorWidget | undefined> {
|
|
95
130
|
return this.getWidget(uri, options);
|
|
96
131
|
}
|
|
@@ -101,22 +136,24 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
101
136
|
|
|
102
137
|
protected override tryGetPendingWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise<EditorWidget> | undefined {
|
|
103
138
|
const editorPromise = super.tryGetPendingWidget(uri, options);
|
|
104
|
-
if (editorPromise) {
|
|
105
|
-
|
|
106
|
-
if (!(editorPromise instanceof Widget)) {
|
|
107
|
-
editorPromise.then(editor => this.revealSelection(editor, options, uri));
|
|
108
|
-
} else {
|
|
109
|
-
this.revealSelection(editorPromise, options, uri);
|
|
110
|
-
}
|
|
139
|
+
if (!editorPromise) {
|
|
140
|
+
return editorPromise;
|
|
111
141
|
}
|
|
112
|
-
|
|
142
|
+
|
|
143
|
+
// Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955)
|
|
144
|
+
if (!(editorPromise instanceof Widget)) {
|
|
145
|
+
return editorPromise.then(editor => this.revealSelection(editor, options, uri)).then(() => editorPromise);
|
|
146
|
+
} else {
|
|
147
|
+
return this.revealSelection(editorPromise, options, uri).then(() => editorPromise);
|
|
148
|
+
}
|
|
149
|
+
|
|
113
150
|
}
|
|
114
151
|
|
|
115
152
|
protected override async getWidget(uri: URI, options?: EditorOpenerOptions): Promise<EditorWidget | undefined> {
|
|
116
153
|
const editor = await super.getWidget(uri, options);
|
|
117
154
|
if (editor) {
|
|
118
155
|
// Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955)
|
|
119
|
-
this.revealSelection(editor, options, uri);
|
|
156
|
+
await this.revealSelection(editor, options, uri);
|
|
120
157
|
}
|
|
121
158
|
return editor;
|
|
122
159
|
}
|
|
@@ -124,7 +161,7 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
124
161
|
protected override async getOrCreateWidget(uri: URI, options?: EditorOpenerOptions): Promise<EditorWidget> {
|
|
125
162
|
const editor = await super.getOrCreateWidget(uri, options);
|
|
126
163
|
// Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955)
|
|
127
|
-
this.revealSelection(editor, options, uri);
|
|
164
|
+
await this.revealSelection(editor, options, uri);
|
|
128
165
|
return editor;
|
|
129
166
|
}
|
|
130
167
|
|
|
@@ -240,13 +277,17 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
240
277
|
return this.open(uri, splitOptions);
|
|
241
278
|
}
|
|
242
279
|
|
|
243
|
-
protected revealSelection(widget: EditorWidget, input?: EditorOpenerOptions, uri?: URI): void {
|
|
280
|
+
protected async revealSelection(widget: EditorWidget, input?: EditorOpenerOptions, uri?: URI): Promise<void> {
|
|
244
281
|
let inputSelection = input?.selection;
|
|
282
|
+
if (!inputSelection) {
|
|
283
|
+
inputSelection = await this.resolveSelection(widget, input ?? {}, uri);
|
|
284
|
+
}
|
|
285
|
+
// this logic could be moved into a 'EditorSelectionResolver'
|
|
245
286
|
if (!inputSelection && uri) {
|
|
287
|
+
// support file:///some/file.js#73,84
|
|
288
|
+
// support file:///some/file.js#L73
|
|
246
289
|
const match = /^L?(\d+)(?:,(\d+))?/.exec(uri.fragment);
|
|
247
290
|
if (match) {
|
|
248
|
-
// support file:///some/file.js#73,84
|
|
249
|
-
// support file:///some/file.js#L73
|
|
250
291
|
inputSelection = {
|
|
251
292
|
start: {
|
|
252
293
|
line: parseInt(match[1]) - 1,
|
|
@@ -256,22 +297,36 @@ export class EditorManager extends NavigatableWidgetOpenHandler<EditorWidget> {
|
|
|
256
297
|
}
|
|
257
298
|
}
|
|
258
299
|
if (inputSelection) {
|
|
259
|
-
const editor = widget.editor;
|
|
260
300
|
const selection = this.getSelection(widget, inputSelection);
|
|
301
|
+
const editor = widget.editor;
|
|
261
302
|
if (Position.is(selection)) {
|
|
262
303
|
editor.cursor = selection;
|
|
263
304
|
editor.revealPosition(selection);
|
|
264
305
|
} else if (Range.is(selection)) {
|
|
265
306
|
editor.cursor = selection.end;
|
|
266
|
-
editor.selection = {
|
|
267
|
-
...selection,
|
|
268
|
-
direction: 'ltr'
|
|
269
|
-
};
|
|
307
|
+
editor.selection = { ...selection, direction: 'ltr' };
|
|
270
308
|
editor.revealRange(selection);
|
|
271
309
|
}
|
|
272
310
|
}
|
|
273
311
|
}
|
|
274
312
|
|
|
313
|
+
protected async resolveSelection(widget: EditorWidget, options: EditorOpenerOptions, uri?: URI): Promise<RecursivePartial<Range> | undefined> {
|
|
314
|
+
if (options.selection) {
|
|
315
|
+
return options.selection;
|
|
316
|
+
}
|
|
317
|
+
for (const resolver of this.selectionResolvers) {
|
|
318
|
+
try {
|
|
319
|
+
const selection = await resolver.resolveSelection(widget, options, uri);
|
|
320
|
+
if (selection) {
|
|
321
|
+
return selection;
|
|
322
|
+
}
|
|
323
|
+
} catch (error) {
|
|
324
|
+
console.error(error);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
|
|
275
330
|
protected getSelection(widget: EditorWidget, selection: RecursivePartial<Range>): Range | Position | undefined {
|
|
276
331
|
const { start, end } = selection;
|
|
277
332
|
if (Position.is(start)) {
|
|
@@ -40,7 +40,7 @@ const codeActionsContributionSchema: PreferenceSchema['properties'] = {
|
|
|
40
40
|
properties: {
|
|
41
41
|
'source.fixAll': {
|
|
42
42
|
type: 'boolean',
|
|
43
|
-
description: nls.localizeByDefault('Controls whether
|
|
43
|
+
description: nls.localizeByDefault('Controls whether \'{0}\' actions should be run on file save.', 'quickfix')
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
additionalProperties: {
|
|
@@ -53,7 +53,7 @@ const codeActionsContributionSchema: PreferenceSchema['properties'] = {
|
|
|
53
53
|
}
|
|
54
54
|
],
|
|
55
55
|
default: {},
|
|
56
|
-
markdownDescription: nls.localizeByDefault('Run Code Actions for the editor on save. Code Actions must be specified and the editor must not be shutting down. Example: `"source.organizeImports": "explicit" `'),
|
|
56
|
+
markdownDescription: nls.localizeByDefault('Run Code Actions for the editor on save. Code Actions must be specified and the editor must not be shutting down. When {0} is set to `afterDelay`, Code Actions will only be run when the file is saved explicitly. Example: `"source.organizeImports": "explicit" `'),
|
|
57
57
|
scope: 'language-overridable',
|
|
58
58
|
}
|
|
59
59
|
};
|
|
@@ -68,7 +68,7 @@ interface CodeActionsContributionProperties {
|
|
|
68
68
|
const fileContributionSchema: PreferenceSchema['properties'] = {
|
|
69
69
|
'editor.formatOnSave': {
|
|
70
70
|
'type': 'boolean',
|
|
71
|
-
'description': nls.localizeByDefault('Format a file on save. A formatter must be available
|
|
71
|
+
'description': nls.localizeByDefault('Format a file on save. A formatter must be available and the editor must not be shutting down. When {0} is set to `afterDelay`, the file will only be formatted when saved explicitly.'),
|
|
72
72
|
'scope': PreferenceScope.fromString('language-overridable'),
|
|
73
73
|
},
|
|
74
74
|
'editor.formatOnSaveMode': {
|