diff --git a/src/cssMode.ts b/src/cssMode.ts index 39aae4b8..6596b95c 100644 --- a/src/cssMode.ts +++ b/src/cssMode.ts @@ -10,26 +10,75 @@ import { LanguageServiceDefaultsImpl } from './monaco.contribution'; import * as languageFeatures from './languageFeatures'; import Uri = monaco.Uri; +import IDisposable = monaco.IDisposable; -export function setupMode(defaults: LanguageServiceDefaultsImpl): void { +export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { + + const disposables: IDisposable[] = []; + const providers: IDisposable[] = []; const client = new WorkerManager(defaults); + disposables.push(client); - const worker = (first: Uri, ...more: Uri[]): Promise => { - return client.getLanguageServiceWorker(...[first].concat(more)); + const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise => { + return client.getLanguageServiceWorker(...uris); }; - let languageId = defaults.languageId; - monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker)); - monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)); - monaco.languages.registerDocumentHighlightProvider(languageId, new languageFeatures.DocumentHighlightAdapter(worker)); - monaco.languages.registerDefinitionProvider(languageId, new languageFeatures.DefinitionAdapter(worker)); - monaco.languages.registerReferenceProvider(languageId, new languageFeatures.ReferenceAdapter(worker)); - monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker)); - monaco.languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker)); - monaco.languages.registerColorProvider(languageId, new languageFeatures.DocumentColorAdapter(worker)); - monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker)); - monaco.languages.registerSelectionRangeProvider(languageId, new languageFeatures.SelectionRangeAdapter(worker)); - new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults); + function registerProviders(): void { + const { languageId, modeConfiguration } = defaults; + + disposeAll(providers); + + if (modeConfiguration.completionItems) { + providers.push(monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker))); + } + if (modeConfiguration.hovers) { + providers.push(monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))); + } + if (modeConfiguration.documentHighlights) { + providers.push(monaco.languages.registerDocumentHighlightProvider(languageId, new languageFeatures.DocumentHighlightAdapter(worker))); + } + if (modeConfiguration.definitions) { + providers.push(monaco.languages.registerDefinitionProvider(languageId, new languageFeatures.DefinitionAdapter(worker))); + } + if (modeConfiguration.references) { + providers.push(monaco.languages.registerReferenceProvider(languageId, new languageFeatures.ReferenceAdapter(worker))); + } + if (modeConfiguration.documentSymbols) { + providers.push(monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker))); + } + if (modeConfiguration.rename) { + providers.push(monaco.languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker))); + } + if (modeConfiguration.colors) { + providers.push(monaco.languages.registerColorProvider(languageId, new languageFeatures.DocumentColorAdapter(worker))); + } + if (modeConfiguration.foldingRanges) { + providers.push(monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker))); + } + if (modeConfiguration.diagnostics) { + providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults)); + } + if (modeConfiguration.selectionRanges) { + providers.push(monaco.languages.registerSelectionRangeProvider(languageId, new languageFeatures.SelectionRangeAdapter(worker))); + } + } + + registerProviders(); + + + disposables.push(asDisposable(providers)); + + return asDisposable(disposables); +} + +function asDisposable(disposables: IDisposable[]): IDisposable { + return { dispose: () => disposeAll(disposables) }; +} + +function disposeAll(disposables: IDisposable[]) { + while (disposables.length) { + disposables.pop().dispose(); + } } diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index ee46e9f7..e15b5c04 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -15,11 +15,13 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.css.Languag private _onDidChange = new Emitter(); private _diagnosticsOptions: monaco.languages.css.DiagnosticsOptions; + private _modeConfiguration: monaco.languages.css.ModeConfiguration; private _languageId: string; - constructor(languageId: string, diagnosticsOptions: monaco.languages.css.DiagnosticsOptions) { + constructor(languageId: string, diagnosticsOptions: monaco.languages.css.DiagnosticsOptions, modeConfiguration: monaco.languages.css.ModeConfiguration) { this._languageId = languageId; this.setDiagnosticsOptions(diagnosticsOptions); + this.setModeConfiguration(modeConfiguration); } get onDidChange(): IEvent { @@ -30,6 +32,10 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.css.Languag return this._languageId; } + get modeConfiguration(): monaco.languages.css.ModeConfiguration { + return this._modeConfiguration; + } + get diagnosticsOptions(): monaco.languages.css.DiagnosticsOptions { return this._diagnosticsOptions; } @@ -38,9 +44,67 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.css.Languag this._diagnosticsOptions = options || Object.create(null); this._onDidChange.fire(this); } + + setModeConfiguration(modeConfiguration: monaco.languages.css.ModeConfiguration): void { + this._modeConfiguration = modeConfiguration || Object.create(null); + this._onDidChange.fire(this); + }; } -const diagnosticDefault: monaco.languages.css.DiagnosticsOptions = { +export interface ModeConfiguration { + /** + * Defines whether the built-in documentFormattingEdit provider is enabled. + */ + readonly documentFormattingEdits?: boolean; + + /** + * Defines whether the built-in documentRangeFormattingEdit provider is enabled. + */ + readonly documentRangeFormattingEdits?: boolean; + + /** + * Defines whether the built-in completionItemProvider is enabled. + */ + readonly completionItems?: boolean; + + /** + * Defines whether the built-in hoverProvider is enabled. + */ + readonly hovers?: boolean; + + /** + * Defines whether the built-in documentSymbolProvider is enabled. + */ + readonly documentSymbols?: boolean; + + /** + * Defines whether the built-in tokens provider is enabled. + */ + readonly tokens?: boolean; + + /** + * Defines whether the built-in color provider is enabled. + */ + readonly colors?: boolean; + + /** + * Defines whether the built-in foldingRange provider is enabled. + */ + readonly foldingRanges?: boolean; + + /** + * Defines whether the built-in diagnostic provider is enabled. + */ + readonly diagnostics?: boolean; + + /** + * Defines whether the built-in selection range provider is enabled. + */ + readonly selectionRanges?: boolean; + +} + +const diagnosticDefault: Required = { validate: true, lint: { compatibleVendorPrefixes: 'ignore', @@ -64,9 +128,23 @@ const diagnosticDefault: monaco.languages.css.DiagnosticsOptions = { } } -const cssDefaults = new LanguageServiceDefaultsImpl('css', diagnosticDefault); -const scssDefaults = new LanguageServiceDefaultsImpl('scss', diagnosticDefault); -const lessDefaults = new LanguageServiceDefaultsImpl('less', diagnosticDefault); +const modeConfigurationDefault: Required = { + completionItems: true, + hovers: true, + documentSymbols: true, + definitions: true, + references: true, + documentHighlights: true, + rename: true, + colors: true, + foldingRanges: true, + diagnostics: true, + selectionRanges: true +} + +const cssDefaults = new LanguageServiceDefaultsImpl('css', diagnosticDefault, modeConfigurationDefault); +const scssDefaults = new LanguageServiceDefaultsImpl('scss', diagnosticDefault, modeConfigurationDefault); +const lessDefaults = new LanguageServiceDefaultsImpl('less', diagnosticDefault, modeConfigurationDefault); // Export API diff --git a/src/monaco.d.ts b/src/monaco.d.ts index 4736227f..cfc4a3db 100644 --- a/src/monaco.d.ts +++ b/src/monaco.d.ts @@ -27,10 +27,70 @@ declare module monaco.languages.css { } } + export interface ModeConfiguration { + /** + * Defines whether the built-in completionItemProvider is enabled. + */ + readonly completionItems?: boolean; + + /** + * Defines whether the built-in hoverProvider is enabled. + */ + readonly hovers?: boolean; + + /** + * Defines whether the built-in documentSymbolProvider is enabled. + */ + readonly documentSymbols?: boolean; + + /** + * Defines whether the built-in definitions provider is enabled. + */ + readonly definitions?: boolean; + + /** + * Defines whether the built-in references provider is enabled. + */ + readonly references?: boolean; + + /** + * Defines whether the built-in references provider is enabled. + */ + readonly documentHighlights?: boolean; + + /** + * Defines whether the built-in rename provider is enabled. + */ + readonly rename?: boolean; + + /** + * Defines whether the built-in color provider is enabled. + */ + readonly colors?: boolean; + + /** + * Defines whether the built-in foldingRange provider is enabled. + */ + readonly foldingRanges?: boolean; + + /** + * Defines whether the built-in diagnostic provider is enabled. + */ + readonly diagnostics?: boolean; + + /** + * Defines whether the built-in selection range provider is enabled. + */ + readonly selectionRanges?: boolean; + + } + export interface LanguageServiceDefaults { readonly onDidChange: IEvent; readonly diagnosticsOptions: DiagnosticsOptions; + readonly modeConfiguration: ModeConfiguration; setDiagnosticsOptions(options: DiagnosticsOptions): void; + setModeConfiguration(modeConfiguration: ModeConfiguration): void; } export var cssDefaults: LanguageServiceDefaults;