0
# Filesystem Preferences
1
2
User preference management for file operations, encoding, watching, exclusions, and behavior customization. Provides comprehensive configuration options for tailoring filesystem behavior to user needs and system requirements.
3
4
## Capabilities
5
6
### FileSystemConfiguration Interface
7
8
Complete configuration schema for all filesystem-related user preferences with sensible defaults and validation.
9
10
```typescript { .api }
11
/**
12
* User preferences schema for filesystem behavior
13
*/
14
interface FileSystemConfiguration {
15
/** Glob patterns to exclude from file watching */
16
'files.watcherExclude': { [globPattern: string]: boolean };
17
18
/** Glob patterns to exclude from file listings */
19
'files.exclude': { [key: string]: boolean };
20
21
/** Enable trash/recycle bin for delete operations */
22
'files.enableTrash': boolean;
23
24
/** File pattern to language associations */
25
'files.associations': { [filepattern: string]: string };
26
27
/** Default character encoding for files */
28
'files.encoding': string;
29
30
/** Automatically detect file encoding */
31
'files.autoGuessEncoding': boolean;
32
33
/** Timeout for file operation participants (milliseconds) */
34
'files.participants.timeout': number;
35
36
/** Maximum file size to open in MB */
37
'files.maxFileSizeMB': number;
38
39
/** Trim trailing whitespace on save */
40
'files.trimTrailingWhitespace': boolean;
41
42
/** Insert final newline on save */
43
'files.insertFinalNewline': boolean;
44
45
/** Maximum concurrent file uploads */
46
'files.maxConcurrentUploads': number;
47
}
48
```
49
50
### Preference Constants
51
52
Platform-specific constants and default values for filesystem preferences.
53
54
```typescript { .api }
55
/** Windows file size limit (300 MB) */
56
const WIN32_MAX_FILE_SIZE_MB: number = 300;
57
58
/** General file size limit (16 GB) */
59
const GENERAL_MAX_FILE_SIZE_MB: number = 16 * 1024;
60
61
/** Platform-dependent file size limit */
62
const MAX_FILE_SIZE_MB: number = isWindows ? WIN32_MAX_FILE_SIZE_MB : GENERAL_MAX_FILE_SIZE_MB;
63
64
/** Default encoding for text files */
65
const DEFAULT_ENCODING: string = 'utf8';
66
67
/** Default watcher excludes */
68
const DEFAULT_WATCHER_EXCLUDES: { [pattern: string]: boolean } = {
69
'**/.git/**': true,
70
'**/node_modules/**': true,
71
'**/.DS_Store': true,
72
'**/Thumbs.db': true
73
};
74
75
/** Default file excludes */
76
const DEFAULT_FILE_EXCLUDES: { [pattern: string]: boolean } = {
77
'**/.git': true,
78
'**/.svn': true,
79
'**/.hg': true,
80
'**/CVS': true,
81
'**/.DS_Store': true,
82
'**/Thumbs.db': true
83
};
84
```
85
86
### FileSystemPreferences Type
87
88
Type-safe preference accessor providing strongly-typed access to filesystem configuration values.
89
90
```typescript { .api }
91
/**
92
* Type-safe filesystem preferences accessor
93
*/
94
type FileSystemPreferences = {
95
/** Get watcher exclude patterns */
96
'files.watcherExclude': PreferenceProxy<{ [globPattern: string]: boolean }>;
97
98
/** Get file exclude patterns */
99
'files.exclude': PreferenceProxy<{ [key: string]: boolean }>;
100
101
/** Get trash enabled setting */
102
'files.enableTrash': PreferenceProxy<boolean>;
103
104
/** Get file associations */
105
'files.associations': PreferenceProxy<{ [filepattern: string]: string }>;
106
107
/** Get default encoding */
108
'files.encoding': PreferenceProxy<string>;
109
110
/** Get auto-guess encoding setting */
111
'files.autoGuessEncoding': PreferenceProxy<boolean>;
112
113
/** Get participants timeout */
114
'files.participants.timeout': PreferenceProxy<number>;
115
116
/** Get max file size */
117
'files.maxFileSizeMB': PreferenceProxy<number>;
118
119
/** Get trim whitespace setting */
120
'files.trimTrailingWhitespace': PreferenceProxy<boolean>;
121
122
/** Get insert final newline setting */
123
'files.insertFinalNewline': PreferenceProxy<boolean>;
124
125
/** Get max concurrent uploads */
126
'files.maxConcurrentUploads': PreferenceProxy<number>;
127
};
128
129
/**
130
* Preference proxy for reactive value access
131
*/
132
interface PreferenceProxy<T> {
133
/** Current preference value */
134
readonly value: T;
135
136
/** Event fired when preference changes */
137
readonly onDidChange: Event<PreferenceChange>;
138
139
/** Get preference value with fallback */
140
get(fallback?: T): T;
141
142
/** Set preference value */
143
set(value: T): Promise<void>;
144
145
/** Reset preference to default */
146
reset(): Promise<void>;
147
}
148
```
149
150
### Preference Management Functions
151
152
Utility functions for creating and managing filesystem preferences with proper dependency injection integration.
153
154
```typescript { .api }
155
/**
156
* Create filesystem preferences from preference service
157
*/
158
function createFileSystemPreferences(
159
preferences: PreferenceService,
160
schema?: PreferenceSchema
161
): FileSystemPreferences;
162
163
/**
164
* Bind filesystem preferences to dependency injection container
165
*/
166
function bindFileSystemPreferences(bind: interfaces.Bind): void;
167
168
/**
169
* Get filesystem preference schema definition
170
*/
171
function getFileSystemPreferenceSchema(): PreferenceSchema;
172
173
/**
174
* Validate filesystem preferences
175
*/
176
function validateFileSystemPreferences(config: Partial<FileSystemConfiguration>): ValidationResult;
177
178
interface ValidationResult {
179
/** Whether configuration is valid */
180
valid: boolean;
181
182
/** Validation errors */
183
errors: string[];
184
185
/** Sanitized configuration */
186
sanitized: FileSystemConfiguration;
187
}
188
```
189
190
### Preference Change Events
191
192
Event system for reacting to preference changes with detailed change information.
193
194
```typescript { .api }
195
/**
196
* Preference change event
197
*/
198
interface PreferenceChange {
199
/** Preference key that changed */
200
readonly key: string;
201
202
/** New preference value */
203
readonly newValue: any;
204
205
/** Previous preference value */
206
readonly oldValue: any;
207
208
/** Configuration scope (user, workspace, etc.) */
209
readonly scope: PreferenceScope;
210
}
211
212
enum PreferenceScope {
213
User = 'user',
214
Workspace = 'workspace',
215
Folder = 'folder'
216
}
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
import {
223
FileSystemPreferences,
224
createFileSystemPreferences,
225
bindFileSystemPreferences
226
} from "@theia/filesystem/lib/browser";
227
import { PreferenceService } from "@theia/core/lib/browser/preferences";
228
229
// Get preferences instance
230
const preferenceService = container.get(PreferenceService);
231
const fsPreferences = createFileSystemPreferences(preferenceService);
232
233
// Access preference values
234
const encoding = fsPreferences['files.encoding'].value;
235
console.log(`Default encoding: ${encoding}`);
236
237
const maxFileSize = fsPreferences['files.maxFileSizeMB'].value;
238
console.log(`Max file size: ${maxFileSize} MB`);
239
240
const trashEnabled = fsPreferences['files.enableTrash'].value;
241
console.log(`Trash enabled: ${trashEnabled}`);
242
243
// Get with fallback
244
const timeout = fsPreferences['files.participants.timeout'].get(30000);
245
246
// React to preference changes
247
fsPreferences['files.encoding'].onDidChange(change => {
248
console.log(`Encoding changed from ${change.oldValue} to ${change.newValue}`);
249
});
250
251
fsPreferences['files.watcherExclude'].onDidChange(change => {
252
console.log('Watcher excludes updated:', change.newValue);
253
// Update file watchers with new excludes
254
updateFileWatchers(change.newValue);
255
});
256
257
// Set preference values
258
await fsPreferences['files.encoding'].set('utf16le');
259
await fsPreferences['files.trimTrailingWhitespace'].set(true);
260
await fsPreferences['files.insertFinalNewline'].set(true);
261
262
// Working with complex preferences
263
const watcherExcludes = fsPreferences['files.watcherExclude'].value;
264
console.log('Current watcher excludes:');
265
for (const [pattern, enabled] of Object.entries(watcherExcludes)) {
266
if (enabled) {
267
console.log(` ${pattern}`);
268
}
269
}
270
271
// Update complex preferences
272
const newExcludes = {
273
...watcherExcludes,
274
'**/coverage/**': true,
275
'**/dist/**': true
276
};
277
await fsPreferences['files.watcherExclude'].set(newExcludes);
278
279
// File associations
280
const associations = fsPreferences['files.associations'].value;
281
console.log('File associations:', associations);
282
283
// Add new association
284
const newAssociations = {
285
...associations,
286
'*.config': 'json',
287
'*.log': 'plaintext'
288
};
289
await fsPreferences['files.associations'].set(newAssociations);
290
291
// Reset preference to default
292
await fsPreferences['files.maxFileSizeMB'].reset();
293
294
// Check if file should be excluded
295
function isFileExcluded(filePath: string): boolean {
296
const excludes = fsPreferences['files.exclude'].value;
297
298
for (const [pattern, enabled] of Object.entries(excludes)) {
299
if (enabled && minimatch(filePath, pattern)) {
300
return true;
301
}
302
}
303
304
return false;
305
}
306
307
// Check if path should be watched
308
function shouldWatchPath(filePath: string): boolean {
309
const excludes = fsPreferences['files.watcherExclude'].value;
310
311
for (const [pattern, enabled] of Object.entries(excludes)) {
312
if (enabled && minimatch(filePath, pattern)) {
313
return false;
314
}
315
}
316
317
return true;
318
}
319
```
320
321
### Dependency Injection Setup
322
323
```typescript
324
import { ContainerModule } from 'inversify';
325
import { bindFileSystemPreferences } from "@theia/filesystem/lib/browser";
326
327
// In your Theia extension module
328
export default new ContainerModule(bind => {
329
// Bind filesystem preferences
330
bindFileSystemPreferences(bind);
331
332
// Other bindings...
333
});
334
335
// Usage in a service
336
@injectable()
337
class FileService {
338
339
constructor(
340
@inject(FileSystemPreferences) private readonly preferences: FileSystemPreferences
341
) {}
342
343
async readFile(uri: URI): Promise<string> {
344
const encoding = this.preferences['files.encoding'].value;
345
const maxSize = this.preferences['files.maxFileSizeMB'].value * 1024 * 1024;
346
347
// Use preferences in file operations
348
// ...
349
}
350
}
351
```
352
353
### Advanced Preference Usage
354
355
```typescript
356
// Custom preference validation
357
class FileSystemPreferenceValidator {
358
359
validate(config: Partial<FileSystemConfiguration>): ValidationResult {
360
const errors: string[] = [];
361
362
// Validate encoding
363
if (config['files.encoding'] && !this.isValidEncoding(config['files.encoding'])) {
364
errors.push(`Invalid encoding: ${config['files.encoding']}`);
365
}
366
367
// Validate file size
368
if (config['files.maxFileSizeMB'] && config['files.maxFileSizeMB'] <= 0) {
369
errors.push('Max file size must be positive');
370
}
371
372
// Validate timeout
373
if (config['files.participants.timeout'] && config['files.participants.timeout'] < 0) {
374
errors.push('Timeout cannot be negative');
375
}
376
377
return {
378
valid: errors.length === 0,
379
errors,
380
sanitized: this.sanitize(config)
381
};
382
}
383
384
private isValidEncoding(encoding: string): boolean {
385
const validEncodings = ['utf8', 'utf16le', 'utf16be', 'ascii', 'latin1'];
386
return validEncodings.includes(encoding.toLowerCase());
387
}
388
389
private sanitize(config: Partial<FileSystemConfiguration>): FileSystemConfiguration {
390
// Return sanitized configuration with defaults
391
return {
392
'files.watcherExclude': config['files.watcherExclude'] || DEFAULT_WATCHER_EXCLUDES,
393
'files.exclude': config['files.exclude'] || DEFAULT_FILE_EXCLUDES,
394
'files.enableTrash': config['files.enableTrash'] ?? true,
395
'files.associations': config['files.associations'] || {},
396
'files.encoding': config['files.encoding'] || DEFAULT_ENCODING,
397
'files.autoGuessEncoding': config['files.autoGuessEncoding'] ?? false,
398
'files.participants.timeout': config['files.participants.timeout'] || 60000,
399
'files.maxFileSizeMB': config['files.maxFileSizeMB'] || MAX_FILE_SIZE_MB,
400
'files.trimTrailingWhitespace': config['files.trimTrailingWhitespace'] ?? false,
401
'files.insertFinalNewline': config['files.insertFinalNewline'] ?? false,
402
'files.maxConcurrentUploads': config['files.maxConcurrentUploads'] || 5
403
};
404
}
405
}
406
407
// Preference migration
408
class FileSystemPreferenceMigrator {
409
410
migrate(oldPreferences: any): FileSystemConfiguration {
411
// Migrate old preference format to new format
412
return {
413
'files.watcherExclude': this.migrateExcludes(oldPreferences.watcherExclude),
414
'files.exclude': this.migrateExcludes(oldPreferences.exclude),
415
// ... other migrations
416
};
417
}
418
419
private migrateExcludes(oldExcludes: string[] | { [key: string]: boolean }): { [key: string]: boolean } {
420
if (Array.isArray(oldExcludes)) {
421
// Convert array format to object format
422
return oldExcludes.reduce((obj, pattern) => {
423
obj[pattern] = true;
424
return obj;
425
}, {} as { [key: string]: boolean });
426
}
427
428
return oldExcludes || {};
429
}
430
}
431
```