0
# Workspace Preferences
1
2
The workspace preferences module provides configuration management for workspace behavior settings. It includes basic workspace preferences and workspace trust management, integrating with Theia's preference system for persistent configuration.
3
4
## Capabilities
5
6
### Workspace Configuration
7
8
Basic workspace behavior preferences and configuration schema.
9
10
```typescript { .api }
11
interface WorkspaceConfiguration {
12
/** Whether to preserve window when opening workspace */
13
'workspace.preserveWindow': boolean;
14
}
15
16
/**
17
* Workspace preference schema definition
18
*/
19
const workspacePreferenceSchema: PreferenceSchema;
20
```
21
22
**Usage Example:**
23
24
```typescript
25
import { injectable, inject } from "@theia/core/shared/inversify";
26
import { WorkspacePreferences } from "@theia/workspace/lib/browser";
27
28
@injectable()
29
export class MyWorkspaceHandler {
30
31
@inject(WorkspacePreferences)
32
protected readonly preferences: WorkspacePreferences;
33
34
async openWorkspace(uri: URI): Promise<void> {
35
// Check if workspace should open in same window
36
const preserveWindow = this.preferences['workspace.preserveWindow'];
37
38
if (preserveWindow) {
39
console.log("Opening workspace in current window");
40
// Open in same window
41
} else {
42
console.log("Opening workspace in new window");
43
// Open in new window
44
}
45
}
46
47
listenToPreferenceChanges(): void {
48
// React to preference changes
49
this.preferences.onPreferenceChanged(event => {
50
if (event.preferenceName === 'workspace.preserveWindow') {
51
console.log(`Window preservation setting changed to: ${event.newValue}`);
52
this.updateWorkspaceOpenBehavior(event.newValue);
53
}
54
});
55
}
56
57
private updateWorkspaceOpenBehavior(preserveWindow: boolean): void {
58
// Update internal state based on preference change
59
if (preserveWindow) {
60
this.enableSameWindowMode();
61
} else {
62
this.enableNewWindowMode();
63
}
64
}
65
}
66
```
67
68
### Workspace Preferences Factory
69
70
Factory functions and dependency injection setup for workspace preferences.
71
72
```typescript { .api }
73
/**
74
* Workspace preferences type alias
75
*/
76
type WorkspacePreferences = PreferenceProxy<WorkspaceConfiguration>;
77
78
/**
79
* Create workspace preferences proxy
80
* @param preferences - The preference service instance
81
* @param schema - Optional preference schema (defaults to workspacePreferenceSchema)
82
*/
83
function createWorkspacePreferences(
84
preferences: PreferenceService,
85
schema?: PreferenceSchema
86
): WorkspacePreferences;
87
88
/**
89
* Bind workspace preferences for dependency injection
90
* @param bind - Inversify binding function
91
*/
92
function bindWorkspacePreferences(bind: interfaces.Bind): void;
93
```
94
95
**Usage Example:**
96
97
```typescript
98
import { ContainerModule } from "@theia/core/shared/inversify";
99
import { createWorkspacePreferences, bindWorkspacePreferences } from "@theia/workspace/lib/browser";
100
101
// In your module configuration
102
export default new ContainerModule(bind => {
103
// Use the convenience binding function
104
bindWorkspacePreferences(bind);
105
106
// Or create custom bindings
107
bind(MyWorkspacePreferences).toDynamicValue(ctx => {
108
const preferences = ctx.container.get(PreferenceService);
109
const customSchema = {
110
...workspacePreferenceSchema,
111
properties: {
112
...workspacePreferenceSchema.properties,
113
'myExtension.customSetting': {
114
type: 'boolean',
115
default: false,
116
description: 'Custom workspace setting'
117
}
118
}
119
};
120
return createWorkspacePreferences(preferences, customSchema);
121
}).inSingletonScope();
122
});
123
```
124
125
### Workspace Trust Service
126
127
Service for managing workspace trust and security settings.
128
129
```typescript { .api }
130
class WorkspaceTrustService {
131
/**
132
* Get the current workspace trust status
133
*/
134
getWorkspaceTrust(): Promise<boolean>;
135
136
/**
137
* Request workspace trust from the user
138
* Returns the trust decision or undefined if already resolved
139
*/
140
requestWorkspaceTrust(): Promise<boolean | undefined>;
141
}
142
```
143
144
**Usage Example:**
145
146
```typescript
147
import { injectable, inject } from "@theia/core/shared/inversify";
148
import { WorkspaceTrustService } from "@theia/workspace/lib/browser";
149
150
@injectable()
151
export class MySecurityAwareComponent {
152
153
@inject(WorkspaceTrustService)
154
protected readonly trustService: WorkspaceTrustService;
155
156
async executeSecuritySensitiveOperation(): Promise<void> {
157
// Check if workspace is trusted before proceeding
158
const isTrusted = await this.trustService.getWorkspaceTrust();
159
160
if (!isTrusted) {
161
console.log("Workspace is not trusted, requesting user permission");
162
163
// Request trust from user
164
const trustGranted = await this.trustService.requestWorkspaceTrust();
165
166
if (trustGranted === undefined) {
167
console.log("Trust status already resolved");
168
return;
169
}
170
171
if (!trustGranted) {
172
console.log("User denied workspace trust");
173
return;
174
}
175
}
176
177
console.log("Workspace is trusted, proceeding with operation");
178
// Perform security-sensitive operation
179
this.performSecureOperation();
180
}
181
182
async checkTrustAndExecute<T>(operation: () => Promise<T>): Promise<T | undefined> {
183
const isTrusted = await this.trustService.getWorkspaceTrust();
184
185
if (isTrusted) {
186
return await operation();
187
} else {
188
console.log("Operation blocked: workspace not trusted");
189
return undefined;
190
}
191
}
192
193
private async performSecureOperation(): Promise<void> {
194
// Implementation of security-sensitive functionality
195
console.log("Executing trusted operation");
196
}
197
}
198
```
199
200
### Integration with Extension Development
201
202
Workspace preferences integrate with the broader Theia ecosystem through the preference system.
203
204
**Usage Example:**
205
206
```typescript
207
import { injectable, inject, postConstruct } from "@theia/core/shared/inversify";
208
import { WorkspacePreferences, WorkspaceTrustService } from "@theia/workspace/lib/browser";
209
import { PreferenceService } from "@theia/core/lib/browser";
210
211
@injectable()
212
export class MyWorkspaceExtension {
213
214
@inject(WorkspacePreferences)
215
protected readonly workspacePreferences: WorkspacePreferences;
216
217
@inject(WorkspaceTrustService)
218
protected readonly trustService: WorkspaceTrustService;
219
220
@inject(PreferenceService)
221
protected readonly preferenceService: PreferenceService;
222
223
@postConstruct()
224
initialize(): void {
225
this.setupPreferenceListeners();
226
this.checkInitialTrustStatus();
227
}
228
229
private setupPreferenceListeners(): void {
230
// Listen to workspace preference changes
231
this.workspacePreferences.onPreferenceChanged(event => {
232
console.log(`Workspace preference ${event.preferenceName} changed:`, {
233
oldValue: event.oldValue,
234
newValue: event.newValue
235
});
236
237
this.handlePreferenceChange(event.preferenceName, event.newValue);
238
});
239
}
240
241
private async checkInitialTrustStatus(): Promise<void> {
242
const isTrusted = await this.trustService.getWorkspaceTrust();
243
console.log(`Initial workspace trust status: ${isTrusted}`);
244
245
if (isTrusted) {
246
this.enableTrustedFeatures();
247
} else {
248
this.restrictUntrustedFeatures();
249
}
250
}
251
252
private handlePreferenceChange(preferenceName: string, newValue: any): void {
253
switch (preferenceName) {
254
case 'workspace.preserveWindow':
255
this.updateWindowBehavior(newValue);
256
break;
257
default:
258
console.log(`Unhandled preference change: ${preferenceName}`);
259
}
260
}
261
262
private updateWindowBehavior(preserveWindow: boolean): void {
263
console.log(`Window preservation ${preserveWindow ? 'enabled' : 'disabled'}`);
264
}
265
266
private enableTrustedFeatures(): void {
267
console.log("Enabling trusted workspace features");
268
}
269
270
private restrictUntrustedFeatures(): void {
271
console.log("Restricting features for untrusted workspace");
272
}
273
}
274
```
275
276
### Custom Preference Extensions
277
278
Example of extending workspace preferences with custom settings.
279
280
**Usage Example:**
281
282
```typescript
283
import { PreferenceSchema, PreferenceScope } from "@theia/core/lib/browser";
284
import { createWorkspacePreferences } from "@theia/workspace/lib/browser";
285
286
// Define custom workspace preference schema
287
export const customWorkspacePreferenceSchema: PreferenceSchema = {
288
type: 'object',
289
scope: PreferenceScope.Workspace,
290
properties: {
291
// Extend the base workspace preferences
292
'workspace.preserveWindow': {
293
description: 'Enable opening workspaces in current window',
294
type: 'boolean',
295
default: false
296
},
297
// Add custom preferences
298
'workspace.autoSave': {
299
description: 'Automatically save workspace configuration changes',
300
type: 'boolean',
301
default: true
302
},
303
'workspace.defaultLayout': {
304
description: 'Default layout for new workspaces',
305
type: 'string',
306
enum: ['simple', 'advanced', 'custom'],
307
default: 'simple'
308
}
309
}
310
};
311
312
interface CustomWorkspaceConfiguration extends WorkspaceConfiguration {
313
'workspace.autoSave': boolean;
314
'workspace.defaultLayout': 'simple' | 'advanced' | 'custom';
315
}
316
317
@injectable()
318
export class CustomWorkspaceManager {
319
320
private customPreferences: PreferenceProxy<CustomWorkspaceConfiguration>;
321
322
constructor(
323
@inject(PreferenceService) preferenceService: PreferenceService
324
) {
325
this.customPreferences = createWorkspacePreferences(
326
preferenceService,
327
customWorkspacePreferenceSchema
328
) as PreferenceProxy<CustomWorkspaceConfiguration>;
329
}
330
331
getWorkspaceLayout(): string {
332
return this.customPreferences['workspace.defaultLayout'];
333
}
334
335
isAutoSaveEnabled(): boolean {
336
return this.customPreferences['workspace.autoSave'];
337
}
338
339
shouldPreserveWindow(): boolean {
340
return this.customPreferences['workspace.preserveWindow'];
341
}
342
}
343
```
344
345
## Types
346
347
```typescript { .api }
348
interface WorkspaceConfiguration {
349
'workspace.preserveWindow': boolean;
350
}
351
352
type WorkspacePreferences = PreferenceProxy<WorkspaceConfiguration>;
353
354
interface PreferenceSchema {
355
type: string;
356
scope?: PreferenceScope;
357
properties: { [key: string]: PreferenceSchemaProperty };
358
}
359
360
interface PreferenceProxy<T> {
361
[K in keyof T]: T[K];
362
onPreferenceChanged(callback: (event: PreferenceChangeEvent<T>) => void): Disposable;
363
}
364
365
interface PreferenceChangeEvent<T> {
366
preferenceName: keyof T;
367
newValue: any;
368
oldValue: any;
369
affects(resourceUri?: string): boolean;
370
}
371
372
const workspacePreferenceSchema: PreferenceSchema;
373
374
function createWorkspacePreferences(
375
preferences: PreferenceService,
376
schema?: PreferenceSchema
377
): WorkspacePreferences;
378
379
function bindWorkspacePreferences(bind: interfaces.Bind): void;
380
```