@theia/plugin-ext 1.66.0-next.0 → 1.66.0-next.12

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.
@@ -37,6 +37,7 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
37
37
  private _name: string | undefined;
38
38
  private _text: string;
39
39
  private _tooltip: string | theia.MarkdownString | undefined;
40
+ private _tooltip2: string | theia.MarkdownString | undefined | ((token: theia.CancellationToken) => theia.ProviderResult<string | theia.MarkdownString>);
40
41
  private _color: string | ThemeColor | undefined;
41
42
  private _backgroundColor: ThemeColor | undefined;
42
43
  private _command: string | theia.Command;
@@ -47,12 +48,13 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
47
48
 
48
49
  _proxy: StatusBarMessageRegistryMain;
49
50
 
50
- constructor(_proxy: StatusBarMessageRegistryMain,
51
+ constructor(proxy: StatusBarMessageRegistryMain,
51
52
  private readonly commandRegistry: CommandRegistryImpl,
52
53
  alignment: StatusBarAlignment = StatusBarAlignment.Left,
53
54
  priority: number = 0,
54
- id = StatusBarItemImpl.nextId()) {
55
- this._proxy = _proxy;
55
+ id = StatusBarItemImpl.nextId(),
56
+ private onDispose?: () => void) {
57
+ this._proxy = proxy;
56
58
  this._alignment = alignment;
57
59
  this._priority = priority;
58
60
  this._id = id;
@@ -63,7 +65,7 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
63
65
  }
64
66
 
65
67
  public get alignment(): theia.StatusBarAlignment {
66
- return <theia.StatusBarAlignment>this._alignment;
68
+ return this._alignment;
67
69
  }
68
70
 
69
71
  public get priority(): number {
@@ -82,6 +84,17 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
82
84
  return this._tooltip;
83
85
  }
84
86
 
87
+ public get tooltip2(): string | theia.MarkdownString | undefined | ((token: theia.CancellationToken) => theia.ProviderResult<string | theia.MarkdownString>) {
88
+ if (typeof this._tooltip2 === 'function') {
89
+ const getTooltip = this._tooltip2.bind(this);
90
+ return (token: theia.CancellationToken) => Promise.resolve(getTooltip(token)).then(res => {
91
+ this.processTooltip(res);
92
+ return res;
93
+ });
94
+ }
95
+ return this._tooltip2;
96
+ }
97
+
85
98
  public get color(): string | ThemeColor | undefined {
86
99
  return this._color;
87
100
  }
@@ -108,57 +121,14 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
108
121
  this.update();
109
122
  }
110
123
 
111
- public set tooltip(tooltip: string | theia.MarkdownString | undefined) {
112
- if (tooltip && MarkdownString.isMarkdownString(tooltip)) {
113
- const markdownTooltip = tooltip;
114
- const content = markdownTooltip.value;
115
- // Find all command links in the markdown content
116
- const regex = /\[([^\]]+)\]\(command:([^?\s\)]+)(?:\?([^\s\)]+))?([^\)]*)\)/g;
117
- let match;
118
- let updatedContent = content;
119
-
120
- while ((match = regex.exec(content)) !== null) {
121
- const linkText = match[1];
122
- const commandId = match[2];
123
- const argsEncoded = match[3]; // This captures the encoded arguments
124
- const tooltipPart = match[4] || ''; // This captures any tooltip or additional content after the command and args
125
-
126
- let args: unknown[] = [];
127
- if (argsEncoded) {
128
- try {
129
- const decoded = decodeURIComponent(argsEncoded);
130
- args = JSON.parse(decoded);
131
- } catch (e) {
132
- console.error('Failed to parse command arguments:', e);
133
- }
134
- }
135
-
136
- const safeCommand = this.commandRegistry.converter.toSafeCommand(
137
- {
138
- command: commandId,
139
- title: linkText,
140
- arguments: Array.isArray(args) ? args : [args]
141
- },
142
- new DisposableCollection()
143
- );
144
-
145
- if (safeCommand?.id) {
146
- let newArgsPart = '';
147
- if (safeCommand.arguments && safeCommand.arguments.length > 0) {
148
- newArgsPart = `?${encodeURIComponent(JSON.stringify(safeCommand.arguments))}`;
149
- }
150
-
151
- const argsPart = argsEncoded ? `?${argsEncoded}` : '';
152
- const originalLink = `[${linkText}](command:${commandId}${argsPart}${tooltipPart})`;
153
- const safeLink = `[${linkText}](command:${safeCommand.id}${newArgsPart}${tooltipPart})`;
154
- updatedContent = updatedContent.replace(originalLink, safeLink);
155
- }
156
- }
124
+ public set tooltip2(tooltip: string | theia.MarkdownString | ((token: theia.CancellationToken) => theia.ProviderResult<string | theia.MarkdownString>) | undefined) {
125
+ this.processTooltip(tooltip);
126
+ this._tooltip2 = tooltip;
127
+ this.update();
128
+ }
157
129
 
