Theia workspace extension providing workspace functionality and services for Eclipse Theia IDE framework
—
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.
Basic workspace behavior preferences and configuration schema.
interface WorkspaceConfiguration {
/** Whether to preserve window when opening workspace */
'workspace.preserveWindow': boolean;
}
/**
* Workspace preference schema definition
*/
const workspacePreferenceSchema: PreferenceSchema;Usage Example:
import { injectable, inject } from "@theia/core/shared/inversify";
import { WorkspacePreferences } from "@theia/workspace/lib/browser";
@injectable()
export class MyWorkspaceHandler {
@inject(WorkspacePreferences)
protected readonly preferences: WorkspacePreferences;
async openWorkspace(uri: URI): Promise<void> {
// Check if workspace should open in same window
const preserveWindow = this.preferences['workspace.preserveWindow'];
if (preserveWindow) {
console.log("Opening workspace in current window");
// Open in same window
} else {
console.log("Opening workspace in new window");
// Open in new window
}
}
listenToPreferenceChanges(): void {
// React to preference changes
this.preferences.onPreferenceChanged(event => {
if (event.preferenceName === 'workspace.preserveWindow') {
console.log(`Window preservation setting changed to: ${event.newValue}`);
this.updateWorkspaceOpenBehavior(event.newValue);
}
});
}
private updateWorkspaceOpenBehavior(preserveWindow: boolean): void {
// Update internal state based on preference change
if (preserveWindow) {
this.enableSameWindowMode();
} else {
this.enableNewWindowMode();
}
}
}Factory functions and dependency injection setup for workspace preferences.
/**
* Workspace preferences type alias
*/
type WorkspacePreferences = PreferenceProxy<WorkspaceConfiguration>;
/**
* Create workspace preferences proxy
* @param preferences - The preference service instance
* @param schema - Optional preference schema (defaults to workspacePreferenceSchema)
*/
function createWorkspacePreferences(
preferences: PreferenceService,
schema?: PreferenceSchema
): WorkspacePreferences;
/**
* Bind workspace preferences for dependency injection
* @param bind - Inversify binding function
*/
function bindWorkspacePreferences(bind: interfaces.Bind): void;Usage Example:
import { ContainerModule } from "@theia/core/shared/inversify";
import { createWorkspacePreferences, bindWorkspacePreferences } from "@theia/workspace/lib/browser";
// In your module configuration
export default new ContainerModule(bind => {
// Use the convenience binding function
bindWorkspacePreferences(bind);
// Or create custom bindings
bind(MyWorkspacePreferences).toDynamicValue(ctx => {
const preferences = ctx.container.get(PreferenceService);
const customSchema = {
...workspacePreferenceSchema,
properties: {
...workspacePreferenceSchema.properties,
'myExtension.customSetting': {
type: 'boolean',
default: false,
description: 'Custom workspace setting'
}
}
};
return createWorkspacePreferences(preferences, customSchema);
}).inSingletonScope();
});Service for managing workspace trust and security settings.
class WorkspaceTrustService {
/**
* Get the current workspace trust status
*/
getWorkspaceTrust(): Promise<boolean>;
/**
* Request workspace trust from the user
* Returns the trust decision or undefined if already resolved
*/
requestWorkspaceTrust(): Promise<boolean | undefined>;
}Usage Example:
import { injectable, inject } from "@theia/core/shared/inversify";
import { WorkspaceTrustService } from "@theia/workspace/lib/browser";
@injectable()
export class MySecurityAwareComponent {
@inject(WorkspaceTrustService)
protected readonly trustService: WorkspaceTrustService;
async executeSecuritySensitiveOperation(): Promise<void> {
// Check if workspace is trusted before proceeding
const isTrusted = await this.trustService.getWorkspaceTrust();
if (!isTrusted) {
console.log("Workspace is not trusted, requesting user permission");
// Request trust from user
const trustGranted = await this.trustService.requestWorkspaceTrust();
if (trustGranted === undefined) {
console.log("Trust status already resolved");
return;
}
if (!trustGranted) {
console.log("User denied workspace trust");
return;
}
}
console.log("Workspace is trusted, proceeding with operation");
// Perform security-sensitive operation
this.performSecureOperation();
}
async checkTrustAndExecute<T>(operation: () => Promise<T>): Promise<T | undefined> {
const isTrusted = await this.trustService.getWorkspaceTrust();
if (isTrusted) {
return await operation();
} else {
console.log("Operation blocked: workspace not trusted");
return undefined;
}
}
private async performSecureOperation(): Promise<void> {
// Implementation of security-sensitive functionality
console.log("Executing trusted operation");
}
}Workspace preferences integrate with the broader Theia ecosystem through the preference system.
Usage Example:
import { injectable, inject, postConstruct } from "@theia/core/shared/inversify";
import { WorkspacePreferences, WorkspaceTrustService } from "@theia/workspace/lib/browser";
import { PreferenceService } from "@theia/core/lib/browser";
@injectable()
export class MyWorkspaceExtension {
@inject(WorkspacePreferences)
protected readonly workspacePreferences: WorkspacePreferences;
@inject(WorkspaceTrustService)
protected readonly trustService: WorkspaceTrustService;
@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;
@postConstruct()
initialize(): void {
this.setupPreferenceListeners();
this.checkInitialTrustStatus();
}
private setupPreferenceListeners(): void {
// Listen to workspace preference changes
this.workspacePreferences.onPreferenceChanged(event => {
console.log(`Workspace preference ${event.preferenceName} changed:`, {
oldValue: event.oldValue,
newValue: event.newValue
});
this.handlePreferenceChange(event.preferenceName, event.newValue);
});
}
private async checkInitialTrustStatus(): Promise<void> {
const isTrusted = await this.trustService.getWorkspaceTrust();
console.log(`Initial workspace trust status: ${isTrusted}`);
if (isTrusted) {
this.enableTrustedFeatures();
} else {
this.restrictUntrustedFeatures();
}
}
private handlePreferenceChange(preferenceName: string, newValue: any): void {
switch (preferenceName) {
case 'workspace.preserveWindow':
this.updateWindowBehavior(newValue);
break;
default:
console.log(`Unhandled preference change: ${preferenceName}`);
}
}
private updateWindowBehavior(preserveWindow: boolean): void {
console.log(`Window preservation ${preserveWindow ? 'enabled' : 'disabled'}`);
}
private enableTrustedFeatures(): void {
console.log("Enabling trusted workspace features");
}
private restrictUntrustedFeatures(): void {
console.log("Restricting features for untrusted workspace");
}
}Example of extending workspace preferences with custom settings.
Usage Example:
import { PreferenceSchema, PreferenceScope } from "@theia/core/lib/browser";
import { createWorkspacePreferences } from "@theia/workspace/lib/browser";
// Define custom workspace preference schema
export const customWorkspacePreferenceSchema: PreferenceSchema = {
type: 'object',
scope: PreferenceScope.Workspace,
properties: {
// Extend the base workspace preferences
'workspace.preserveWindow': {
description: 'Enable opening workspaces in current window',
type: 'boolean',
default: false
},
// Add custom preferences
'workspace.autoSave': {
description: 'Automatically save workspace configuration changes',
type: 'boolean',
default: true
},
'workspace.defaultLayout': {
description: 'Default layout for new workspaces',
type: 'string',
enum: ['simple', 'advanced', 'custom'],
default: 'simple'
}
}
};
interface CustomWorkspaceConfiguration extends WorkspaceConfiguration {
'workspace.autoSave': boolean;
'workspace.defaultLayout': 'simple' | 'advanced' | 'custom';
}
@injectable()
export class CustomWorkspaceManager {
private customPreferences: PreferenceProxy<CustomWorkspaceConfiguration>;
constructor(
@inject(PreferenceService) preferenceService: PreferenceService
) {
this.customPreferences = createWorkspacePreferences(
preferenceService,
customWorkspacePreferenceSchema
) as PreferenceProxy<CustomWorkspaceConfiguration>;
}
getWorkspaceLayout(): string {
return this.customPreferences['workspace.defaultLayout'];
}
isAutoSaveEnabled(): boolean {
return this.customPreferences['workspace.autoSave'];
}
shouldPreserveWindow(): boolean {
return this.customPreferences['workspace.preserveWindow'];
}
}interface WorkspaceConfiguration {
'workspace.preserveWindow': boolean;
}
type WorkspacePreferences = PreferenceProxy<WorkspaceConfiguration>;
interface PreferenceSchema {
type: string;
scope?: PreferenceScope;
properties: { [key: string]: PreferenceSchemaProperty };
}
interface PreferenceProxy<T> {
[K in keyof T]: T[K];
onPreferenceChanged(callback: (event: PreferenceChangeEvent<T>) => void): Disposable;
}
interface PreferenceChangeEvent<T> {
preferenceName: keyof T;
newValue: any;
oldValue: any;
affects(resourceUri?: string): boolean;
}
const workspacePreferenceSchema: PreferenceSchema;
function createWorkspacePreferences(
preferences: PreferenceService,
schema?: PreferenceSchema
): WorkspacePreferences;
function bindWorkspacePreferences(bind: interfaces.Bind): void;Install with Tessl CLI
npx tessl i tessl/npm-theia--workspace