@theia/plugin-ext 1.43.0 → 1.44.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.
Files changed (116) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +9 -0
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js.map +1 -1
  4. package/lib/common/plugin-protocol.d.ts +9 -2
  5. package/lib/common/plugin-protocol.d.ts.map +1 -1
  6. package/lib/common/plugin-protocol.js.map +1 -1
  7. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +1 -0
  8. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
  9. package/lib/hosted/node/hosted-plugin-deployer-handler.js +6 -0
  10. package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
  11. package/lib/hosted/node/scanners/scanner-theia.d.ts +0 -3
  12. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  13. package/lib/hosted/node/scanners/scanner-theia.js +11 -94
  14. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  15. package/lib/main/browser/debug/plugin-debug-service.d.ts +3 -0
  16. package/lib/main/browser/debug/plugin-debug-service.d.ts.map +1 -1
  17. package/lib/main/browser/debug/plugin-debug-service.js +78 -1
  18. package/lib/main/browser/debug/plugin-debug-service.js.map +1 -1
  19. package/lib/main/browser/languages-main.d.ts.map +1 -1
  20. package/lib/main/browser/languages-main.js +1 -0
  21. package/lib/main/browser/languages-main.js.map +1 -1
  22. package/lib/main/browser/plugin-contribution-handler.d.ts +2 -0
  23. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  24. package/lib/main/browser/plugin-contribution-handler.js +10 -0
  25. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  26. package/lib/main/browser/plugin-icon-theme-service.d.ts +12 -1
  27. package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
  28. package/lib/main/browser/plugin-icon-theme-service.js +44 -8
  29. package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
  30. package/lib/main/browser/plugin-shared-style.d.ts +5 -1
  31. package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
  32. package/lib/main/browser/plugin-shared-style.js +32 -16
  33. package/lib/main/browser/plugin-shared-style.js.map +1 -1
  34. package/lib/main/browser/terminal-main.d.ts +1 -0
  35. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  36. package/lib/main/browser/terminal-main.js +5 -0
  37. package/lib/main/browser/terminal-main.js.map +1 -1
  38. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  39. package/lib/main/browser/text-editor-main.js +10 -0
  40. package/lib/main/browser/text-editor-main.js.map +1 -1
  41. package/lib/main/browser/webview/webview.d.ts +8 -1
  42. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  43. package/lib/main/browser/webview/webview.js +10 -0
  44. package/lib/main/browser/webview/webview.js.map +1 -1
  45. package/lib/main/node/plugin-deployer-contribution.d.ts +1 -1
  46. package/lib/main/node/plugin-deployer-contribution.d.ts.map +1 -1
  47. package/lib/main/node/plugin-deployer-contribution.js +1 -1
  48. package/lib/main/node/plugin-deployer-contribution.js.map +1 -1
  49. package/lib/main/node/plugin-deployer-impl.d.ts +1 -1
  50. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  51. package/lib/main/node/plugin-deployer-impl.js +1 -1
  52. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  53. package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
  54. package/lib/main/node/plugin-ext-backend-module.js +3 -0
  55. package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
  56. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts +13 -0
  57. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts.map +1 -0
  58. package/lib/main/node/plugin-mgmt-cli-contribution.js +71 -0
  59. package/lib/main/node/plugin-mgmt-cli-contribution.js.map +1 -0
  60. package/lib/plugin/env.d.ts +0 -3
  61. package/lib/plugin/env.d.ts.map +1 -1
  62. package/lib/plugin/env.js +0 -6
  63. package/lib/plugin/env.js.map +1 -1
  64. package/lib/plugin/languages-utils.d.ts +2 -1
  65. package/lib/plugin/languages-utils.d.ts.map +1 -1
  66. package/lib/plugin/languages-utils.js +14 -1
  67. package/lib/plugin/languages-utils.js.map +1 -1
  68. package/lib/plugin/languages.d.ts.map +1 -1
  69. package/lib/plugin/languages.js +2 -1
  70. package/lib/plugin/languages.js.map +1 -1
  71. package/lib/plugin/plugin-context.d.ts.map +1 -1
  72. package/lib/plugin/plugin-context.js +5 -1
  73. package/lib/plugin/plugin-context.js.map +1 -1
  74. package/lib/plugin/plugin-manager.js +1 -1
  75. package/lib/plugin/plugin-manager.js.map +1 -1
  76. package/lib/plugin/status-bar/status-bar-item.d.ts.map +1 -1
  77. package/lib/plugin/terminal-ext.d.ts +5 -0
  78. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  79. package/lib/plugin/terminal-ext.js +11 -0
  80. package/lib/plugin/terminal-ext.js.map +1 -1
  81. package/lib/plugin/text-editor.d.ts +6 -2
  82. package/lib/plugin/text-editor.d.ts.map +1 -1
  83. package/lib/plugin/text-editor.js +57 -2
  84. package/lib/plugin/text-editor.js.map +1 -1
  85. package/lib/plugin/types-impl.d.ts +22 -0
  86. package/lib/plugin/types-impl.d.ts.map +1 -1
  87. package/lib/plugin/types-impl.js +36 -4
  88. package/lib/plugin/types-impl.js.map +1 -1
  89. package/package.json +29 -29
  90. package/src/common/plugin-api-rpc.ts +10 -0
  91. package/src/common/plugin-protocol.ts +9 -2
  92. package/src/hosted/node/hosted-plugin-deployer-handler.ts +7 -0
  93. package/src/hosted/node/scanners/scanner-theia.ts +10 -101
  94. package/src/main/browser/debug/plugin-debug-service.ts +84 -2
  95. package/src/main/browser/languages-main.ts +1 -0
  96. package/src/main/browser/plugin-contribution-handler.ts +9 -0
  97. package/src/main/browser/plugin-icon-theme-service.ts +46 -12
  98. package/src/main/browser/plugin-shared-style.ts +36 -17
  99. package/src/main/browser/terminal-main.ts +7 -0
  100. package/src/main/browser/text-editor-main.ts +9 -0
  101. package/src/main/browser/webview/pre/host.js +1 -1
  102. package/src/main/browser/webview/pre/main.js +57 -32
  103. package/src/main/browser/webview/webview.ts +18 -1
  104. package/src/main/node/plugin-deployer-contribution.ts +2 -2
  105. package/src/main/node/plugin-deployer-impl.ts +2 -2
  106. package/src/main/node/plugin-ext-backend-module.ts +4 -0
  107. package/src/main/node/plugin-mgmt-cli-contribution.ts +64 -0
  108. package/src/plugin/env.ts +0 -8
  109. package/src/plugin/languages-utils.ts +13 -1
  110. package/src/plugin/languages.ts +3 -2
  111. package/src/plugin/plugin-context.ts +6 -1
  112. package/src/plugin/plugin-manager.ts +1 -1
  113. package/src/plugin/status-bar/status-bar-item.ts +1 -1
  114. package/src/plugin/terminal-ext.ts +15 -0
  115. package/src/plugin/text-editor.ts +64 -4
  116. package/src/plugin/types-impl.ts +32 -0
