or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-framework.mdcommands.mddependency-injection.mdevents-messaging.mdindex.mdkeybindings.mdmenus.mdpreferences-configuration.mdresources-files.mdwidgets-ui.md

preferences-configuration.mddocs/

0

# Preferences and Configuration

1

2

Theia's preference system provides type-safe preference management with schema definition, multiple providers, and runtime configuration changes for customizable applications.

3

4

## Capabilities

5

6

### Preference Service

7

8

Core service for accessing and modifying application preferences.

9

10

```typescript { .api }

11

/**

12

* Service for managing application preferences

13

*/

14

interface PreferenceService {

15

/**

16

* Get preference value

17

* @param preferenceName - Preference identifier

18

* @param defaultValue - Default value if preference not set

19

* @returns Preference value or default

20

*/

21

get<T>(preferenceName: string, defaultValue?: T): T | undefined;

22

23

/**

24

* Set preference value

25

* @param preferenceName - Preference identifier

26

* @param value - Value to set

27

* @returns Promise that resolves when preference is saved

28

*/

29

set(preferenceName: string, value: any): Promise<void>;

30

31

/**

32

* Check if preference has been set

33

* @param preferenceName - Preference identifier

34

* @returns True if preference exists

35

*/

36

has(preferenceName: string): boolean;

37

38

/**

39

* Remove preference

40

* @param preferenceName - Preference identifier

41

* @returns Promise that resolves when preference is removed

42

*/

43

unset(preferenceName: string): Promise<void>;

44

45

/**

46

* Event fired when preferences change

47

*/

48

readonly onPreferenceChanged: Event<PreferenceChangeEvent<any>>;

49

50

/**

51

* Event fired when preferences are about to change

52

*/

53

readonly onPreferencesChanged: Event<PreferenceChanges>;

54

}

55

56

/**

57

* Service token for PreferenceService

58

*/

59

const PreferenceService: symbol;

60

```

61

62

**Usage Example:**

63

64

```typescript

65

import { inject, injectable } from "@theia/core";

66

import { PreferenceService } from "@theia/core/lib/browser";

67

68

@injectable()

69

export class MyConfigurableService {

70

constructor(

71

@inject(PreferenceService) private readonly preferences: PreferenceService

72

) {

73

// Listen for preference changes

74

this.preferences.onPreferenceChanged(event => {

75

if (event.preferenceName === 'myExtension.enableFeature') {

76

this.updateFeatureState(event.newValue);

77

}

78

});

79

}

80

81

private updateFeatureState(enabled: boolean): void {

82

console.log(`Feature ${enabled ? 'enabled' : 'disabled'}`);

83

}

84

85

async configure(): Promise<void> {

86

// Get preference with default

87

const theme = this.preferences.get('workbench.colorTheme', 'dark');

88

89

// Check if preference exists

90

if (!this.preferences.has('myExtension.initialized')) {

91

await this.preferences.set('myExtension.initialized', true);

92

}

93

94

// Get typed preference

95

const maxFiles = this.preferences.get<number>('files.maxOpenFiles', 50);

96

}

97

}

98

```

99

100

### Preference Schema

101

102

Define preference schemas with validation, types, and UI metadata.

103

104

```typescript { .api }

105

/**

106

* Preference schema definition

107

*/

108

interface PreferenceSchema {

109

[name: string]: PreferenceSchemaProperty;

110

}

111

112

/**

113

* Individual preference property definition

114

*/

115

interface PreferenceSchemaProperty {

116

/** Property type */

117

type?: 'boolean' | 'string' | 'number' | 'integer' | 'array' | 'object';

118

119

/** Default value */

120

default?: any;

121

122

/** Human-readable description */

123

description?: string;

124

125

/** Allowed enum values */

126

enum?: any[];

127

128

/** Enum descriptions */

129

enumDescriptions?: string[];

130

131

/** Minimum value (numbers) */

132

minimum?: number;

133

134

/** Maximum value (numbers) */

135

maximum?: number;

136

137

/** Array item type */

138

items?: PreferenceSchemaProperty;

139

140

/** Object property definitions */

141

properties?: { [key: string]: PreferenceSchemaProperty };

142

143

/** Additional properties allowed */

144

additionalProperties?: boolean | PreferenceSchemaProperty;

145

146

/** Preference scope */

147

scope?: PreferenceScope;

148

149

/** UI order hint */

150

order?: number;

151

152

/** Deprecation message */

153

deprecationMessage?: string;

154

}

155

156

/**

157

* Preference scope enumeration

158

*/

159

enum PreferenceScope {

160

/** User-wide preferences */

161

User = 1,

162

163

/** Workspace-specific preferences */

164

Workspace = 2,

165

166

/** Folder-specific preferences */

167

Folder = 3

168

}

169

```

