Skip to content

feat: support keybinding via extensions #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/components/menu/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@
}
}

&__keybinding {
display: inline-block;
flex: 2 1 auto;
line-height: 1;
padding: 0 2em;
text-align: right;
}

&__separator {
height: 1px;
width: 100%;
Expand Down
15 changes: 9 additions & 6 deletions src/controller/activityBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {
CONTEXT_MENU_EXPLORER,
CONTEXT_MENU_SEARCH,
CONTEXT_MENU_HIDE,
CONTEXT_MENU_COLOR_THEME,
CONTEXT_MENU_COMMAND_PALETTE,
CONTEXT_MENU_SETTINGS,
IActivityBarItem,
} from 'mo/model';
import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction';
Expand All @@ -24,6 +21,12 @@ import {
} from 'mo/services';
import { CommandQuickAccessViewAction } from 'mo/monaco/quickAccessViewAction';
import { IMonacoService, MonacoService } from 'mo/monaco/monacoService';
import {
ACTION_QUICK_COMMAND,
ACTION_QUICK_ACCESS_SETTINGS,
ACTION_SELECT_THEME,
} from 'mo/model/keybinding';

export interface IActivityBarController {
/**
* Called when activity bar item is clicked
Expand Down Expand Up @@ -107,15 +110,15 @@ export class ActivityBarController
break;
}
// manage button contextMenu
case CONTEXT_MENU_COMMAND_PALETTE: {
case ACTION_QUICK_COMMAND: {
this.gotoQuickCommand();
break;
}
case CONTEXT_MENU_SETTINGS: {
case ACTION_QUICK_ACCESS_SETTINGS: {
this.settingsService.openSettingsInEditor();
break;
}
case CONTEXT_MENU_COLOR_THEME: {
case ACTION_SELECT_THEME: {
this.onSelectColorTheme();
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/extensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ExtendsActivityBar } from './activityBar';
import { ExtendsPanel } from './panel';
import { ExtendsExplorer } from './explorer';
import { ExtendsEditorTree } from './editorTree';
import { ExtendsKeybinding } from './keybinding';

import { defaultColorThemeExtension } from './theme-defaults';
import { monokaiColorThemeExtension } from './theme-monokai';
Expand All @@ -28,4 +29,5 @@ export const defaultExtensions = [
monokaiColorThemeExtension,
paleNightColorThemeExtension,
ExtendsFolderTree,
ExtendsKeybinding,
];
15 changes: 15 additions & 0 deletions src/extensions/keybinding/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { IExtensionService } from 'mo/services';
import { IExtension } from 'mo/model';
import { SelectLocaleAction } from 'mo/i18n/selectLocaleAction';
import { QuickAccessSettings } from 'mo/monaco/quickAccessSettingsAction';
import { CommandQuickAccessViewAction } from 'mo/monaco/quickAccessViewAction';
import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction';

export const ExtendsKeybinding: IExtension = {
activate(extensionCtx: IExtensionService) {
extensionCtx.registerAction(CommandQuickAccessViewAction);
extensionCtx.registerAction(SelectColorThemeAction);
extensionCtx.registerAction(QuickAccessSettings);
extensionCtx.registerAction(SelectLocaleAction);
},
};
8 changes: 7 additions & 1 deletion src/i18n/selectLocaleAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { Action2 } from 'mo/monaco/common';
import { localize } from './localize';
import { ILocaleService, LocaleService } from './localeService';
import { ILocale } from './localization';
import { KeyCode, KeyMod } from 'mo/monaco';
import { ACTION_SELECT_LOCALE } from 'mo/model/keybinding';

export class SelectLocaleAction extends Action2 {
static readonly ID = 'workbench.action.selectLocale';
static readonly ID = ACTION_SELECT_LOCALE;
static readonly LABEL = localize(
'select.locale',
'Select Display Language'
Expand All @@ -29,6 +31,10 @@ export class SelectLocaleAction extends Action2 {
alias: 'Select Display Language',
precondition: undefined,
f1: true,
keybinding: {
when: undefined,
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_L,
},
});
}

Expand Down
70 changes: 69 additions & 1 deletion src/model/keybinding.ts
Original file line number Diff line number Diff line change
@@ -1 +1,69 @@
export interface IKeybinding {}
import { KeyCode } from 'mo/monaco';

export const KeyCodeString: Partial<{ [key in KeyCode]: string }> = {
[KeyCode.Unknown]: '',
[KeyCode.Backspace]: '⌫',
[KeyCode.Tab]: '⇥',
[KeyCode.Enter]: '↩︎',
[KeyCode.KEY_0]: '0',
[KeyCode.KEY_1]: '1',
[KeyCode.KEY_2]: '2',
[KeyCode.KEY_3]: '3',
[KeyCode.KEY_4]: '4',
[KeyCode.KEY_5]: '5',
[KeyCode.KEY_6]: '6',
[KeyCode.KEY_7]: '7',
[KeyCode.KEY_8]: '8',
[KeyCode.KEY_9]: '9',
[KeyCode.KEY_A]: 'A',
[KeyCode.KEY_B]: 'B',
[KeyCode.KEY_C]: 'C',
[KeyCode.KEY_D]: 'D',
[KeyCode.KEY_E]: 'E',
[KeyCode.KEY_F]: 'F',
[KeyCode.KEY_G]: 'G',
[KeyCode.KEY_H]: 'H',
[KeyCode.KEY_I]: 'I',
[KeyCode.KEY_J]: 'J',
[KeyCode.KEY_K]: 'K',
[KeyCode.KEY_L]: 'L',
[KeyCode.KEY_M]: 'M',
[KeyCode.KEY_N]: 'N',
[KeyCode.KEY_O]: 'O',
[KeyCode.KEY_P]: 'P',
[KeyCode.KEY_Q]: 'Q',
[KeyCode.KEY_R]: 'R',
[KeyCode.KEY_S]: 'S',
[KeyCode.KEY_T]: 'T',
[KeyCode.KEY_U]: 'U',
[KeyCode.KEY_V]: 'V',
[KeyCode.KEY_W]: 'W',
[KeyCode.KEY_X]: 'X',
[KeyCode.KEY_Y]: 'Y',
[KeyCode.KEY_Z]: 'Z',
[KeyCode.US_SEMICOLON]: ';',
[KeyCode.US_EQUAL]: '+',
[KeyCode.US_COMMA]: ',',
[KeyCode.US_MINUS]: '-',
[KeyCode.US_DOT]: '.',
[KeyCode.US_SLASH]: '/',
[KeyCode.US_BACKTICK]: '~',
[KeyCode.US_OPEN_SQUARE_BRACKET]: '[',
[KeyCode.US_BACKSLASH]: '\\',
[KeyCode.US_CLOSE_SQUARE_BRACKET]: ']',
[KeyCode.US_QUOTE]: '"',
};

export interface ISimpleKeybinding {
ctrlKey: boolean;
shiftKey: boolean;
altKey: boolean;
metaKey: boolean;
keyCode: KeyCode;
}

export const ACTION_QUICK_ACCESS_SETTINGS =
'workbench.action.quickAccessSettings';
export const ACTION_QUICK_COMMAND = 'workbench.action.quickCommand';
export const ACTION_SELECT_THEME = 'workbench.action.selectTheme';
export const ACTION_SELECT_LOCALE = 'workbench.action.selectLocale';
15 changes: 8 additions & 7 deletions src/model/workbench/activityBar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as React from 'react';
import { IMenuItemProps } from 'mo/components/menu';
import { localize } from 'mo/i18n/localize';
import {
ACTION_QUICK_ACCESS_SETTINGS,
ACTION_QUICK_COMMAND,
ACTION_SELECT_THEME,
} from '../keybinding';

/**
* The activity bar event definition
Expand Down Expand Up @@ -38,10 +43,6 @@ export interface IActivityBar {
export const ACTIVITY_BAR_GLOBAL_SETTINGS = 'global.menu.settings';
export const ACTIVITY_BAR_GLOBAL_ACCOUNT = 'global.menu.account';

export const CONTEXT_MENU_COMMAND_PALETTE = 'menu.commandPalette';
export const CONTEXT_MENU_SETTINGS = 'menu.settings';
export const CONTEXT_MENU_COLOR_THEME = 'menu.colorTheme';

export const CONTEXT_MENU_MENU = 'menubar';
export const CONTEXT_MENU_EXPLORER = 'sidebar.explore.title';
export const CONTEXT_MENU_SEARCH = 'sidebar.search.title';
Expand All @@ -62,15 +63,15 @@ export function builtInActivityBar(): IActivityBar {
type: 'global',
contextMenu: [
{
id: CONTEXT_MENU_COMMAND_PALETTE,
id: ACTION_QUICK_COMMAND,
name: localize('menu.commandPalette', 'Command Palette'),
},
{
id: CONTEXT_MENU_SETTINGS,
id: ACTION_QUICK_ACCESS_SETTINGS,
name: localize('menu.settings', 'Settings'),
},
{
id: CONTEXT_MENU_COLOR_THEME,
id: ACTION_SELECT_THEME,
name: localize('menu.colorTheme', 'Color Theme'),
},
],
Expand Down
8 changes: 0 additions & 8 deletions src/molecule.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ import {
NotificationService,
IColorThemeService,
ColorThemeService,
IExtensionService,
ExtensionService,
ISettingsService,
SettingsService,
IProblemsService,
Expand Down Expand Up @@ -101,12 +99,6 @@ export const colorTheme = container.resolve<IColorThemeService>(
ColorThemeService
);

/**
* Note: The extension service depends on other workbench services,
* So it need initialized be last one.
*/
export const extension = container.resolve<IExtensionService>(ExtensionService);

/**
* Settings service
*/
Expand Down
10 changes: 9 additions & 1 deletion src/monaco/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ export enum KeybindingWeight {
}

export abstract class Action2 {
constructor(readonly desc: Readonly<any>) {}
constructor(
readonly desc: Readonly<{
/**
* Specify visible in quick access view
*/
f1: boolean;
[key: string]: any;
}>
) {}
abstract run(accessor: ServicesAccessor, ...args: any[]): any;
}

Expand Down
3 changes: 2 additions & 1 deletion src/monaco/quickAccessSettingsAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { ISettingsService, SettingsService } from 'mo/services';
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
import { container } from 'tsyringe';
import { Action2, KeybindingWeight } from './common';
import { ACTION_QUICK_ACCESS_SETTINGS } from 'mo/model/keybinding';

export class QuickAccessSettings extends Action2 {
static readonly ID = 'workbench.action.quickAccessSettings';
static readonly ID = ACTION_QUICK_ACCESS_SETTINGS;
static readonly LABEL = localize(
'quickAccessSettings.label',
'Open Settings (JSON)'
Expand Down
3 changes: 2 additions & 1 deletion src/monaco/quickAccessViewAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { EditorService, IEditorService } from 'mo/services';
import { Action2, KeybindingWeight } from './common';
import { MonacoService } from './monacoService';
import { registerQuickAccessProvider } from './quickAccessProvider';
import { ACTION_QUICK_COMMAND } from 'mo/model/keybinding';

export class CommandQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider {
static PREFIX = '>';
Expand Down Expand Up @@ -166,7 +167,7 @@ registerQuickAccessProvider({
});

export class CommandQuickAccessViewAction extends Action2 {
static ID = 'workbench.action.quickCommand';
static ID = ACTION_QUICK_COMMAND;

constructor() {
super({
Expand Down
3 changes: 2 additions & 1 deletion src/monaco/selectColorThemeAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { ColorThemeService, IColorThemeService } from 'mo/services';
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
import { container } from 'tsyringe';
import { Action2, KeybindingWeight } from './common';
import { ACTION_SELECT_THEME } from 'mo/model/keybinding';

export class SelectColorThemeAction extends Action2 {
static readonly ID = 'workbench.action.selectTheme';
static readonly ID = ACTION_SELECT_THEME;
static readonly LABEL = localize('selectTheme.label', 'Color Theme');
private readonly colorThemeService: IColorThemeService;

Expand Down
18 changes: 1 addition & 17 deletions src/provider/molecule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,9 @@ import {
IExtensionService,
} from 'mo/services/extensionService';
import { IMonacoService, MonacoService } from 'mo/monaco/monacoService';
import { CommandQuickAccessViewAction } from 'mo/monaco/quickAccessViewAction';
import { registerAction2 } from 'mo/monaco/common';
import { QuickAccessSettings } from 'mo/monaco/quickAccessSettingsAction';
import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction';
import { ILocaleService, LocaleService } from 'mo/i18n/localeService';
import { ILayoutService, LayoutService } from 'mo/services';
import { SelectLocaleAction } from 'mo/i18n/selectLocaleAction';

export interface IMoleculeProps {
extensions?: IExtension[];
locales?: ILocale[];
Expand Down Expand Up @@ -64,18 +60,6 @@ export class MoleculeProvider extends React.Component<IMoleculeProps> {
this.monacoService.initWorkspace(this.container!);
this.extensionService.load(defaultExtensions);
this.extensionService.load(extensions);

this.initWorkbenchActions();
}

/**
* TODO: move the register of actions to extensionService
*/
initWorkbenchActions() {
registerAction2(CommandQuickAccessViewAction);
registerAction2(SelectColorThemeAction);
registerAction2(QuickAccessSettings);
registerAction2(SelectLocaleAction);
}

public render() {
Expand Down
14 changes: 14 additions & 0 deletions src/services/extensionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ColorThemeService,
IColorThemeService,
} from './theme/colorThemeService';
import { Action2, registerAction2 } from 'mo/monaco/common';

export interface IExtensionService {
/**
Expand All @@ -22,6 +23,15 @@ export interface IExtensionService {
load(extensions: IExtension[]);
loadContributes(contributes: IContribute);
unload(extension: IExtension);
/**
* Register action based in Action2,
* @example
* ```ts
* const action = class Action extends Action2 {};
* registerAction(action);
* ```
*/
registerAction(actionClass: { new (): Action2 }): void;
}

@singleton()
Expand Down Expand Up @@ -71,6 +81,10 @@ export class ExtensionService implements IExtensionService {
});
}

public registerAction(actionClass: { new (): Action2 }) {
registerAction2(actionClass);
}

unload(extension: IExtension) {
console.log('unload extension:', extension.name);
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './extensionService';
export type { IExtensionService } from './extensionService';
export * from './theme/colorThemeService';
export * from './workbench';
export * from './settingsService';
Expand Down
Loading