上一篇:使用Theia——創建語言支持
命令和快捷鍵
Theia可以通過多種不同的方式進行擴展。命令允許packages提供可以被其它包調用的唯一命令,還可以向這些命令添加快捷鍵和上下文,使得它們只能在某些特定的條件下被調用(如窗口獲取焦點、當前選項等)。
在Theia中添加命令
要將命令添加到Theia,必須實現CommandContribution類,如:
java-commands.ts
@injectable() export class JavaCommandContribution implements CommandContribution { ... registerCommands(commands: CommandRegistry): void { commands.registerCommand(SHOW_JAVA_REFERENCES, { execute: (uri: string, position: Position, locations: Location[]) => commands.executeCommand(SHOW_REFERENCES.id, uri, position, locations) }); commands.registerCommand(APPLY_WORKSPACE_EDIT, { execute: (changes: WorkspaceEdit) => !!this.workspace.applyEdit && this.workspace.applyEdit(changes) }); } }
每一個contribution需要提供一個唯一的命令id,以及一個命令處理程序(由回調函數執行)。
將contribution綁定到CommandContribution。
然后將contribution的類注入到適當的模塊中(確保類被標記為@injectable()),像這樣:
java-frontend-module.ts
export default new ContainerModule(bind => { bind(CommandContribution).to(JavaCommandContribution).inSingletonScope(); ... });
負責注冊和執行命令的類是CommandRegistry,通過get commandIds() api可以獲取命令列表。
添加快捷鍵
默認情況下不需要給命令添加快捷鍵,因為它可以通過許多不同的方式來調用(通過編程方式或者用戶點擊)。不過,我們仍然可以將具有特定上下文的快捷鍵綁定到命令上以完成相同的命令功能。
要添加快捷鍵,只需要注入一個
KeybindingContribution的實現。
editor-keybinding.ts
@injectable() export class EditorKeybindingContribution implements KeybindingContribution { constructor( @inject(EditorKeybindingContext) protected readonly editorKeybindingContext: EditorKeybindingContext ) { } registerKeybindings(registry: KeybindingRegistry): void { [ { command: 'editor.close', context: this.editorKeybindingContext, keybinding: "alt+w" }, { command: 'editor.close.all', context: this.editorKeybindingContext, keybinding: "alt+shift+w" } ].forEach(binding => { registry.registerKeybinding(binding); }); } }
commandId必須是預先注冊好的命令,而且必須唯一。
context是一個簡單的類,用於確保命令和快捷鍵的綁定組合在特定條件下是可用的。對於編輯器而言,它看起來是這樣的:
editor-keybinding.ts
@injectable() export class EditorKeybindingContext implements KeybindingContext { constructor( @inject(EditorManager) protected readonly editorService: EditorManager) { } id = 'editor.keybinding.context'; isEnabled(arg?: Keybinding) { return this.editorService && !!this.editorService.activeEditor; } }
context也有一個唯一的id,用於在上下文中將快捷鍵注冊到命令中。
isEnabled()方法會根據給定的條件返回true或false。請注意,context是一個可選參數,如果沒有提供,則默認為
NOOP_CONTEXT。使用該context注冊的快捷鍵將始終保持開啟狀態,可以在應用程序的任何地方使用。
對於
id而言,參數
keycode是必須的,它是一個包含實際快捷鍵綁定的結構。下面是一個正確的結構:
keys.ts
export declare type Keystroke = { first: Key, modifiers?: Modifier[] };
Modifier是平台無關的,所以Modifier.M1在OS X上是Command而在Windows/Linux上是CTRL。Key字符串常量定義在keys.ts中。
將contribution綁定到KeybindingContribution
與綁定命令contribution一樣,快捷鍵contribution也需要按模塊進行綁定,像這樣:
editor-frontend-module.ts
export default new ContainerModule(bind => { ... bind(CommandContribution).to(EditorCommandHandlers); bind(EditorKeybindingContext).toSelf().inSingletonScope(); bind(KeybindingContext).toDynamicValue(context => context.container.get(EditorKeybindingContext)); bind(KeybindingContribution).to(EditorKeybindingContribution); });