Skip to content

Commit f6db058

Browse files
committed
feat: Add 2 methods to get editors plugged on the configuration service
1 parent 76bdfc2 commit f6db058

5 files changed

Lines changed: 115 additions & 3 deletions

File tree

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
"./service-override/configuration": {
3636
"types": "./dist/configuration.d.ts",
3737
"default": "./dist/configuration.js"
38+
},
39+
"./monaco": {
40+
"types": "./dist/monaco.d.ts",
41+
"default": "./dist/monaco.js"
3842
}
3943
},
4044
"typesVersions": {
@@ -50,6 +54,9 @@
5054
],
5155
"service-override/configuration": [
5256
"./dist/configuration.d.ts"
57+
],
58+
"monaco": [
59+
"./dist/monaco.d.ts"
5360
]
5461
}
5562
},

rollup/rollup.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ export default (args: Record<string, string>): rollup.RollupOptions => {
8585
services: './src/services.ts',
8686
messages: './src/service-override/messages.ts',
8787
modelEditor: './src/service-override/modelEditor.ts',
88-
configuration: './src/service-override/configuration.ts'
88+
configuration: './src/service-override/configuration.ts',
89+
monaco: './src/monaco'
8990
},
9091
plugins: [
9192
{

rollup/rollup.types.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default rollup.defineConfig([
1616
'./dist/types/src/services.d.ts',
1717
'./dist/types/src/service-override/messages.d.ts',
1818
'./dist/types/src/service-override/modelEditor.d.ts',
19-
'./dist/types/src/service-override/configuration.d.ts'
19+
'./dist/types/src/service-override/configuration.d.ts',
20+
'./dist/types/src/monaco.d.ts'
2021
].map((input): rollup.RollupOptions => ({
2122
input,
2223
output: {

src/monaco.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices'
2+
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'
3+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'
4+
import { IStandaloneEditorConstructionOptions, StandaloneDiffEditor, StandaloneEditor } from 'vs/editor/standalone/browser/standaloneCodeEditor'
5+
import { IEditorOptions } from 'vs/editor/common/config/editorOptions'
6+
import { IEditorConfiguration } from 'vs/workbench/browser/parts/editor/textEditor'
7+
import { isObject } from 'vs/base/common/types'
8+
import { deepClone, distinct } from 'vs/base/common/objects'
9+
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'
10+
import type { create as createEditor, createDiffEditor } from 'vs/editor/standalone/browser/standaloneEditor'
11+
import { createInjectedClass } from './tools/injection'
12+
13+
function computeConfiguration (configuration: IEditorConfiguration, isDiffEditor: boolean, overrides?: Readonly<IEditorOptions>): IEditorOptions {
14+
const editorConfiguration: IEditorOptions = isObject(configuration.editor) ? deepClone(configuration.editor) : Object.create(null)
15+
if (isDiffEditor && isObject(configuration.diffEditor)) {
16+
Object.assign(editorConfiguration, configuration.diffEditor)
17+
}
18+
if (isObject(configuration.diffEditor)) {
19+
Object.assign(editorConfiguration, overrides)
20+
}
21+
return editorConfiguration
22+
}
23+
24+
/**
25+
* A StandaloneEditor which is plugged on the `textResourceConfigurationService` for its options
26+
* So instead of just taking the options given by the user via the `updateOptions` method,
27+
* it fallbacks on the current configurationService configuration
28+
*/
29+
class ConfiguredStandaloneEditor extends createInjectedClass(StandaloneEditor) {
30+
// use createInjectedClass because StandaloneEditor has a lot of injected services and it would be a pain to inject them all here to be able to forward them
31+
// Also, the injected services may vary so relying on the annotations is more robust (and useful for @codingame/monaco-editor which removes a service from the list)
32+
33+
private optionsOverrides?: Readonly<IEditorOptions>
34+
private lastAppliedEditorOptions?: IEditorOptions
35+
36+
constructor (
37+
domElement: HTMLElement,
38+
private isDiffEditor: boolean,
39+
_options: Readonly<IStandaloneEditorConstructionOptions> | undefined,
40+
@IInstantiationService instantiationService: IInstantiationService,
41+
@ITextResourceConfigurationService private textResourceConfigurationService: ITextResourceConfigurationService
42+
) {
43+
const computedOptions = computeConfiguration(textResourceConfigurationService.getValue<IEditorConfiguration>(_options?.model?.uri), isDiffEditor, _options)
44+
super(instantiationService, domElement, computedOptions)
45+
this.lastAppliedEditorOptions = computedOptions
46+
47+
this.optionsOverrides = _options
48+
this._register(textResourceConfigurationService.onDidChangeConfiguration(() => this.updateEditorConfiguration()))
49+
this._register(this.onDidChangeModelLanguage(() => this.updateEditorConfiguration()))
50+
this._register(this.onDidChangeModel(() => this.updateEditorConfiguration()))
51+
}
52+
53+
/**
54+
* This method is widely inspired from vs/workbench/browser/parts/editor/textEditor
55+
*/
56+
private updateEditorConfiguration (): void {
57+
const resource = this.getModel()?.uri
58+
if (resource == null) {
59+
return
60+
}
61+
const configuration = this.textResourceConfigurationService.getValue<IEditorConfiguration | undefined>(resource)
62+
if (configuration == null) {
63+
return
64+
}
65+
66+
const editorConfiguration = computeConfiguration(configuration, this.isDiffEditor, this.optionsOverrides)
67+
68+
// Try to figure out the actual editor options that changed from the last time we updated the editor.
69+
// We do this so that we are not overwriting some dynamic editor settings (e.g. word wrap) that might
70+
// have been applied to the editor directly.
71+
let editorSettingsToApply = editorConfiguration
72+
if (this.lastAppliedEditorOptions != null) {
73+
editorSettingsToApply = distinct(this.lastAppliedEditorOptions, editorSettingsToApply)
74+
}
75+
76+
if (Object.keys(editorSettingsToApply).length > 0) {
77+
this.lastAppliedEditorOptions = editorConfiguration
78+
79+
super.updateOptions(editorSettingsToApply)
80+
}
81+
}
82+
83+
override updateOptions (newOptions: Readonly<IEditorOptions>): void {
84+
this.optionsOverrides = newOptions
85+
this.updateEditorConfiguration()
86+
}
87+
}
88+
89+
class ConfiguredStandaloneDiffEditor extends StandaloneDiffEditor {
90+
protected override _createInnerEditor (instantiationService: IInstantiationService, container: HTMLElement, options: Readonly<IEditorOptions>): CodeEditorWidget {
91+
return instantiationService.createInstance(ConfiguredStandaloneEditor, container, true, options)
92+
}
93+
}
94+
95+
export const createConfiguredEditor: typeof createEditor = (domElement, options, override) => {
96+
const instantiationService = StandaloneServices.initialize(override ?? {})
97+
return instantiationService.createInstance(ConfiguredStandaloneEditor, domElement, false, options)
98+
}
99+
100+
export const createConfiguredDiffEditor: typeof createDiffEditor = (domElement, options, override) => {
101+
const instantiationService = StandaloneServices.initialize(override ?? {})
102+
return instantiationService.createInstance(ConfiguredStandaloneDiffEditor, domElement, options)
103+
}

tsconfig.types.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@
5252
"emitDeclarationOnly": true,
5353
"skipLibCheck": true
5454
},
55-
"include": ["src/services.ts", "src/types.d.ts", "src/service-override/messages.ts", "src/service-override/modelEditor.ts", "src/service-override/configuration.ts"]
55+
"include": ["src/services.ts", "src/types.d.ts", "src/service-override/messages.ts", "src/service-override/modelEditor.ts", "src/service-override/configuration.ts", "src/monaco.ts"]
5656
}

0 commit comments

Comments
 (0)