@@ -144,40 +144,65 @@
144
144
  * @param {*} [state]
145
145
  * @return {string}
146
146
  */
147
- function getVsCodeApiScript(state) {
147
+ function getDefaultScript(state) {
148
148
  return `
149
- const acquireVsCodeApi = (function() {
150
- const originalPostMessage = window.parent.postMessage.bind(window.parent);
151
- const targetOrigin = '*';
152
- let acquired = false;
149
+ const acquireVsCodeApi = (function() {
150
+ const originalPostMessage = window.parent.postMessage.bind(window.parent);
151
+ const originalConsole = {...console};
152
+ const targetOrigin = '*';
153
+ let acquired = false;
154
+
155
+ let state = ${state ? `JSON.parse(${JSON.stringify(state)})` : undefined};
156
+
157
+ const forwardConsoleLog = (level, msg, args) => {
158
+ let message, optionalParams;
159
+ try {
160
+ if (msg) {
161
+ message = JSON.stringify(msg) ?? null;
162
+ }
163
+ if (args) {
164
+ optionalParams = JSON.stringify(args) ?? null;
165
+ }
166
+ } catch (e) {
167
+ // Log non serializable objects inside of view
168
+ originalConsole[level](msg, args);
169
+ return;
170
+ }
171
+ originalPostMessage({ command: 'onconsole', data: { level, message, optionalParams } }, targetOrigin);
172
+ };
153
173
 
154
- let state = ${state ? `JSON.parse(${JSON.stringify(state)})` : undefined};
174
+ console.log = (message, args) => forwardConsoleLog('log', message, args);
175
+ console.info = (message, args) => forwardConsoleLog('info', message, args);
176
+ console.warn = (message, args) => forwardConsoleLog('warn', message, args);
177
+ console.error = (message, args) => forwardConsoleLog('error', message, args);
178
+ console.debug = (message, args) => forwardConsoleLog('debug', message, args);
179
+ console.trace = (message, args) => forwardConsoleLog('trace', message, args);
155
180
 
156
- return () => {
157
- if (acquired) {
158
- throw new Error('An instance of the VS Code API has already been acquired');
159
- }
160
- acquired = true;
161
- return Object.freeze({
162
- postMessage: function(msg) {
163
- return originalPostMessage({ command: 'onmessage', data: msg }, targetOrigin);
164
- },
165
- setState: function(newState) {
166
- state = newState;
167
- originalPostMessage({ command: 'do-update-state', data: JSON.stringify(newState) }, targetOrigin);
168
- return newState;
169
- },
170
- getState: function() {
171
- return state;
172
- }
173
- });
174
- };
175
- })();
176
- const acquireTheiaApi = acquireVsCodeApi;
177
- delete window.parent;
178
- delete window.top;
179
- delete window.frameElement;
180
- `;
181
+ return () => {
182
+ if (acquired) {
183
+ throw new Error('An instance of the VS Code API has already been acquired');
184
+ }
185
+ acquired = true;
186
+ return Object.freeze({
187
+ postMessage: function (msg) {
188
+ return originalPostMessage({ command: 'onmessage', data: msg }, targetOrigin);
189
+ },
190
+ setState: function (newState) {
191
+ state = newState;
192
+ originalPostMessage({ command: 'do-update-state', data: JSON.stringify(newState) }, targetOrigin);
193
+ return newState;
194
+ },
195
+ getState: function () {
196
+ return state;
197
+ }
198
+ });
199
+ };
200
+ })();
201
+ const acquireTheiaApi = acquireVsCodeApi;
202
+ delete window.parent;
203
+ delete window.top;
204
+ delete window.frameElement;
205
+ `;
181
206
  }
182
207
 
183
208
  /**
@@ -369,7 +394,7 @@
369
394
  // apply default script
370
395
  if (options.allowScripts) {
371
396
  const defaultScript = newDocument.createElement('script');
372
- defaultScript.textContent = getVsCodeApiScript(data.state);
397
+ defaultScript.textContent = getDefaultScript(data.state);
373
398
  newDocument.head.prepend(defaultScript);
374
399
  }
375
400
 
@@ -69,7 +69,8 @@ export const enum WebviewMessageChannels {
69
69
  webviewReady = 'webview-ready',
70
70
  didKeydown = 'did-keydown',
71
71
  didMouseDown = 'did-mousedown',
72
- didMouseUp = 'did-mouseup'
72
+ didMouseUp = 'did-mouseup',
73
+ onconsole = 'onconsole'
73
74
  }
74
75
 
75
76
  export interface WebviewContentOptions {
@@ -80,6 +81,12 @@ export interface WebviewContentOptions {
80
81
  readonly enableCommandUris?: boolean | readonly string[];
81
82
  }
82
83
 
84
+ export interface WebviewConsoleLog {
85
+ level: Extract<keyof typeof console, 'log' | 'info' | 'warn' | 'error' | 'trace' | 'debug'>;
86
+ message?: string;
87
+ optionalParams?: string;
88
+ }
89
+
83
90
  @injectable()
84
91
  export class WebviewWidgetIdentifier {
85
92
  id: string;
@@ -318,6 +325,7 @@ export class WebviewWidget extends BaseWidget implements StatefulWidget, Extract
318
325
  this.toHide.push(subscription);
319
326
 
320
327
  this.toHide.push(this.on(WebviewMessageChannels.onmessage, (data: any) => this.onMessageEmitter.fire(data)));
328
+ this.toHide.push(this.on(WebviewMessageChannels.onconsole, (data: WebviewConsoleLog) => this.forwardConsoleLog(data)));
321
329
  this.toHide.push(this.on(WebviewMessageChannels.didClickLink, (uri: string) => this.openLink(new URI(uri))));
322
330
  this.toHide.push(this.on(WebviewMessageChannels.doUpdateState, (state: any) => {
323
331
  this._state = state;
@@ -462,6 +470,15 @@ export class WebviewWidget extends BaseWidget implements StatefulWidget, Extract
462
470
  this.doUpdateContent();
463
471
  }
464
472
 
473
+ protected forwardConsoleLog(log: WebviewConsoleLog): void {
474
+ const message = `[webview: ${this.identifier.id}] ${log.message ? JSON.parse(log.message) : undefined}`;
475
+ if (log.optionalParams !== undefined) {
476
+ console[log.level](message, JSON.parse(log.optionalParams));
477
+ } else {
478
+ console[log.level](message);
479
+ }
480
+ }
481
+
465
482
  protected style(): void {
466
483
  const { styles, activeThemeType, activeThemeName } = this.themeDataProvider.getThemeData();
467
484
  this.doSend('styles', { styles, activeThemeType, activeThemeName });
@@ -28,7 +28,7 @@ export class PluginDeployerContribution implements BackendApplicationContributio
28
28
  @inject(PluginDeployer)
29
29
  protected pluginDeployer: PluginDeployer;
30
30
 
31
- initialize(): void {
32
- this.pluginDeployer.start();
31
+ initialize(): Promise<void> {
32
+ return this.pluginDeployer.start();
33
33
  }
34
34
  }
@@ -75,9 +75,9 @@ export class PluginDeployerImpl implements PluginDeployer {
75
75
  @inject(ContributionProvider) @named(PluginDeployerParticipant)
76
76
  protected readonly participants: ContributionProvider<PluginDeployerParticipant>;
77
77
 
78
- public start(): void {
78
+ public start(): Promise<void> {
79
79
  this.logger.debug('Starting the deployer with the list of resolvers', this.pluginResolvers);
80
- this.doStart();
80
+ return this.doStart();
81
81
  }
82
82
 
83
83
  public async initResolvers(): Promise<Array<void>> {
@@ -41,6 +41,7 @@ import { WebviewBackendSecurityWarnings } from './webview-backend-security-warni
41
41
  import { PluginUninstallationManager } from './plugin-uninstallation-manager';
42
42
  import { LocalizationServerImpl } from '@theia/core/lib/node/i18n/localization-server';
43
43
  import { PluginLocalizationServer } from './plugin-localization-server';
44
+ import { PluginMgmtCliContribution } from './plugin-mgmt-cli-contribution';
44
45
 
45
46
  export function bindMainBackend(bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind): void {
46
47
  bind(PluginApiContribution).toSelf().inSingletonScope();
@@ -85,6 +86,9 @@ export function bindMainBackend(bind: interfaces.Bind, unbind: interfaces.Unbind
85
86
  bind(PluginCliContribution).toSelf().inSingletonScope();
86
87
  bind(CliContribution).toService(PluginCliContribution);
87
88
 
89
+ bind(PluginMgmtCliContribution).toSelf().inSingletonScope();
90
+ bind(CliContribution).toService(PluginMgmtCliContribution);
91
+
88
92
  bind(WebviewBackendSecurityWarnings).toSelf().inSingletonScope();
89
93
  bind(BackendApplicationContribution).toService(WebviewBackendSecurityWarnings);
90
94
 
@@ -0,0 +1,64 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 STMicroelectronics and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { inject, injectable } from '@theia/core/shared/inversify';
18
+ import { Argv, Arguments } from '@theia/core/shared/yargs';
19
+ import { CliContribution } from '@theia/core/lib/node/cli';
20
+ import { HostedPluginDeployerHandler } from '../../hosted/node/hosted-plugin-deployer-handler';
21
+ import { PluginType } from '../../common';
22
+
23
+ @injectable()
24
+ export class PluginMgmtCliContribution implements CliContribution {
25
+
26
+ static LIST_PLUGINS = 'list-plugins';
27
+ static SHOW_VERSIONS = '--show-versions';
28
+ static SHOW_BUILTINS = '--show-builtins';
29
+
30
+ @inject(HostedPluginDeployerHandler)
31
+ protected deployerHandler: HostedPluginDeployerHandler;
32
+
33
+ configure(conf: Argv): void {
34
+ conf.command([PluginMgmtCliContribution.LIST_PLUGINS, 'list-extensions'],
35
+ 'List the installed plugins',
36
+ yargs => yargs.option(PluginMgmtCliContribution.SHOW_VERSIONS, {
37
+ description: 'List the versions of the installed plugins',
38
+ type: 'boolean',
39
+ default: false,
40
+ }).option(PluginMgmtCliContribution.SHOW_BUILTINS, {
41
+ description: 'List the built-in plugins',
42
+ type: 'boolean',
43
+ default: false,
44
+ }),
45
+
46
+ async yargs => {
47
+ const showVersions = yargs[PluginMgmtCliContribution.SHOW_VERSIONS];
48
+ const deployedIds = await this.deployerHandler.getDeployedBackendPlugins();
49
+ const pluginType = yargs[PluginMgmtCliContribution.SHOW_BUILTINS] ? PluginType.System : PluginType.User;
50
+ process.stdout.write('installed plugins:\n');
51
+ deployedIds.filter(plugin => plugin.type === pluginType).forEach(plugin => {
52
+ if (showVersions) {
53
+ process.stdout.write(`${plugin.metadata.model.id}@${plugin.metadata.model.version}\n`);
54
+ } else {
55
+ process.stdout.write(`${plugin.metadata.model.id}\n`);
56
+ }
57
+ });
58
+ }
59
+ );
60
+ }
61
+
62
+ setArguments(args: Arguments): void {
63
+ }
64
+ }
package/src/plugin/env.ts CHANGED
@@ -25,7 +25,6 @@ export abstract class EnvExtImpl {
25
25
  private queryParameters: QueryParameters;
26
26
  private lang: string;
27
27
  private applicationName: string;
28
- private defaultShell: string;
29
28
  private ui: theia.UIKind;
30
29
  private envMachineId: string;
31
30
  private envSessionId: string;
@@ -68,10 +67,6 @@ export abstract class EnvExtImpl {
68
67
  this.lang = lang;
69
68
  }
70
69
 
71
- setShell(shell: string): void {
72
- this.defaultShell = shell;
73
- }
74
-
75
70
  setUIKind(uiKind: theia.UIKind): void {
76
71
  this.ui = uiKind;
77
72
  }
@@ -112,9 +107,6 @@ export abstract class EnvExtImpl {
112
107
  get uriScheme(): string {
113
108
  return 'theia';
114
109
  }
115
- get shell(): string {
116
- return this.defaultShell;
117
- }
118
110
  get uiKind(): theia.UIKind {
119
111
  return this.ui;
120
112
  }
@@ -15,7 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import * as theia from '@theia/plugin';
18
- import { SerializedIndentationRule, SerializedOnEnterRule, SerializedRegExp } from '../common';
18
+ import { SerializedAutoClosingPair, SerializedIndentationRule, SerializedOnEnterRule, SerializedRegExp } from '../common';
19
+ import { SyntaxTokenType } from './types-impl';
19
20
 
20
21
  export function serializeEnterRules(rules?: theia.OnEnterRule[]): SerializedOnEnterRule[] | undefined {
21
22
  if (typeof rules === 'undefined' || rules === null) {
@@ -54,3 +55,14 @@ export function serializeIndentation(indentationRules?: theia.IndentationRule):
54
55
  unIndentedLinePattern: serializeRegExp(indentationRules.unIndentedLinePattern)
55
56
  };
56
57
  }
58
+
59
+ export function serializeAutoClosingPairs(pairs: theia.AutoClosingPair[] | undefined): SerializedAutoClosingPair[] | undefined {
60
+ if (!pairs) {
61
+ return undefined;
62
+ };
63
+ return pairs.map(pair => ({
64
+ open: pair.open,
65
+ close: pair.close,
66
+ notIn: pair.notIn ? pair.notIn.map(tokenType => SyntaxTokenType.toString(tokenType)) : undefined
67
+ }));
68
+ }
@@ -108,7 +108,7 @@ import { isReadonlyArray } from '../common/arrays';
108
108
  import { DisposableCollection, disposableTimeout, Disposable as TheiaDisposable } from '@theia/core/lib/common/disposable';
109
109
  import { Severity } from '@theia/core/lib/common/severity';
110
110
  import { LinkedEditingRangeAdapter } from './languages/linked-editing-range';
111
- import { serializeEnterRules, serializeIndentation, serializeRegExp } from './languages-utils';
111
+ import { serializeAutoClosingPairs, serializeEnterRules, serializeIndentation, serializeRegExp } from './languages-utils';
112
112
  import { InlayHintsAdapter } from './languages/inlay-hints';
113
113
  import { InlineCompletionAdapter, InlineCompletionAdapterBase } from './languages/inline-completion';
114
114
  import { DocumentDropEditAdapter } from './languages/document-drop-edit';
@@ -208,7 +208,8 @@ export class LanguagesExtImpl implements LanguagesExt {
208
208
  comments: configuration.comments,
209
209
  onEnterRules: serializeEnterRules(configuration.onEnterRules),
210
210
  wordPattern: serializeRegExp(configuration.wordPattern),
211
- indentationRules: serializeIndentation(configuration.indentationRules)
211
+ indentationRules: serializeIndentation(configuration.indentationRules),
212
+ autoClosingPairs: serializeAutoClosingPairs(configuration.autoClosingPairs)
212
213
  };
213
214
 
214
215
  this.proxy.$setLanguageConfiguration(callId, language, config);
@@ -57,6 +57,7 @@ import {
57
57
  StatusBarAlignment,
58
58
  RelativePattern,
59
59
  IndentAction,
60
+ SyntaxTokenType,
60
61
  CompletionItem,
61
62
  CompletionItemKind,
62
63
  CompletionList,
@@ -796,7 +797,10 @@ export function createAPIFactory(
796
797
  get machineId(): string { return envExt.machineId; },
797
798
  get sessionId(): string { return envExt.sessionId; },
798
799
  get uriScheme(): string { return envExt.uriScheme; },
799
- get shell(): string { return envExt.shell; },
800
+ get shell(): string { return terminalExt.defaultShell; },
801
+ get onDidChangeShell(): theia.Event<string> {
802
+ return terminalExt.onDidChangeShell;
803
+ },
800
804
  get uiKind(): theia.UIKind { return envExt.uiKind; },
801
805
  clipboard,
802
806
  getEnvVariable(envVarName: string): PromiseLike<string | undefined> {
@@ -1225,6 +1229,7 @@ export function createAPIFactory(
1225
1229
  ConfigurationTarget,
1226
1230
  RelativePattern,
1227
1231
  IndentAction,
1232
+ SyntaxTokenType,
1228
1233
  CompletionItem,
1229
1234
  CompletionItemKind,
1230
1235
  CompletionList,
@@ -206,7 +206,7 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
206
206
 
207
207
  this.envExt.setQueryParameters(params.env.queryParams);
208
208
  this.envExt.setLanguage(params.env.language);
209
- this.envExt.setShell(params.env.shell);
209
+ this.terminalService.$setShell(params.env.shell);
210
210
  this.envExt.setUIKind(params.env.uiKind);
211
211
  this.envExt.setApplicationName(params.env.appName);
212
212
  this.envExt.setAppHost(params.env.appHost);
@@ -40,7 +40,7 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
40
40
  private _accessibilityInformation: theia.AccessibilityInformation;
41
41
 
42
42
  private _isVisible: boolean;
43
- private _timeoutHandle: NodeJS.Timer | undefined;
43
+ private _timeoutHandle: NodeJS.Timeout | undefined;
44
44
 
45
45
  _proxy: StatusBarMessageRegistryMain;
46
46
 
@@ -71,6 +71,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
71
71
 
72
72
  protected environmentVariableCollections: MultiKeyMap<string, EnvironmentVariableCollectionImpl> = new MultiKeyMap(2);
73
73
 
74
+ private shell: string;
75
+ private readonly onDidChangeShellEmitter = new Emitter<string>();
76
+ readonly onDidChangeShell: theia.Event<string> = this.onDidChangeShellEmitter.event;
77
+
74
78
  constructor(rpc: RPCProtocol) {
75
79
  this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TERMINAL_MAIN);
76
80
  }
@@ -79,6 +83,17 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
79
83
  return [...this._terminals.values()];
80
84
  }
81
85
 
86
+ get defaultShell(): string {
87
+ return this.shell || '';
88
+ }
89
+
90
+ async $setShell(shell: string): Promise<void> {
91
+ if (this.shell !== shell) {
92
+ this.shell = shell;
93
+ this.onDidChangeShellEmitter.fire(shell);
94
+ }
95
+ }
96
+
82
97
  createTerminal(
83
98
  nameOrOptions: TerminalOptions | PseudoTerminalOptions | ExtensionTerminalOptions | (string | undefined),
84
99
  shellPath?: string, shellArgs?: string[] | string
@@ -277,7 +277,8 @@ export class TextEditorExt implements theia.TextEditor {
277
277
  }
278
278
 
279
279
  export class TextEditorOptionsExt implements theia.TextEditorOptions {
280
- private _tabSize?: number;
280
+ private _tabSize: number;
281
+ private _indentSize: number | 'tabSize';
281
282
  private _insertSpace: boolean;
282
283
  private _cursorStyle: TextEditorCursorStyle;
283
284
  private _lineNumbers: TextEditorLineNumbersStyle;
@@ -289,12 +290,13 @@ export class TextEditorOptionsExt implements theia.TextEditorOptions {
289
290
 
290
291
  accept(source: TextEditorConfiguration): void {
291
292
  this._tabSize = source.tabSize;
293
+ this._indentSize = source.indentSize;
292
294
  this._insertSpace = source.insertSpaces;
293
295
  this._cursorStyle = source.cursorStyle;
294
296
  this._lineNumbers = source.lineNumbers;
295
297
  }
296
298
 
297
- get tabSize(): number | string | undefined {
299
+ get tabSize(): number {
298
300
  return this._tabSize;
299
301
  }
300
302
 
@@ -305,10 +307,10 @@ export class TextEditorOptionsExt implements theia.TextEditorOptions {
305
307
  }
306
308
 
307
309
  if (typeof tabSize === 'number') {
308
- if (this.tabSize === tabSize) {
310
+ if (this._tabSize === tabSize) {
309
311
  return;
310
312
  }
311
- this.tabSize = tabSize;
313
+ this._tabSize = tabSize;
312
314
  }
313
315
  warnOnError(this.proxy.$trySetOptions(this.id, {
314
316
  tabSize
@@ -334,6 +336,51 @@ export class TextEditorOptionsExt implements theia.TextEditorOptions {
334
336
  return undefined;
335
337
  }
336
338
 
339
+ get indentSize(): number {
340
+ if (this._indentSize === 'tabSize') {
341
+ return this.tabSize;
342
+ }
343
+ return this._indentSize;
344
+ }
345
+
346
+ set indentSize(val: number | string | undefined) {
347
+ const indentSize = this.validateIndentSize(val);
348
+ if (!indentSize) {
349
+ return; // ignore invalid values
350
+ }
351
+
352
+ if (typeof indentSize === 'number') {
353
+ if (this._indentSize === indentSize) {
354
+ return;
355
+ }
356
+ this._indentSize = indentSize;
357
+ } else if (val === 'tabSize') {
358
+ this._indentSize = val;
359
+ }
360
+ warnOnError(this.proxy.$trySetOptions(this.id, {
361
+ indentSize
362
+ }));
363
+ }
364
+
365
+ private validateIndentSize(val: number | string | undefined): number | 'tabSize' | undefined {
366
+ if (val === 'tabSize') {
367
+ return 'tabSize';
368
+ }
369
+
370
+ if (typeof val === 'number') {
371
+ const r = Math.floor(val);
372
+ return r > 0 ? r : undefined;
373
+ }
374
+ if (typeof val === 'string') {
375
+ const r = parseInt(val, undefined);
376
+ if (isNaN(r)) {
377
+ return undefined;
378
+ }
379
+ return r > 0 ? r : undefined;
380
+ }
381
+ return undefined;
382
+ }
383
+
337
384
  get insertSpaces(): boolean | string {
338
385
  return this._insertSpace;
339
386
  }
@@ -395,6 +442,19 @@ export class TextEditorOptionsExt implements theia.TextEditorOptions {
395
442
  }
396
443
  }
397
444
 
445
+ if (typeof newOptions.indentSize !== 'undefined') {
446
+ const indentSize = this.validateIndentSize(newOptions.indentSize);
447
+ if (indentSize === 'tabSize') {
448
+ hasUpdate = true;
449
+ configurationUpdate.indentSize = indentSize;
450
+ } else if (typeof indentSize === 'number' && this._indentSize !== indentSize) {
451
+ // reflect the new indentSize value immediately
452
+ this._indentSize = indentSize;
453
+ hasUpdate = true;
454
+ configurationUpdate.indentSize = indentSize;
455
+ }
456
+ }
457
+
398
458
  if (typeof newOptions.insertSpaces !== 'undefined') {
399
459
  const insertSpaces = this.validateInsertSpaces(newOptions.insertSpaces);
400
460
  if (insertSpaces === 'auto') {
@@ -845,6 +845,37 @@ export enum IndentAction {
845
845
  Outdent = 3
846
846
  }
847
847
 
848
+ export namespace SyntaxTokenType {
849
+ export function toString(v: SyntaxTokenType | unknown): 'other' | 'comment' | 'string' | 'regex' {
850
+ switch (v) {
851
+ case SyntaxTokenType.Other: return 'other';
852
+ case SyntaxTokenType.Comment: return 'comment';
853
+ case SyntaxTokenType.String: return 'string';
854
+ case SyntaxTokenType.RegEx: return 'regex';
855
+ }
856
+ return 'other';
857
+ }
858
+ }
859
+
860
+ export enum SyntaxTokenType {
861
+ /**
862
+ * Everything except tokens that are part of comments, string literals and regular expressions.
863
+ */
864
+ Other = 0,
865
+ /**
866
+ * A comment.
867
+ */
868
+ Comment = 1,
869
+ /**
870
+ * A string literal.
871
+ */
872
+ String = 2,
873
+ /**
874
+ * A regular expression.
875
+ */
876
+ RegEx = 3
877
+ }
878
+
848
879
  @es5ClassCompat
849
880
  export class TextEdit {
850
881
 
@@ -1657,6 +1688,7 @@ export class CodeActionKind {
1657
1688
  public static readonly Source = CodeActionKind.Empty.append('source');
1658
1689
  public static readonly SourceOrganizeImports = CodeActionKind.Source.append('organizeImports');
1659
1690
  public static readonly SourceFixAll = CodeActionKind.Source.append('fixAll');
1691
+ public static readonly Notebook = CodeActionKind.Empty.append('notebook');
1660
1692
 
1661
1693
  constructor(
1662
1694
  public readonly value: string