170

171

**Usage Example:**

172

173

```typescript

174

import { PreferenceSchema } from "@theia/core/lib/browser";

175

176

export const myExtensionPreferenceSchema: PreferenceSchema = {

177

'myExtension.enableFeature': {

178

type: 'boolean',

179

default: true,

180

description: 'Enable the special feature',

181

scope: PreferenceScope.User

182

},

183

184

'myExtension.maxRetries': {

185

type: 'integer',

186

default: 3,

187

minimum: 1,

188

maximum: 10,

189

description: 'Maximum number of retry attempts'

190

},

191

192

'myExtension.theme': {

193

type: 'string',

194

default: 'auto',

195

enum: ['light', 'dark', 'auto'],

196

enumDescriptions: [

197

'Light theme',

198

'Dark theme',

199

'Auto-detect from system'

200

],

201

description: 'Color theme preference'

202

},

203

204

'myExtension.excludePatterns': {

205

type: 'array',

206

items: {

207

type: 'string'

208

},

209

default: ['*.tmp', '*.log'],

210

description: 'File patterns to exclude'

211

}

212

};

213

```

214

215

### Preference Proxy

216

217

Type-safe preference access with automatic change detection.

218

219

```typescript { .api }

220

/**

221

* Type-safe preference proxy

222

*/

223

class PreferenceProxy<T> {

224

/**

225

* Event fired when preferences change

226

*/

227

readonly onPreferenceChanged: Event<PreferenceChangeEvent<T>>;

228

229

/**

230

* Get all preference values

231

* @returns Current preference values

232

*/

233

getPreferences(): T;

234

235

/**

236

* Access preferences like object properties

237

*/

238

[K in keyof T]: T[K];

239

}

240

241

/**

242

* Create preference proxy

243

* @param preferences - Preference service

244

* @param schema - Preference schema

245

* @returns Type-safe preference proxy

246

*/

247

function createPreferenceProxy<T>(

248

preferences: PreferenceService,

249

schema: PreferenceSchema

250

): PreferenceProxy<T>;

251

```

252

253

**Usage Example:**

254

255

```typescript

256

interface MyExtensionConfig {

257

enableFeature: boolean;

258

maxRetries: number;

259

theme: 'light' | 'dark' | 'auto';

260

excludePatterns: string[];

261

}

262

263

@injectable()

264

export class MyConfigurableService {

265

private readonly config: PreferenceProxy<MyExtensionConfig>;

266

267

constructor(

268

@inject(PreferenceService) preferences: PreferenceService

269

) {

270

this.config = createPreferenceProxy(preferences, myExtensionPreferenceSchema);

271

272

// Listen for specific preference changes

273

this.config.onPreferenceChanged(event => {

274

if (event.preferenceName === 'myExtension.enableFeature') {

275

this.handleFeatureToggle(event.newValue);

276

}

277

});

278

}

279

280

private handleFeatureToggle(enabled: boolean): void {

281

// Type-safe access to preferences

282

console.log(`Feature ${enabled ? 'enabled' : 'disabled'}`);

283

console.log(`Max retries: ${this.config.maxRetries}`);

284

console.log(`Theme: ${this.config.theme}`);

285

console.log(`Exclude patterns: ${this.config.excludePatterns.join(', ')}`);

286

}

287

}

288

```

289

290

### Preference Providers

291

292

Extensible preference provider system for different preference sources.

293

294

```typescript { .api }

295

/**

296

* Preference provider interface

297

*/

298

interface PreferenceProvider {

299

/**

300

* Get preference value

301

* @param preferenceName - Preference name

302

* @returns Preference value or undefined

303

*/

304

get<T>(preferenceName: string): T | undefined;

305

306

/**

307

* Set preference value

308

* @param preferenceName - Preference name

309

* @param value - Value to set

310

* @returns Promise that resolves when saved

311

*/

312

set(preferenceName: string, value: any): Promise<boolean>;

313

314

/**

315

* Get all preference names

316

* @returns Array of preference names

317

*/

318

getPreferenceNames(): string[];

319

320

/**

321

* Event fired when preferences change

322

*/

323

readonly onDidPreferencesChanged: Event<PreferenceChanges>;

324

325

/**

326

* Provider domain (user, workspace, folder)

327

*/

328

readonly domain: PreferenceDomain;

329

}

330

331

/**

332

* Preference domain types

333

*/

334

type PreferenceDomain = 'user' | 'workspace' | 'folder';

335

336

/**

337

* Service token for PreferenceProvider

338

*/

339

const PreferenceProvider: symbol;

340

```

