diff --git a/packages/core/src/browser/keybinding.ts b/packages/core/src/browser/keybinding.ts index b1595faf0c908..239ee04ec58f2 100644 --- a/packages/core/src/browser/keybinding.ts +++ b/packages/core/src/browser/keybinding.ts @@ -83,7 +83,14 @@ export interface ScopedKeybinding extends Keybinding { } export const KeybindingContribution = Symbol('KeybindingContribution'); +/** + * Representation of a keybinding contribution. + */ export interface KeybindingContribution { + /** + * Registers keybindings. + * @param keybindings the keybinding registry. + */ registerKeybindings(keybindings: KeybindingRegistry): void; } diff --git a/packages/core/src/browser/shell/tab-bar-toolbar.tsx b/packages/core/src/browser/shell/tab-bar-toolbar.tsx index 51bc9ed8bed1a..2e9b3c78c9051 100644 --- a/packages/core/src/browser/shell/tab-bar-toolbar.tsx +++ b/packages/core/src/browser/shell/tab-bar-toolbar.tsx @@ -206,10 +206,15 @@ export namespace TabBarToolbar { * Clients should implement this interface if they want to contribute to the tab-bar toolbar. */ export const TabBarToolbarContribution = Symbol('TabBarToolbarContribution'); +/** + * Representation of a tabbar toolbar contribution. + */ export interface TabBarToolbarContribution { - + /** + * Registers toolbar items. + * @param registry the tabbar toolbar registry. + */ registerToolbarItems(registry: TabBarToolbarRegistry): void; - } /** diff --git a/packages/core/src/common/menu.ts b/packages/core/src/common/menu.ts index 0c13c71f39949..7f9fc0bb474f7 100644 --- a/packages/core/src/common/menu.ts +++ b/packages/core/src/common/menu.ts @@ -45,7 +45,15 @@ export type MenuPath = string[]; export const MAIN_MENU_BAR: MenuPath = ['menubar']; export const MenuContribution = Symbol('MenuContribution'); + +/** + * Representation of a menu contribution. + */ export interface MenuContribution { + /** + * Registers menus. + * @param menus the menu model registry. + */ registerMenus(menus: MenuModelRegistry): void; } diff --git a/packages/keymaps/src/browser/keybindings-widget.tsx b/packages/keymaps/src/browser/keybindings-widget.tsx index 71a3031de4177..252c4e2513d23 100644 --- a/packages/keymaps/src/browser/keybindings-widget.tsx +++ b/packages/keymaps/src/browser/keybindings-widget.tsx @@ -80,11 +80,14 @@ export class KeybindingWidget extends ReactWidget { @inject(KeymapsService) protected readonly keymapsService: KeymapsService; - protected items: KeybindingItem[] = []; - static readonly ID = 'keybindings.view.widget'; static readonly LABEL = 'Keyboard Shortcuts'; + /** + * The list of all available keybindings. + */ + protected items: KeybindingItem[] = []; + /** * The current user search query. */ @@ -94,6 +97,9 @@ export class KeybindingWidget extends ReactWidget { * The regular expression used to extract values between fuzzy results. */ protected readonly regexp = /(.*?)<\/match>/g; + /** + * The regular expression used to extract values between the keybinding separator. + */ protected readonly keybindingSeparator = /\+<\/match>/g; /** @@ -108,8 +114,14 @@ export class KeybindingWidget extends ReactWidget { protected readonly onDidUpdateEmitter = new Emitter(); readonly onDidUpdate: Event = this.onDidUpdateEmitter.event; + /** + * Search keybindings. + */ protected readonly searchKeybindings: () => void = debounce(() => this.doSearchKeybindings(), 50); + /** + * Initialize the widget. + */ @postConstruct() protected init(): void { this.id = KeybindingWidget.ID; @@ -368,7 +380,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the actions container with action icons. - * @param item {KeybindingItem} the keybinding item for the row. + * @param item the keybinding item for the row. */ protected renderActions(item: KeybindingItem): React.ReactNode { return {this.renderEdit(item)}{this.renderReset(item)}; @@ -376,7 +388,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the edit action used to update a keybinding. - * @param item {KeybindingItem} the keybinding item for the row. + * @param item the keybinding item for the row. */ protected renderEdit(item: KeybindingItem): React.ReactNode { return this.editKeybinding(item)}>; @@ -385,7 +397,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the reset action to reset the custom keybinding. * Only visible if a keybinding has a `user` scope. - * @param item {KeybindingItem} the keybinding item for the row. + * @param item the keybinding item for the row. */ protected renderReset(item: KeybindingItem): React.ReactNode { return (item.source && this.getRawValue(item.source) === KeybindingScope[1].toLocaleLowerCase()) @@ -394,7 +406,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the keybinding. - * @param keybinding {string} the keybinding value. + * @param keybinding the keybinding value. */ protected renderKeybinding(keybinding: string): React.ReactNode { const regex = new RegExp(this.keybindingSeparator); @@ -472,8 +484,14 @@ export class KeybindingWidget extends ReactWidget { /** * Compare two strings. - * @param a {string | undefined} the first string. - * @param b {string | undefined} the second string. + * - Strings are first normalized before comparison (`toLowerCase`). + * @param a the optional first string. + * @param b the optional second string. + * + * @returns an integer indicating whether `a` comes before, after or is equivalent to `b`. + * - returns `-1` if `a` occurs before `b`. + * - returns `1` if `a` occurs after `b`. + * - returns `0` if they are equivalent. */ protected compareItem(a: string | undefined, b: string | undefined): number { if (a && b) { @@ -498,7 +516,7 @@ export class KeybindingWidget extends ReactWidget { /** * Prompt users to update the keybinding for the given command. - * @param item {KeybindingItem} the keybinding item. + * @param item the keybinding item. */ protected editKeybinding(item: KeybindingItem): void { const command = this.getRawValue(item.command); @@ -519,7 +537,7 @@ export class KeybindingWidget extends ReactWidget { /** * Prompt users for confirmation before resetting. - * @param command {string} the command label. + * @param command the command label. * * @returns a Promise which resolves to `true` if a user accepts resetting. */ @@ -533,7 +551,7 @@ export class KeybindingWidget extends ReactWidget { /** * Reset the keybinding to its default value. - * @param item {KeybindingItem} the keybinding item. + * @param item the keybinding item. */ protected async resetKeybinding(item: KeybindingItem): Promise { const rawCommandId = this.getRawValue(item.id); @@ -546,9 +564,9 @@ export class KeybindingWidget extends ReactWidget { /** * Validate the provided keybinding value against its previous value. - * @param command {string} the command label. - * @param oldKeybinding {string} the old keybinding value. - * @param keybinding {string} the new keybinding value. + * @param command the command label. + * @param oldKeybinding the old keybinding value. + * @param keybinding the new keybinding value. * * @returns the end user message to display. */ @@ -573,7 +591,7 @@ export class KeybindingWidget extends ReactWidget { /** * Build the cell data with highlights if applicable. - * @param raw {string} the raw cell value. + * @param raw the raw cell value. * * @returns the list of cell data. */ @@ -612,7 +630,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the fuzzy representation of a matched result. - * @param property {string} one of the `KeybindingItem` properties. + * @param property one of the `KeybindingItem` properties. */ protected renderMatchedData(property: string): React.ReactNode { if (this.query !== '') { @@ -629,7 +647,7 @@ export class KeybindingWidget extends ReactWidget { /** * Render the raw value of a item without fuzzy highlighting. - * @param property {string} one of the `KeybindingItem` properties. + * @param property one of the `KeybindingItem` properties. */ protected getRawValue(property: string): string { return property.replace(new RegExp(this.regexp), '$1'); @@ -675,8 +693,8 @@ class EditKeybindingDialog extends SingleTextInputDialog { /** * Add `Reset` action used to reset a custom keybinding, and close the dialog. - * @param element {HTMLElement} the HTML element in question. - * @param additionalEventTypes {K[]} additional event types. + * @param element the HTML element in question. + * @param additionalEventTypes additional event types. */ protected addResetAction(element: HTMLElement, ...additionalEventTypes: K[]): void { this.addKeyListener(element, Key.ENTER, () => { @@ -712,7 +730,7 @@ class EditKeybindingDialog extends SingleTextInputDialog { /** * Extract the raw value from a string (without fuzzy matching). - * @param a {string} given string value for extraction. + * @param a given string value for extraction. * * @returns the raw value of a string without any fuzzy matching. */ diff --git a/packages/keymaps/src/browser/keymaps-frontend-contribution.ts b/packages/keymaps/src/browser/keymaps-frontend-contribution.ts index c47715227df93..b951f1cb5b918 100644 --- a/packages/keymaps/src/browser/keymaps-frontend-contribution.ts +++ b/packages/keymaps/src/browser/keymaps-frontend-contribution.ts @@ -120,6 +120,9 @@ export class KeymapsFrontendContribution extends AbstractViewContribution(widget: Widget | undefined = this.tryGetWidget(), fn: (widget: KeybindingWidget) => T): T | false { if (widget instanceof KeybindingWidget && widget.id === KeybindingWidget.ID) { return fn(widget); diff --git a/packages/keymaps/src/browser/keymaps-parser.spec.ts b/packages/keymaps/src/browser/keymaps-parser.spec.ts index ae7b0adfed68c..8be9ed5ccfc05 100644 --- a/packages/keymaps/src/browser/keymaps-parser.spec.ts +++ b/packages/keymaps/src/browser/keymaps-parser.spec.ts @@ -106,6 +106,11 @@ describe('keymaps-parser', () => { ]`); }); + /** + * Assert that the content equals the expected content. + * @param expectation the expected string. + * @param content the content to verify. + */ function assertParsing(expectation: string, content: string): void { const errors: string[] = []; const keybindings = parser.parse(content, errors); diff --git a/packages/keymaps/src/browser/keymaps-parser.ts b/packages/keymaps/src/browser/keymaps-parser.ts index e3788a6777e8d..b0548bb5c74a2 100644 --- a/packages/keymaps/src/browser/keymaps-parser.ts +++ b/packages/keymaps/src/browser/keymaps-parser.ts @@ -56,6 +56,11 @@ export class KeymapsParser { }).compile(keymapsSchema); } + /** + * Parse the keybindings for potential errors. + * @param content the content. + * @param errors the optional list of parsing errors. + */ parse(content: string, errors?: string[]): Keybinding[] { const strippedContent = parser.stripComments(content); const parsingErrors: parser.ParseError[] | undefined = errors ? [] : undefined; @@ -76,6 +81,10 @@ export class KeymapsParser { return []; } + /** + * Print the parsed error code. + * @param code the error code if available. + */ // https://github.com/Microsoft/node-jsonc-parser/issues/13 // tslint:disable-next-line:typedef protected printParseErrorCode(code: number | undefined) { diff --git a/packages/keymaps/src/browser/keymaps-service.ts b/packages/keymaps/src/browser/keymaps-service.ts index bb7ea5cfb2b45..27b4ad362cb29 100644 --- a/packages/keymaps/src/browser/keymaps-service.ts +++ b/packages/keymaps/src/browser/keymaps-service.ts @@ -23,9 +23,21 @@ import { KeymapsParser } from './keymaps-parser'; import * as jsoncparser from 'jsonc-parser'; import { Emitter } from '@theia/core/lib/common/'; +/** + * Representation of a JSON keybinding. + */ export interface KeybindingJson { + /** + * The keybinding command. + */ command: string, + /** + * The actual keybinding. + */ keybinding: string, + /** + * The keybinding context. + */ context: string, } @@ -49,6 +61,9 @@ export class KeymapsService { protected resource: Resource; + /** + * Initialize the keybinding service. + */ @postConstruct() protected async init(): Promise { this.resource = await this.resourceProvider(new URI().withScheme(UserStorageUri.SCHEME).withPath('keymaps.json')); @@ -59,12 +74,18 @@ export class KeymapsService { this.keyBindingRegistry.onKeybindingsChanged(() => this.changeKeymapEmitter.fire(undefined)); } + /** + * Reconcile all the keybindings, registering them to the registry. + */ protected async reconcile(): Promise { const keybindings = await this.parseKeybindings(); this.keyBindingRegistry.setKeymap(KeybindingScope.USER, keybindings); this.changeKeymapEmitter.fire(undefined); } + /** + * Parsed the read keybindings. + */ protected async parseKeybindings(): Promise { try { const content = await this.resource.readContents(); @@ -74,6 +95,10 @@ export class KeymapsService { } } + /** + * Open the keybindings widget. + * @param ref the optional reference for opening the widget. + */ open(ref?: Widget): void { const options: WidgetOpenerOptions = { widgetOptions: ref ? { area: 'main', mode: 'split-right', ref } : { area: 'main' }, @@ -82,6 +107,10 @@ export class KeymapsService { open(this.opener, this.resource.uri, options); } + /** + * Set the keybinding in the JSON. + * @param keybindingJson the JSON keybindings. + */ async setKeybinding(keybindingJson: KeybindingJson): Promise { if (!this.resource.saveContents) { return; @@ -102,6 +131,10 @@ export class KeymapsService { await this.resource.saveContents(JSON.stringify(keybindings, undefined, 4)); } + /** + * Remove the given keybinding with the given command id from the JSON. + * @param commandId the keybinding command id. + */ async removeKeybinding(commandId: string): Promise { if (!this.resource.saveContents) { return; @@ -112,6 +145,11 @@ export class KeymapsService { await this.resource.saveContents(JSON.stringify(filtered, undefined, 4)); } + /** + * Get the list of keybindings from the JSON. + * + * @returns the list of keybindings in JSON. + */ async getKeybindings(): Promise { if (!this.resource.saveContents) { return [];