_.contribution.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. 'use strict';
  6. // Allow for running under nodejs/requirejs in tests
  7. const _monaco: typeof monaco = (typeof monaco === 'undefined' ? (<any>self).monaco : monaco);
  8. interface ILang extends monaco.languages.ILanguageExtensionPoint {
  9. loader: () => Promise<ILangImpl>;
  10. }
  11. interface ILangImpl {
  12. conf: monaco.languages.LanguageConfiguration;
  13. language: monaco.languages.IMonarchLanguage;
  14. }
  15. const languageDefinitions: { [languageId: string]: ILang; } = {};
  16. const lazyLanguageLoaders: { [languageId: string]: LazyLanguageLoader; } = {};
  17. class LazyLanguageLoader {
  18. public static getOrCreate(languageId: string): LazyLanguageLoader {
  19. if (!lazyLanguageLoaders[languageId]) {
  20. lazyLanguageLoaders[languageId] = new LazyLanguageLoader(languageId);
  21. }
  22. return lazyLanguageLoaders[languageId];
  23. }
  24. private readonly _languageId: string;
  25. private _loadingTriggered: boolean;
  26. private _lazyLoadPromise: Promise<ILangImpl>;
  27. private _lazyLoadPromiseResolve!: (value: ILangImpl) => void;
  28. private _lazyLoadPromiseReject!: (err: any) => void;
  29. constructor(languageId: string) {
  30. this._languageId = languageId;
  31. this._loadingTriggered = false;
  32. this._lazyLoadPromise = new Promise((resolve, reject) => {
  33. this._lazyLoadPromiseResolve = resolve;
  34. this._lazyLoadPromiseReject = reject;
  35. });
  36. }
  37. public whenLoaded(): Promise<ILangImpl> {
  38. return this._lazyLoadPromise;
  39. }
  40. public load(): Promise<ILangImpl> {
  41. if (!this._loadingTriggered) {
  42. this._loadingTriggered = true;
  43. languageDefinitions[this._languageId].loader().then(mod => this._lazyLoadPromiseResolve(mod), err => this._lazyLoadPromiseReject(err));
  44. }
  45. return this._lazyLoadPromise;
  46. }
  47. }
  48. export function loadLanguage(languageId: string): Promise<ILangImpl> {
  49. return LazyLanguageLoader.getOrCreate(languageId).load();
  50. }
  51. export function registerLanguage(def: ILang): void {
  52. const languageId = def.id;
  53. languageDefinitions[languageId] = def;
  54. _monaco.languages.register(def);
  55. const lazyLanguageLoader = LazyLanguageLoader.getOrCreate(languageId);
  56. _monaco.languages.setMonarchTokensProvider(languageId, lazyLanguageLoader.whenLoaded().then(mod => mod.language));
  57. _monaco.languages.onLanguage(languageId, () => {
  58. lazyLanguageLoader.load().then(mod => {
  59. _monaco.languages.setLanguageConfiguration(languageId, mod.conf);
  60. });
  61. });
  62. }