上一篇:Theia APIs——命令和快捷鍵
Preferences
Theia有一個preference service,模塊可以通過它來獲取preference的值,提供默認的preferences以及監聽preference的更改, Preferences的內容可以保存在workspace根目錄下的.theia/settings.json中,或者Linux系統的$HOME/.theia/settings.json檔案中,在Windows系統中,用戶設定默認保存在%USERPROFILE%/.theia/settings.json檔案中(例如c:\Users\epatpol\.theia\settings.json), 所有這些檔案都必須包含一個有效的JSON,其中包含preferences的名稱和值(注意下面例子中的preference不是官方指定的,這里僅作為一個示例),如有需要,你也可以在settings.json檔案中添加注釋,如:{ // Enable/Disable the line numbers in the monaco editor "monaco.lineNumbers": "off", // Tab width in the editor "monaco.tabWidth": 4, "fs.watcherExcludes": "path/to/file"}
我們以filesystem作為示例,它是使用preference service的一個模塊,
使用inversity創建具有默認preferences的模塊
為了提供preference的值,模塊必須提供一個有效的json schema,用來驗證所提供的值,模塊必須像下面這樣將PreferenceContributton系結到值:
export interface PreferenceSchema { [name: string]: Object, properties: { [name: string]: object }}export interface PreferenceContribution { readonly schema: PreferenceSchema;}例如,filesystem中的代碼:
export const filesystemPreferenceSchema: PreferenceSchema = { "type": "object", "properties": { "files.watcherExclude": { "description": "List of paths to exclude from the filesystem watcher", "additionalProperties": { "type": "boolean" } } }};bind(PreferenceContribution).toConstantValue({ schema: filesystemPreferenceSchema });下面是一些有關提供驗證的schema的鏈接:
- JSON schema規范
- 在線JSON驗證器
- 在線JSON schema驗證器
通過配置監聽preference的更改
要使用preference的值,只需從容器中獲得注入的PreferenceService,
const preferences = ctx.container.get(PreferenceService);
對filesystem而言,服務在一開始系結的時候獲取,這里,你可以使用onPreferenceChanged方法來注冊preference更改的回呼,
constructor(@inject(PreferenceService) protected readonly prefService: PreferenceService prefService.onPreferenceChanged(e => { callback }這里,事件接收到的物件e是下面這種型別:
export interface PreferenceChangedEvent { readonly preferenceName: string; readonly newValue?: any; readonly oldValue?: any;}
雖然我們可以在類中直接這樣使用,不過filesystem提供了一個特定于filesystem preferences的代理preference服務(該服務在后臺運行),這樣可以更快、更有效地搜索preference(因為它在filesystem preference service中進行搜索,而不是通過更通用的preference service搜索所有的內容),從某種意義上來說,它也更高效,因為只有那些監視與某個模塊相關的特定preferences的模塊才會得到通知,要做到這一點,可以看看有關filesystem配置的代理介面是如何系結使用preference代理介面的:
export type PreferenceProxy<T> = Readonly<T> & Disposable & PreferenceEventEmitter<T>;export function createPreferenceProxy<T extends Configuration>(preferences: PreferenceService, configuration: T): PreferenceProxy<T> { /* Register a client to the preference server When a preference is received, it is validated against the schema and then fired if valid, otherwise the default value is provided. This proxy is also in charge of calling the configured preference service when the proxy object is called i.e editorPrefs['preferenceName'] It basically forwards methods to the real object, i.e dispose/ready etc.}
要使用這個代理,只需要將它系結到一個新型別X = PreferenceProxy<CONFIGURATION_INTERFACE>,然后使用上面的方法bind(X)到一個代理,
export interface FileSystemConfiguration { 'files.watcherExclude': { [globPattern: string]: boolean }}export const FileSystemPreferences = Symbol('FileSystemPreferences');export type FileSystemPreferences = PreferenceProxy<FileSystemConfiguration>;export function createFileSystemPreferences(preferences: PreferenceService): FileSystemPreferences { return createPreferenceProxy(preferences, defaultFileSystemConfiguration, filesystemPreferenceSchema);}export function bindFileSystemPreferences(bind: interfaces.Bind): void { bind(FileSystemPreferences).toDynamicValue(ctx => { const preferences = ctx.container.get(PreferenceService); return createFileSystemPreferences(preferences); }); bind(PreferenceContribution).toConstantValue({ schema: filesystemPreferenceSchema });}
最后,在模塊中使用filesystem配置,只需要將它注入到你需要的地方,你可以像這樣訪問preference(以filesystem為例):
const patterns = this.preferences['files.watcherExclude'];你也可以像這樣監聽preference的更改:
this.toDispose.push(preferences.onPreferenceChanged(e => { if (e.preferenceName === 'files.watcherExclude') { this.toRestartAll.dispose(); }}));
constructor(..., @inject(FileSystemPreferences) protected readonly preferences: FileSystemPreferences) { ... this.toDispose.push(preferences.onPreferenceChanged(e => { if (e.preferenceName === 'files.watcherExclude') { this.toRestartAll.dispose(); } })); ...}
Preference的修改流程
當在${workspace}/.theia/或者os.homedir()/.theia/中修改settings.json的內容時,JSON preference服務器會觸發一個事件,首先,CompoundPreferenceServer用來管理不同的服務器(作用域),例如workspace/user/defaults(提供上面說的contributions),接下來,PreferenceService管理該服務器并在其上添加更多api以方便呼叫(例如getBoolean,getSrtring等等),它同時還允許客戶端監聽preference的修改,這個PreferenceService可以直接或通過特定的代理(如上面這個filesystem配置)被注入到模塊中, 當preference被修改時,對應的流程是:.theia/settings.json -> JsonPreferenceServer -> CompoundPreferenceServer -> PreferenceService -> PreferenceProxy<FileSystemConfiguration> -> FileSystemWatcher
獲取preference的值
對于filesystem來說,我們可以使用與上面相同的代理配置來訪問preference的內容,
if (this.prefService['preferenceName']) { ... } if (this.prefService['preferenceName2']) { ... }})
它能正常作業,正如我們在上面所看到的那樣,代理將簡單地呼叫prefService.get('preferenceName'),
TODO/FIXME
- 在CompoundPreferenceServer中添加server優先級
- 當在theia的settings.json中修改內容時添加自動完成和描述功能
原文地址:https://theia-ide.org/docs/preferences
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/6681.html
標籤:其他
下一篇:Theia APIs——事件
