standaloneLanguages.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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. import { Color } from '../../../base/common/color.js';
  6. import { Range } from '../../common/core/range.js';
  7. import { Token, TokenizationResult, TokenizationResult2 } from '../../common/core/token.js';
  8. import * as modes from '../../common/modes.js';
  9. import { LanguageConfigurationRegistry } from '../../common/modes/languageConfigurationRegistry.js';
  10. import { ModesRegistry } from '../../common/modes/modesRegistry.js';
  11. import * as standaloneEnums from '../../common/standalone/standaloneEnums.js';
  12. import { StaticServices } from './standaloneServices.js';
  13. import { compile } from '../common/monarch/monarchCompile.js';
  14. import { createTokenizationSupport } from '../common/monarch/monarchLexer.js';
  15. /**
  16. * Register information about a new language.
  17. */
  18. export function register(language) {
  19. ModesRegistry.registerLanguage(language);
  20. }
  21. /**
  22. * Get the information of all the registered languages.
  23. */
  24. export function getLanguages() {
  25. let result = [];
  26. result = result.concat(ModesRegistry.getLanguages());
  27. return result;
  28. }
  29. export function getEncodedLanguageId(languageId) {
  30. const modeService = StaticServices.modeService.get();
  31. return modeService.languageIdCodec.encodeLanguageId(languageId);
  32. }
  33. /**
  34. * An event emitted when a language is first time needed (e.g. a model has it set).
  35. * @event
  36. */
  37. export function onLanguage(languageId, callback) {
  38. let disposable = StaticServices.modeService.get().onDidEncounterLanguage((encounteredLanguageId) => {
  39. if (encounteredLanguageId === languageId) {
  40. // stop listening
  41. disposable.dispose();
  42. // invoke actual listener
  43. callback();
  44. }
  45. });
  46. return disposable;
  47. }
  48. /**
  49. * Set the editing configuration for a language.
  50. */
  51. export function setLanguageConfiguration(languageId, configuration) {
  52. const validLanguageId = StaticServices.modeService.get().validateLanguageId(languageId);
  53. if (!validLanguageId) {
  54. throw new Error(`Cannot set configuration for unknown language ${languageId}`);
  55. }
  56. return LanguageConfigurationRegistry.register(validLanguageId, configuration, 100);
  57. }
  58. /**
  59. * @internal
  60. */
  61. export class EncodedTokenizationSupport2Adapter {
  62. constructor(languageId, actual) {
  63. this._languageId = languageId;
  64. this._actual = actual;
  65. }
  66. getInitialState() {
  67. return this._actual.getInitialState();
  68. }
  69. tokenize(line, hasEOL, state, offsetDelta) {
  70. if (typeof this._actual.tokenize === 'function') {
  71. return TokenizationSupport2Adapter.adaptTokenize(this._languageId, this._actual, line, state, offsetDelta);
  72. }
  73. throw new Error('Not supported!');
  74. }
  75. tokenize2(line, hasEOL, state) {
  76. let result = this._actual.tokenizeEncoded(line, state);
  77. return new TokenizationResult2(result.tokens, result.endState);
  78. }
  79. }
  80. /**
  81. * @internal
  82. */
  83. export class TokenizationSupport2Adapter {
  84. constructor(_languageId, _actual, _modeService, _standaloneThemeService) {
  85. this._languageId = _languageId;
  86. this._actual = _actual;
  87. this._modeService = _modeService;
  88. this._standaloneThemeService = _standaloneThemeService;
  89. }
  90. getInitialState() {
  91. return this._actual.getInitialState();
  92. }
  93. static _toClassicTokens(tokens, language, offsetDelta) {
  94. let result = [];
  95. let previousStartIndex = 0;
  96. for (let i = 0, len = tokens.length; i < len; i++) {
  97. const t = tokens[i];
  98. let startIndex = t.startIndex;
  99. // Prevent issues stemming from a buggy external tokenizer.
  100. if (i === 0) {
  101. // Force first token to start at first index!
  102. startIndex = 0;
  103. }
  104. else if (startIndex < previousStartIndex) {
  105. // Force tokens to be after one another!
  106. startIndex = previousStartIndex;
  107. }
  108. result[i] = new Token(startIndex + offsetDelta, t.scopes, language);
  109. previousStartIndex = startIndex;
  110. }
  111. return result;
  112. }
  113. static adaptTokenize(language, actual, line, state, offsetDelta) {
  114. let actualResult = actual.tokenize(line, state);
  115. let tokens = TokenizationSupport2Adapter._toClassicTokens(actualResult.tokens, language, offsetDelta);
  116. let endState;
  117. // try to save an object if possible
  118. if (actualResult.endState.equals(state)) {
  119. endState = state;
  120. }
  121. else {
  122. endState = actualResult.endState;
  123. }
  124. return new TokenizationResult(tokens, endState);
  125. }
  126. tokenize(line, hasEOL, state, offsetDelta) {
  127. return TokenizationSupport2Adapter.adaptTokenize(this._languageId, this._actual, line, state, offsetDelta);
  128. }
  129. _toBinaryTokens(languageIdCodec, tokens, offsetDelta) {
  130. const languageId = languageIdCodec.encodeLanguageId(this._languageId);
  131. const tokenTheme = this._standaloneThemeService.getColorTheme().tokenTheme;
  132. let result = [], resultLen = 0;
  133. let previousStartIndex = 0;
  134. for (let i = 0, len = tokens.length; i < len; i++) {
  135. const t = tokens[i];
  136. const metadata = tokenTheme.match(languageId, t.scopes);
  137. if (resultLen > 0 && result[resultLen - 1] === metadata) {
  138. // same metadata
  139. continue;
  140. }
  141. let startIndex = t.startIndex;
  142. // Prevent issues stemming from a buggy external tokenizer.
  143. if (i === 0) {
  144. // Force first token to start at first index!
  145. startIndex = 0;
  146. }
  147. else if (startIndex < previousStartIndex) {
  148. // Force tokens to be after one another!
  149. startIndex = previousStartIndex;
  150. }
  151. result[resultLen++] = startIndex + offsetDelta;
  152. result[resultLen++] = metadata;
  153. previousStartIndex = startIndex;
  154. }
  155. let actualResult = new Uint32Array(resultLen);
  156. for (let i = 0; i < resultLen; i++) {
  157. actualResult[i] = result[i];
  158. }
  159. return actualResult;
  160. }
  161. tokenize2(line, hasEOL, state, offsetDelta) {
  162. let actualResult = this._actual.tokenize(line, state);
  163. let tokens = this._toBinaryTokens(this._modeService.languageIdCodec, actualResult.tokens, offsetDelta);
  164. let endState;
  165. // try to save an object if possible
  166. if (actualResult.endState.equals(state)) {
  167. endState = state;
  168. }
  169. else {
  170. endState = actualResult.endState;
  171. }
  172. return new TokenizationResult2(tokens, endState);
  173. }
  174. }
  175. function isEncodedTokensProvider(provider) {
  176. return 'tokenizeEncoded' in provider;
  177. }
  178. function isThenable(obj) {
  179. return obj && typeof obj.then === 'function';
  180. }
  181. /**
  182. * Change the color map that is used for token colors.
  183. * Supported formats (hex): #RRGGBB, $RRGGBBAA, #RGB, #RGBA
  184. */
  185. export function setColorMap(colorMap) {
  186. if (colorMap) {
  187. const result = [null];
  188. for (let i = 1, len = colorMap.length; i < len; i++) {
  189. result[i] = Color.fromHex(colorMap[i]);
  190. }
  191. StaticServices.standaloneThemeService.get().setColorMapOverride(result);
  192. }
  193. else {
  194. StaticServices.standaloneThemeService.get().setColorMapOverride(null);
  195. }
  196. }
  197. /**
  198. * Set the tokens provider for a language (manual implementation).
  199. */
  200. export function setTokensProvider(languageId, provider) {
  201. const validLanguageId = StaticServices.modeService.get().validateLanguageId(languageId);
  202. if (!validLanguageId) {
  203. throw new Error(`Cannot set tokens provider for unknown language ${languageId}`);
  204. }
  205. const create = (provider) => {
  206. if (isEncodedTokensProvider(provider)) {
  207. return new EncodedTokenizationSupport2Adapter(validLanguageId, provider);
  208. }
  209. else {
  210. return new TokenizationSupport2Adapter(validLanguageId, provider, StaticServices.modeService.get(), StaticServices.standaloneThemeService.get());
  211. }
  212. };
  213. if (isThenable(provider)) {
  214. return modes.TokenizationRegistry.registerPromise(languageId, provider.then(provider => create(provider)));
  215. }
  216. return modes.TokenizationRegistry.register(languageId, create(provider));
  217. }
  218. /**
  219. * Set the tokens provider for a language (monarch implementation).
  220. */
  221. export function setMonarchTokensProvider(languageId, languageDef) {
  222. const create = (languageDef) => {
  223. return createTokenizationSupport(StaticServices.modeService.get(), StaticServices.standaloneThemeService.get(), languageId, compile(languageId, languageDef));
  224. };
  225. if (isThenable(languageDef)) {
  226. return modes.TokenizationRegistry.registerPromise(languageId, languageDef.then(languageDef => create(languageDef)));
  227. }
  228. return modes.TokenizationRegistry.register(languageId, create(languageDef));
  229. }
  230. /**
  231. * Register a reference provider (used by e.g. reference search).
  232. */
  233. export function registerReferenceProvider(languageId, provider) {
  234. return modes.ReferenceProviderRegistry.register(languageId, provider);
  235. }
  236. /**
  237. * Register a rename provider (used by e.g. rename symbol).
  238. */
  239. export function registerRenameProvider(languageId, provider) {
  240. return modes.RenameProviderRegistry.register(languageId, provider);
  241. }
  242. /**
  243. * Register a signature help provider (used by e.g. parameter hints).
  244. */
  245. export function registerSignatureHelpProvider(languageId, provider) {
  246. return modes.SignatureHelpProviderRegistry.register(languageId, provider);
  247. }
  248. /**
  249. * Register a hover provider (used by e.g. editor hover).
  250. */
  251. export function registerHoverProvider(languageId, provider) {
  252. return modes.HoverProviderRegistry.register(languageId, {
  253. provideHover: (model, position, token) => {
  254. let word = model.getWordAtPosition(position);
  255. return Promise.resolve(provider.provideHover(model, position, token)).then((value) => {
  256. if (!value) {
  257. return undefined;
  258. }
  259. if (!value.range && word) {
  260. value.range = new Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
  261. }
  262. if (!value.range) {
  263. value.range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);
  264. }
  265. return value;
  266. });
  267. }
  268. });
  269. }
  270. /**
  271. * Register a document symbol provider (used by e.g. outline).
  272. */
  273. export function registerDocumentSymbolProvider(languageId, provider) {
  274. return modes.DocumentSymbolProviderRegistry.register(languageId, provider);
  275. }
  276. /**
  277. * Register a document highlight provider (used by e.g. highlight occurrences).
  278. */
  279. export function registerDocumentHighlightProvider(languageId, provider) {
  280. return modes.DocumentHighlightProviderRegistry.register(languageId, provider);
  281. }
  282. /**
  283. * Register an linked editing range provider.
  284. */
  285. export function registerLinkedEditingRangeProvider(languageId, provider) {
  286. return modes.LinkedEditingRangeProviderRegistry.register(languageId, provider);
  287. }
  288. /**
  289. * Register a definition provider (used by e.g. go to definition).
  290. */
  291. export function registerDefinitionProvider(languageId, provider) {
  292. return modes.DefinitionProviderRegistry.register(languageId, provider);
  293. }
  294. /**
  295. * Register a implementation provider (used by e.g. go to implementation).
  296. */
  297. export function registerImplementationProvider(languageId, provider) {
  298. return modes.ImplementationProviderRegistry.register(languageId, provider);
  299. }
  300. /**
  301. * Register a type definition provider (used by e.g. go to type definition).
  302. */
  303. export function registerTypeDefinitionProvider(languageId, provider) {
  304. return modes.TypeDefinitionProviderRegistry.register(languageId, provider);
  305. }
  306. /**
  307. * Register a code lens provider (used by e.g. inline code lenses).
  308. */
  309. export function registerCodeLensProvider(languageId, provider) {
  310. return modes.CodeLensProviderRegistry.register(languageId, provider);
  311. }
  312. /**
  313. * Register a code action provider (used by e.g. quick fix).
  314. */
  315. export function registerCodeActionProvider(languageId, provider, metadata) {
  316. return modes.CodeActionProviderRegistry.register(languageId, {
  317. providedCodeActionKinds: metadata === null || metadata === void 0 ? void 0 : metadata.providedCodeActionKinds,
  318. provideCodeActions: (model, range, context, token) => {
  319. let markers = StaticServices.markerService.get().read({ resource: model.uri }).filter(m => {
  320. return Range.areIntersectingOrTouching(m, range);
  321. });
  322. return provider.provideCodeActions(model, range, { markers, only: context.only }, token);
  323. },
  324. resolveCodeAction: provider.resolveCodeAction
  325. });
  326. }
  327. /**
  328. * Register a formatter that can handle only entire models.
  329. */
  330. export function registerDocumentFormattingEditProvider(languageId, provider) {
  331. return modes.DocumentFormattingEditProviderRegistry.register(languageId, provider);
  332. }
  333. /**
  334. * Register a formatter that can handle a range inside a model.
  335. */
  336. export function registerDocumentRangeFormattingEditProvider(languageId, provider) {
  337. return modes.DocumentRangeFormattingEditProviderRegistry.register(languageId, provider);
  338. }
  339. /**
  340. * Register a formatter than can do formatting as the user types.
  341. */
  342. export function registerOnTypeFormattingEditProvider(languageId, provider) {
  343. return modes.OnTypeFormattingEditProviderRegistry.register(languageId, provider);
  344. }
  345. /**
  346. * Register a link provider that can find links in text.
  347. */
  348. export function registerLinkProvider(languageId, provider) {
  349. return modes.LinkProviderRegistry.register(languageId, provider);
  350. }
  351. /**
  352. * Register a completion item provider (use by e.g. suggestions).
  353. */
  354. export function registerCompletionItemProvider(languageId, provider) {
  355. return modes.CompletionProviderRegistry.register(languageId, provider);
  356. }
  357. /**
  358. * Register a document color provider (used by Color Picker, Color Decorator).
  359. */
  360. export function registerColorProvider(languageId, provider) {
  361. return modes.ColorProviderRegistry.register(languageId, provider);
  362. }
  363. /**
  364. * Register a folding range provider
  365. */
  366. export function registerFoldingRangeProvider(languageId, provider) {
  367. return modes.FoldingRangeProviderRegistry.register(languageId, provider);
  368. }
  369. /**
  370. * Register a declaration provider
  371. */
  372. export function registerDeclarationProvider(languageId, provider) {
  373. return modes.DeclarationProviderRegistry.register(languageId, provider);
  374. }
  375. /**
  376. * Register a selection range provider
  377. */
  378. export function registerSelectionRangeProvider(languageId, provider) {
  379. return modes.SelectionRangeRegistry.register(languageId, provider);
  380. }
  381. /**
  382. * Register a document semantic tokens provider
  383. */
  384. export function registerDocumentSemanticTokensProvider(languageId, provider) {
  385. return modes.DocumentSemanticTokensProviderRegistry.register(languageId, provider);
  386. }
  387. /**
  388. * Register a document range semantic tokens provider
  389. */
  390. export function registerDocumentRangeSemanticTokensProvider(languageId, provider) {
  391. return modes.DocumentRangeSemanticTokensProviderRegistry.register(languageId, provider);
  392. }
  393. /**
  394. * Register an inline completions provider.
  395. */
  396. export function registerInlineCompletionsProvider(languageId, provider) {
  397. return modes.InlineCompletionsProviderRegistry.register(languageId, provider);
  398. }
  399. /**
  400. * Register an inlay hints provider.
  401. */
  402. export function registerInlayHintsProvider(languageId, provider) {
  403. return modes.InlayHintsProviderRegistry.register(languageId, provider);
  404. }
  405. /**
  406. * @internal
  407. */
  408. export function createMonacoLanguagesAPI() {
  409. return {
  410. register: register,
  411. getLanguages: getLanguages,
  412. onLanguage: onLanguage,
  413. getEncodedLanguageId: getEncodedLanguageId,
  414. // provider methods
  415. setLanguageConfiguration: setLanguageConfiguration,
  416. setColorMap: setColorMap,
  417. setTokensProvider: setTokensProvider,
  418. setMonarchTokensProvider: setMonarchTokensProvider,
  419. registerReferenceProvider: registerReferenceProvider,
  420. registerRenameProvider: registerRenameProvider,
  421. registerCompletionItemProvider: registerCompletionItemProvider,
  422. registerSignatureHelpProvider: registerSignatureHelpProvider,
  423. registerHoverProvider: registerHoverProvider,
  424. registerDocumentSymbolProvider: registerDocumentSymbolProvider,
  425. registerDocumentHighlightProvider: registerDocumentHighlightProvider,
  426. registerLinkedEditingRangeProvider: registerLinkedEditingRangeProvider,
  427. registerDefinitionProvider: registerDefinitionProvider,
  428. registerImplementationProvider: registerImplementationProvider,
  429. registerTypeDefinitionProvider: registerTypeDefinitionProvider,
  430. registerCodeLensProvider: registerCodeLensProvider,
  431. registerCodeActionProvider: registerCodeActionProvider,
  432. registerDocumentFormattingEditProvider: registerDocumentFormattingEditProvider,
  433. registerDocumentRangeFormattingEditProvider: registerDocumentRangeFormattingEditProvider,
  434. registerOnTypeFormattingEditProvider: registerOnTypeFormattingEditProvider,
  435. registerLinkProvider: registerLinkProvider,
  436. registerColorProvider: registerColorProvider,
  437. registerFoldingRangeProvider: registerFoldingRangeProvider,
  438. registerDeclarationProvider: registerDeclarationProvider,
  439. registerSelectionRangeProvider: registerSelectionRangeProvider,
  440. registerDocumentSemanticTokensProvider: registerDocumentSemanticTokensProvider,
  441. registerDocumentRangeSemanticTokensProvider: registerDocumentRangeSemanticTokensProvider,
  442. registerInlineCompletionsProvider: registerInlineCompletionsProvider,
  443. registerInlayHintsProvider: registerInlayHintsProvider,
  444. // enums
  445. DocumentHighlightKind: standaloneEnums.DocumentHighlightKind,
  446. CompletionItemKind: standaloneEnums.CompletionItemKind,
  447. CompletionItemTag: standaloneEnums.CompletionItemTag,
  448. CompletionItemInsertTextRule: standaloneEnums.CompletionItemInsertTextRule,
  449. SymbolKind: standaloneEnums.SymbolKind,
  450. SymbolTag: standaloneEnums.SymbolTag,
  451. IndentAction: standaloneEnums.IndentAction,
  452. CompletionTriggerKind: standaloneEnums.CompletionTriggerKind,
  453. SignatureHelpTriggerKind: standaloneEnums.SignatureHelpTriggerKind,
  454. InlayHintKind: standaloneEnums.InlayHintKind,
  455. InlineCompletionTriggerKind: standaloneEnums.InlineCompletionTriggerKind,
  456. // classes
  457. FoldingRangeKind: modes.FoldingRangeKind,
  458. };
  459. }