158
- if (updatedContent !== content) {
159
- markdownTooltip.value = updatedContent;
160
- }
161
- }
130
+ public set tooltip(tooltip: string | theia.MarkdownString | undefined) {
131
+ this.processTooltip(tooltip);
162
132
  this._tooltip = tooltip;
163
133
  this.update();
164
134
  }
@@ -200,6 +170,59 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
200
170
  this._isVisible = false;
201
171
  }
202
172
 
173
+ private processTooltip(tooltip: string | theia.MarkdownString | ((token: theia.CancellationToken) => theia.ProviderResult<string | theia.MarkdownString>) | undefined): void {
174
+ if (!MarkdownString.isMarkdownString(tooltip)) {
175
+ return;
176
+ }
177
+ const content = tooltip.value;
178
+ // Find all command links in the markdown content
179
+ const regex = /\[([^\]]+)\]\(command:([^?\s\)]+)(?:\?([^\s\)]+))?([^\)]*)\)/g;
180
+ let match;
181
+ let updatedContent = content;
182
+
183
+ while ((match = regex.exec(content)) !== null) {
184
+ const linkText = match[1];
185
+ const commandId = match[2];
186
+ const argsEncoded = match[3]; // This captures the encoded arguments
187
+ const tooltipPart = match[4] || ''; // This captures any tooltip or additional content after the command and args
188
+
189
+ let args: unknown[] = [];
190
+ if (argsEncoded) {
191
+ try {
192
+ const decoded = decodeURIComponent(argsEncoded);
193
+ args = JSON.parse(decoded);
194
+ } catch (e) {
195
+ console.error('Failed to parse command arguments:', e);
196
+ }
197
+ }
198
+
199
+ const safeCommand = this.commandRegistry.converter.toSafeCommand(
200
+ {
201
+ command: commandId,
202
+ title: linkText,
203
+ arguments: Array.isArray(args) ? args : [args]
204
+ },
205
+ new DisposableCollection()
206
+ );
207
+
208
+ if (safeCommand?.id) {
209
+ let newArgsPart = '';
210
+ if (safeCommand.arguments && safeCommand.arguments.length > 0) {
211
+ newArgsPart = `?${encodeURIComponent(JSON.stringify(safeCommand.arguments))}`;
212
+ }
213
+
214
+ const argsPart = argsEncoded ? `?${argsEncoded}` : '';
215
+ const originalLink = `[${linkText}](command:${commandId}${argsPart}${tooltipPart})`;
216
+ const safeLink = `[${linkText}](command:${safeCommand.id}${newArgsPart}${tooltipPart})`;
217
+ updatedContent = updatedContent.replace(originalLink, safeLink);
218
+ }
219
+ }
220
+
221
+ if (updatedContent !== content) {
222
+ tooltip.value = updatedContent;
223
+ }
224
+ }
225
+
203
226
  private update(): void {
204
227
  if (!this._isVisible) {
205
228
  return;
@@ -220,6 +243,8 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
220
243
  color = StatusBarItemImpl.BACKGROUND_COLORS.get(this.backgroundColor.id);
221
244
  }
222
245
 
246
+ const tooltip = typeof this._tooltip2 === 'function' ? true : this._tooltip2 ?? this.tooltip;
247
+
223
248
  // Set to status bar
224
249
  this._proxy.$setMessage(
225
250
  this.id,
@@ -229,7 +254,7 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
229
254
  this.alignment,
230
255
  typeof color === 'string' ? color : color?.id,
231
256
  this.backgroundColor?.id,
232
- this.tooltip,
257
+ tooltip,
233
258
  commandId,
234
259
  this.accessibilityInformation,
235
260
  args);
@@ -237,6 +262,7 @@ export class StatusBarItemImpl implements theia.StatusBarItem {
237
262
  }
238
263
 
239
264
  public dispose(): void {
265
+ this.onDispose?.();
240
266
  this.hide();
241
267
  }
242
268
 
@@ -14,20 +14,23 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
  import { Disposable, StatusBarAlignment } from './types-impl';
17
- import { StatusBarItem } from '@theia/plugin';
17
+ import { CancellationToken, ProviderResult, StatusBarItem } from '@theia/plugin';
18
18
  import {
19
- PLUGIN_RPC_CONTEXT as Ext, StatusBarMessageRegistryMain
19
+ PLUGIN_RPC_CONTEXT as Ext, StatusBarMessageRegistryMain,
20
+ StatusBarMessageRegistryExt
20
21
  } from '../common/plugin-api-rpc';
21
22
  import { RPCProtocol } from '../common/rpc-protocol';
22
23
  import { StatusBarItemImpl } from './status-bar/status-bar-item';
23
24
  import { CommandRegistryImpl } from './command-registry';
25
+ import { MarkdownString } from '../common/plugin-api-rpc-model';
24
26
 
25
27
  /*---------------------------------------------------------------------------------------------
26
28
  * Copyright (c) Microsoft Corporation. All rights reserved.
27
29
  * Licensed under the MIT License. See License.txt in the project root for license information.
28
30
  *--------------------------------------------------------------------------------------------*/
29
31
 
30
- export class StatusBarMessageRegistryExt {
32
+ export class StatusBarMessageRegistryExtImpl implements StatusBarMessageRegistryExt {
33
+ private readonly items = new Map<string, StatusBarItemImpl>();
31
34
 
32
35
  proxy: StatusBarMessageRegistryMain;
33
36
 
@@ -38,6 +41,15 @@ export class StatusBarMessageRegistryExt {
38
41
  this.statusMessage = new StatusBarMessage(this);
39
42
  }
40
43
 
44
+ $getMessage(id: string, cancellation: CancellationToken): ProviderResult<string | MarkdownString> {
45
+ const item = this.items.get(id);
46
+ if (!item) { return undefined; }
47
+ if (typeof item.tooltip2 === 'function') {
48
+ return item.tooltip2(cancellation);
49
+ }
50
+ return item.tooltip2 ?? item.tooltip;
51
+ }
52
+
41
53
  // copied from https://github.com/Microsoft/vscode/blob/6c8f02b41db9ae5c4d15df767d47755e5c73b9d5/src/vs/workbench/api/node/extHostStatusBar.ts#L174
42
54
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
55
  setStatusBarMessage(text: string, timeoutOrThenable?: number | PromiseLike<any>): Disposable {
@@ -59,7 +71,9 @@ export class StatusBarMessageRegistryExt {
59
71
  }
60
72
 
61
73
  createStatusBarItem(alignment?: StatusBarAlignment, priority?: number, id?: string): StatusBarItem {
62
- return new StatusBarItemImpl(this.proxy, this.commandRegistry, alignment, priority, id);
74
+ const item: StatusBarItemImpl = new StatusBarItemImpl(this.proxy, this.commandRegistry, alignment, priority, id, () => this.items.delete(item.id));
75
+ this.items.set(item.id, item);
76
+ return item;
63
77
  }
64
78
 
65
79
  }
@@ -70,7 +84,7 @@ class StatusBarMessage {
70
84
  private _item: StatusBarItem;
71
85
  private _messages: { message: string }[] = [];
72
86
 
73
- constructor(statusBar: StatusBarMessageRegistryExt) {
87
+ constructor(statusBar: StatusBarMessageRegistryExtImpl) {
74
88
  this._item = statusBar.createStatusBarItem(StatusBarAlignment.Left, Number.MIN_VALUE);
75
89
  }
76
90