341

342

### Configuration Files

343

344

Support for various configuration file formats.

345

346

```typescript { .api }

347

/**

348

* JSON preference provider for .json config files

349

*/

350

class JsonPreferenceProvider implements PreferenceProvider {

351

constructor(uri: URI, scope: PreferenceScope);

352

353

get<T>(preferenceName: string): T | undefined;

354

set(preferenceName: string, value: any): Promise<boolean>;

355

getPreferenceNames(): string[];

356

357

readonly onDidPreferencesChanged: Event<PreferenceChanges>;

358

readonly domain: PreferenceDomain;

359

}

360

361

/**

362

* Workspace preference provider

363

*/

364

class WorkspacePreferenceProvider extends JsonPreferenceProvider {

365

constructor(workspaceUri: URI);

366

}

367

368

/**

369

* User preference provider

370

*/

371

class UserPreferenceProvider extends JsonPreferenceProvider {

372

constructor();

373

}

374

```

375

376

## Events and Changes

377

378

### Preference Change Events

379

380

Detailed information about preference changes.

381

382

```typescript { .api }

383

/**

384

* Event fired when a preference changes

385

*/

386

interface PreferenceChangeEvent<T> {

387

/** Name of the preference that changed */

388

readonly preferenceName: string;

389

390

/** New preference value */

391

readonly newValue: T | undefined;

392

393

/** Previous preference value */

394

readonly oldValue: T | undefined;

395

396

/** Preference scope that changed */

397

readonly scope: PreferenceScope;

398

399

/** Domain where change occurred */

400

readonly domain: PreferenceDomain;

401

}

402

403

/**

404

* Collection of preference changes

405

*/

406

interface PreferenceChanges {

407

[preferenceName: string]: PreferenceChange;

408

}

409

410

/**

411

* Individual preference change

412

*/

413

interface PreferenceChange {

414

/** New value */

415

readonly newValue: any;

416

417

/** Old value */

418

readonly oldValue: any;

419

420

/** Change scope */

421

readonly scope: PreferenceScope;

422

}

423

```

424

425

## Advanced Usage

426

427

### Custom Preference Providers

428

429

Create custom providers for specialized preference sources.

430

431

```typescript

432

import { injectable } from "@theia/core";

433

import { PreferenceProvider, PreferenceChanges } from "@theia/core/lib/browser";

434

435

@injectable()

436

export class DatabasePreferenceProvider implements PreferenceProvider {

437

readonly domain = 'user';

438

private readonly onDidPreferencesChangedEmitter = new Emitter<PreferenceChanges>();

439

readonly onDidPreferencesChanged = this.onDidPreferencesChangedEmitter.event;

440

441

async get<T>(preferenceName: string): Promise<T | undefined> {

442

// Load from database

443

return this.database.getPreference(preferenceName);

444

}

445

446

async set(preferenceName: string, value: any): Promise<boolean> {

447

const oldValue = await this.get(preferenceName);

448

await this.database.setPreference(preferenceName, value);

449

450

// Fire change event

451

this.onDidPreferencesChangedEmitter.fire({

452

[preferenceName]: {

453

newValue: value,

454

oldValue,

455

scope: PreferenceScope.User

456

}

457

});

458

459

return true;

460

}

461

462

getPreferenceNames(): string[] {

463

return this.database.getAllPreferenceNames();

464

}

465

}

466

```

467

468

## Types

469

470

```typescript { .api }

471

/**

472

* Preference-related type definitions

473

*/

474

type PreferenceValue = string | number | boolean | object | undefined;

475

476

type PreferenceInspection<T> = {

477

preferenceName: string;

478

defaultValue?: T;

479

globalValue?: T;

480

workspaceValue?: T;

481

folderValue?: T;

482

value?: T;

483

};

484

485

interface PreferenceConfiguration {

486

[name: string]: PreferenceValue;

487

}

488

```