From eb6347c7f5f47ec59aa5d96c2a45321e7adf1937 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 15:34:34 +0800 Subject: [PATCH 01/14] feat: add interface IDisposable and ID property in Action2 class --- src/monaco/common.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/monaco/common.ts b/src/monaco/common.ts index 509c2b925..486132297 100644 --- a/src/monaco/common.ts +++ b/src/monaco/common.ts @@ -1,7 +1,4 @@ -import { - IDisposable, - DisposableStore, -} from 'monaco-editor/esm/vs/base/common/lifecycle'; +import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle'; import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry'; import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; @@ -12,6 +9,10 @@ import { MenuId, } from 'monaco-editor/esm/vs/platform/actions/common/actions'; +export interface IDisposable { + dispose(): void; +} + export enum KeybindingWeight { EditorCore = 0, EditorContrib = 100, @@ -42,6 +43,7 @@ export const CATEGORIES = { }; export abstract class Action2 { + static readonly ID: string; constructor( readonly desc: Readonly<{ /** @@ -54,10 +56,10 @@ export abstract class Action2 { abstract run(accessor: ServicesAccessor, ...args: any[]): any; } -export function registerAction2(ctor: { new (): Action2 }): IDisposable { +export function registerAction2(Ctor: { new (): Action2 }): IDisposable { const disposables = new DisposableStore(); - // eslint-disable-next-line new-cap - const action = new ctor(); + + const action = new Ctor(); const { f1, menu, keybinding, description, ...command } = action.desc; From 6dbec3ab9e7ca8aac19d2508f061a1f884ab1133 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 15:55:05 +0800 Subject: [PATCH 02/14] feat: add return type IDisposable for registerAction --- src/services/extensionService.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/services/extensionService.ts b/src/services/extensionService.ts index 1603aae9a..243da8718 100644 --- a/src/services/extensionService.ts +++ b/src/services/extensionService.ts @@ -9,8 +9,9 @@ import { ColorThemeService, IColorThemeService, } from './theme/colorThemeService'; -import { Action2, registerAction2 } from 'mo/monaco/common'; +import { Action2, IDisposable, registerAction2 } from 'mo/monaco/common'; import { IMonacoService, MonacoService } from 'mo/monaco/monacoService'; + import { searchById } from 'mo/common/utils'; import type { UniqueId } from 'mo/common/types'; @@ -70,16 +71,18 @@ export interface IExtensionService { * @param predicate The predicate function */ inactive(predicate: (extension: IExtension) => boolean): void; - /** - * Register a new action which is extends the Action2, + * Register a new action which is extends the Action2, and return a disposable instance. * @example * ```ts * const action = class Action extends Action2 {}; - * registerAction(action); + * const disposableAction = registerAction(action); + * disposableAction.dispose(); // Dispose the action * ``` + * @param actionClass The action class + * @return IDisposable The Disposable instance */ - registerAction(actionClass: { new (): Action2 }): void; + registerAction(actionClass: { new (): Action2 }): IDisposable; /** * Execute the registered command * @param id The command ID @@ -196,8 +199,8 @@ export class ExtensionService implements IExtensionService { }); } - public registerAction(actionClass: { new (): Action2 }) { - registerAction2(actionClass); + public registerAction(ActionClass: { new (): Action2 }): IDisposable { + return registerAction2(ActionClass); } public executeCommand(id, ...args) { From dda2d5d87831ea3c6e7c1ea7504db66a762df349 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 15:56:21 +0800 Subject: [PATCH 03/14] feat: add the ID property in Action2 class --- src/monaco/quickSelectAllAction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/monaco/quickSelectAllAction.ts b/src/monaco/quickSelectAllAction.ts index a6022d435..46a1af055 100644 --- a/src/monaco/quickSelectAllAction.ts +++ b/src/monaco/quickSelectAllAction.ts @@ -8,7 +8,7 @@ import { Action2, KeybindingWeight } from './common'; import { constants } from 'mo/services/builtinService/const'; export class QuickSelectAllAction extends Action2 { - static ID = constants.ACTION_QUICK_SELECT_ALL; + static readonly ID = constants.ACTION_QUICK_SELECT_ALL; static readonly DESC = 'Select All'; static readonly LABEL = localize('menu.selectAll', 'Select All'); private readonly editorService: IEditorService; From 26fa0c740e7b280037a8c0ecfcf55054f2356ea7 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 15:59:34 +0800 Subject: [PATCH 04/14] feat: add use case for disposing an action --- stories/extensions/actions/quickOpen.ts | 51 +++++++++++++++++++++++++ stories/extensions/data-sync/index.tsx | 24 ++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 stories/extensions/actions/quickOpen.ts diff --git a/stories/extensions/actions/quickOpen.ts b/stories/extensions/actions/quickOpen.ts new file mode 100644 index 000000000..ee0118557 --- /dev/null +++ b/stories/extensions/actions/quickOpen.ts @@ -0,0 +1,51 @@ +import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput'; +import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; + +import { debounce } from 'lodash'; +import { Action2, KeybindingWeight, KeyCode, KeyMod } from 'mo/monaco'; + +export class QuickOpenAction extends Action2 { + static readonly ID = 'QuickOpenFile'; + static readonly LABEL = 'Search files by name'; + + constructor() { + super({ + id: QuickOpenAction.ID, + label: QuickOpenAction.LABEL, + title: QuickOpenAction.LABEL, + alias: QuickOpenAction.LABEL, + precondition: undefined, + f1: true, // Whether show the QuickOpenFile in Command Palette + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + when: undefined, + // eslint-disable-next-line new-cap + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyP), + }, + }); + } + + run(accessor: any, ...args: any[]) { + const quickInputService = accessor.get(IQuickInputService); + + const quickPick = quickInputService.createQuickPick(); + quickPick.items = []; + quickPick.placeholder = QuickOpenAction.LABEL; + + quickPick.activeItems = []; + quickPick.canSelectMany = false; + + const queryPick = debounce((value) => {}, 300); + + quickPick.onDidChangeValue(queryPick); + + quickPick.onDidAccept((i: any) => { + const item = quickPick.activeItems[0]; + if (item) { + alert('quickOpen'); + } + quickPick.hide(); + }); + quickPick.show(); + } +} diff --git a/stories/extensions/data-sync/index.tsx b/stories/extensions/data-sync/index.tsx index c8636b4cb..2aafa541e 100644 --- a/stories/extensions/data-sync/index.tsx +++ b/stories/extensions/data-sync/index.tsx @@ -1,6 +1,10 @@ +import React from 'react'; import molecule from 'mo'; import { IExtension } from 'mo/model/extension'; +import { QuickOpenAction } from '../actions/quickOpen'; +import { Button } from 'mo/components'; + const testItem = { id: '3333', icon: 'sync', @@ -19,6 +23,26 @@ export const ExtendsDataSync: IExtension = { }, 'File' ); + + const action = molecule.extension.registerAction(QuickOpenAction); + + molecule.sidebar.add({ + id: testItem.id, + render() { + return ( +
+

Data Sync SidePane

+ +
+ ); + }, + }); }, dispose() { From f36053e51995910758e136e83149bad95d5e21ae Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 17:10:30 +0800 Subject: [PATCH 05/14] test: registerAction should return a disposable instance --- src/services/__tests__/extensionService.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/__tests__/extensionService.test.ts b/src/services/__tests__/extensionService.test.ts index 9fb661df7..6994e25ce 100644 --- a/src/services/__tests__/extensionService.test.ts +++ b/src/services/__tests__/extensionService.test.ts @@ -114,11 +114,12 @@ describe('Test ExtensionService', () => { } run() {} } - instance.registerAction(MyAction); + const myAction = instance.registerAction(MyAction); const command = CommandsRegistry.getCommand(MyAction.ID); expect(command).not.toBeNull(); expect(command.id).toEqual(MyAction.ID); + expect(myAction.dispose).not.toBeUndefined(); }); test('The executeCommand should call the commandService.executeCommand function', () => { From 94a1f4011912f2790f5e0b4d515a28c6c7cf7d50 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Wed, 5 Jan 2022 15:56:21 +0800 Subject: [PATCH 06/14] feat: extrat the Action2 into separate file --- src/monaco/action.ts | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/monaco/action.ts diff --git a/src/monaco/action.ts b/src/monaco/action.ts new file mode 100644 index 000000000..8ff22dadd --- /dev/null +++ b/src/monaco/action.ts @@ -0,0 +1,89 @@ +import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle'; +import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey'; +import { KeybindingsRegistry } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry'; +import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; +import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; +import { + MenuRegistry, + MenuId, +} from 'monaco-editor/esm/vs/platform/actions/common/actions'; +import { IDisposable } from './common'; + +export abstract class Action2 { + static readonly ID: string; + constructor( + readonly desc: Readonly<{ + /** + * Specify visible in quick access view + */ + f1: boolean; + [key: string]: any; + }> + ) {} + abstract run(accessor: ServicesAccessor, ...args: any[]): any; +} + +export function registerAction2(Ctor: { new (): Action2 }): IDisposable { + const disposables = new DisposableStore(); + + const action = new Ctor(); + + const { f1, menu, keybinding, description, ...command } = action.desc; + + // command + disposables.add( + CommandsRegistry.registerCommand({ + id: command.id, + handler: (accessor, ...args) => action.run(accessor, ...args), + description: description, + }) + ); + + // menu + if (Array.isArray(menu)) { + disposables.add( + MenuRegistry.appendMenuItems( + menu.map((item) => ({ + id: item.id, + item: { command, ...item }, + })) + ) + ); + } else if (menu) { + disposables.add( + MenuRegistry.appendMenuItem(menu.id, { command, ...menu }) + ); + } + if (f1) { + disposables.add( + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command, + when: command.precondition, + }) + ); + disposables.add(MenuRegistry.addCommand(command)); + } + + // keybinding + if (Array.isArray(keybinding)) { + for (const item of keybinding) { + KeybindingsRegistry.registerKeybindingRule({ + ...item, + id: command.id, + when: command.precondition + ? ContextKeyExpr.and(command.precondition, item.when) + : item.when, + }); + } + } else if (keybinding) { + KeybindingsRegistry.registerKeybindingRule({ + ...keybinding, + id: command.id, + when: command.precondition + ? ContextKeyExpr.and(command.precondition, keybinding.when) + : keybinding.when, + }); + } + + return disposables; +} From 6e5f4824b812784f3040e53f01d5c15ac7755783 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:05:47 +0800 Subject: [PATCH 07/14] refactor: remove duplcate exports --- src/monaco/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/monaco/index.ts b/src/monaco/index.ts index 4ee3e6b96..7d6e13243 100644 --- a/src/monaco/index.ts +++ b/src/monaco/index.ts @@ -22,5 +22,3 @@ import 'monaco-editor/esm/vs/editor/standalone/browser/referenceSearch/standalon import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast'; export * from 'monaco-editor/esm/vs/editor/editor.api.js'; - -export { KeybindingWeight, Action2 } from './common'; From 18be37b976e4824eb850e2a084718ef603a90773 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:07:09 +0800 Subject: [PATCH 08/14] refactor: export Action2 from action.ts --- src/monaco/api.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/monaco/api.ts b/src/monaco/api.ts index 08c7cde63..2e600afce 100644 --- a/src/monaco/api.ts +++ b/src/monaco/api.ts @@ -1,3 +1,4 @@ export { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; export type { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput'; -export { KeybindingWeight, Action2 } from './common'; +export { KeybindingWeight } from './common'; +export { Action2 } from './action'; From 4c9ab751cf2b37ee7657b58b230378877f8404bf Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:10:30 +0800 Subject: [PATCH 09/14] refactor: update the imports --- src/controller/extension.ts | 2 +- src/i18n/selectLocaleAction.ts | 5 +- src/monaco/common.ts | 88 ------------------- src/monaco/quickAccessSettingsAction.ts | 10 ++- src/monaco/quickAccessViewAction.ts | 10 ++- src/monaco/quickCopyLineUp.ts | 6 +- src/monaco/quickCreateFile.ts | 11 +-- src/monaco/quickRedo.ts | 6 +- src/monaco/quickSelectAllAction.ts | 9 +- src/monaco/quickTogglePanelAction.ts | 10 ++- src/monaco/quickToggleSideBarAction.ts | 7 +- src/monaco/quickUndo.ts | 8 +- src/monaco/selectColorThemeAction.ts | 12 +-- .../__tests__/extensionService.test.ts | 9 +- src/services/extensionService.ts | 3 +- stories/extensions/actions/quickOpen.ts | 4 +- 16 files changed, 69 insertions(+), 131 deletions(-) diff --git a/src/controller/extension.ts b/src/controller/extension.ts index 7a38eef26..3c8e9c988 100644 --- a/src/controller/extension.ts +++ b/src/controller/extension.ts @@ -19,7 +19,7 @@ import { QuickCopyLineUp } from 'mo/monaco/quickCopyLineUp'; import { QuickUndo } from 'mo/monaco/quickUndo'; import { QuickRedo } from 'mo/monaco/quickRedo'; import { QuickCreateFile } from 'mo/monaco/quickCreateFile'; -import type { Action2 } from 'mo/monaco/common'; +import type { Action2 } from 'mo/monaco/action'; export interface IExtensionController extends Partial {} diff --git a/src/i18n/selectLocaleAction.ts b/src/i18n/selectLocaleAction.ts index 8d7cbee89..86ef613b6 100644 --- a/src/i18n/selectLocaleAction.ts +++ b/src/i18n/selectLocaleAction.ts @@ -1,14 +1,15 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; import { IQuickInputService, QuickPickInput, } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput'; import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; -import { container } from 'tsyringe'; -import { Action2 } from 'mo/monaco/common'; + import { localize } from './localize'; import { ILocaleService, LocaleService } from './localeService'; import { ILocale } from './localization'; +import { Action2 } from 'mo/monaco/action'; import { KeyCode, KeyMod } from 'mo/monaco'; import { constants } from 'mo/services/builtinService/const'; diff --git a/src/monaco/common.ts b/src/monaco/common.ts index 486132297..2f9dd4042 100644 --- a/src/monaco/common.ts +++ b/src/monaco/common.ts @@ -1,13 +1,4 @@ -import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle'; -import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey'; -import { KeybindingsRegistry } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry'; -import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; -import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; import { localize } from 'monaco-editor/esm/vs/nls'; -import { - MenuRegistry, - MenuId, -} from 'monaco-editor/esm/vs/platform/actions/common/actions'; export interface IDisposable { dispose(): void; @@ -41,82 +32,3 @@ export const CATEGORIES = { original: 'Developer', }, }; - -export abstract class Action2 { - static readonly ID: string; - constructor( - readonly desc: Readonly<{ - /** - * Specify visible in quick access view - */ - f1: boolean; - [key: string]: any; - }> - ) {} - abstract run(accessor: ServicesAccessor, ...args: any[]): any; -} - -export function registerAction2(Ctor: { new (): Action2 }): IDisposable { - const disposables = new DisposableStore(); - - const action = new Ctor(); - - const { f1, menu, keybinding, description, ...command } = action.desc; - - // command - disposables.add( - CommandsRegistry.registerCommand({ - id: command.id, - handler: (accessor, ...args) => action.run(accessor, ...args), - description: description, - }) - ); - - // menu - if (Array.isArray(menu)) { - disposables.add( - MenuRegistry.appendMenuItems( - menu.map((item) => ({ - id: item.id, - item: { command, ...item }, - })) - ) - ); - } else if (menu) { - disposables.add( - MenuRegistry.appendMenuItem(menu.id, { command, ...menu }) - ); - } - if (f1) { - disposables.add( - MenuRegistry.appendMenuItem(MenuId.CommandPalette, { - command, - when: command.precondition, - }) - ); - disposables.add(MenuRegistry.addCommand(command)); - } - - // keybinding - if (Array.isArray(keybinding)) { - for (const item of keybinding) { - KeybindingsRegistry.registerKeybindingRule({ - ...item, - id: command.id, - when: command.precondition - ? ContextKeyExpr.and(command.precondition, item.when) - : item.when, - }); - } - } else if (keybinding) { - KeybindingsRegistry.registerKeybindingRule({ - ...keybinding, - id: command.id, - when: command.precondition - ? ContextKeyExpr.and(command.precondition, keybinding.when) - : keybinding.when, - }); - } - - return disposables; -} diff --git a/src/monaco/quickAccessSettingsAction.ts b/src/monaco/quickAccessSettingsAction.ts index 3646542db..adcc886b0 100644 --- a/src/monaco/quickAccessSettingsAction.ts +++ b/src/monaco/quickAccessSettingsAction.ts @@ -1,12 +1,14 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; import { localize } from 'monaco-editor/esm/vs/nls'; -import { KeyMod, KeyCode } from 'mo/monaco'; import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; -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 { KeyMod, KeyCode } from 'mo/monaco'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; import { constants } from 'mo/services/builtinService/const'; +import { ISettingsService, SettingsService } from 'mo/services'; export class QuickAccessSettings extends Action2 { static readonly ID = constants.ACTION_QUICK_ACCESS_SETTINGS; diff --git a/src/monaco/quickAccessViewAction.ts b/src/monaco/quickAccessViewAction.ts index 7d4e0e18f..2fbd0598e 100644 --- a/src/monaco/quickAccessViewAction.ts +++ b/src/monaco/quickAccessViewAction.ts @@ -1,4 +1,6 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; + import { localize } from 'monaco-editor/esm/vs/nls'; import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle'; import { QuickCommandNLS } from 'monaco-editor/esm/vs/editor/common/standaloneStrings'; @@ -24,12 +26,12 @@ import { import { stripIcons } from 'monaco-editor/esm/vs/base/common/iconLabels'; import { KeyMod, KeyCode, editor as MonacoEditor } from 'mo/monaco'; -import { container } from 'tsyringe'; import { EditorService, IEditorService } from 'mo/services'; -import { Action2, KeybindingWeight } from './common'; -import { MonacoService } from './monacoService'; -import { registerQuickAccessProvider } from './quickAccessProvider'; import { constants } from 'mo/services/builtinService/const'; +import { Action2 } from 'mo/monaco/action'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { MonacoService } from 'mo/monaco/monacoService'; +import { registerQuickAccessProvider } from 'mo/monaco/quickAccessProvider'; export class CommandQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider { static PREFIX = '>'; diff --git a/src/monaco/quickCopyLineUp.ts b/src/monaco/quickCopyLineUp.ts index 8fc6730ba..99be6be98 100644 --- a/src/monaco/quickCopyLineUp.ts +++ b/src/monaco/quickCopyLineUp.ts @@ -1,10 +1,12 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; import { localize } from 'mo/i18n/localize'; import { KeyMod, KeyCode } from 'mo/monaco'; import { EditorService, IEditorService } from 'mo/services'; -import { container } from 'tsyringe'; -import { Action2, KeybindingWeight } from './common'; + import { constants } from 'mo/services/builtinService/const'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; export class QuickCopyLineUp extends Action2 { static readonly ID = constants.ACTION_QUICK_COPY_LINE_UP; diff --git a/src/monaco/quickCreateFile.ts b/src/monaco/quickCreateFile.ts index de91ddad1..7c1bf7a8c 100644 --- a/src/monaco/quickCreateFile.ts +++ b/src/monaco/quickCreateFile.ts @@ -1,15 +1,16 @@ import 'reflect-metadata'; -import { localize } from 'mo/i18n/localize'; -import { KeyMod, KeyCode } from 'mo/monaco'; -import { FileTypes } from 'mo/model'; +import { container } from 'tsyringe'; import { IFolderTreeController, FolderTreeController, } from 'mo/controller/explorer/folderTree'; -import { container } from 'tsyringe'; -import { Action2, KeybindingWeight } from './common'; +import { KeybindingWeight } from 'mo/monaco/common'; import { constants } from 'mo/services/builtinService/const'; +import { Action2 } from 'mo/monaco/action'; +import { localize } from 'mo/i18n/localize'; +import { KeyMod, KeyCode } from 'mo/monaco'; +import { FileTypes } from 'mo/model'; export class QuickCreateFile extends Action2 { static readonly ID = constants.ACTION_QUICK_CREATE_FILE; diff --git a/src/monaco/quickRedo.ts b/src/monaco/quickRedo.ts index 47f37a093..f9bd44f22 100644 --- a/src/monaco/quickRedo.ts +++ b/src/monaco/quickRedo.ts @@ -1,9 +1,11 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; + import { localize } from 'mo/i18n/localize'; import { KeyMod, KeyCode, Uri, editor as MonacoEditor } from 'mo/monaco'; import { EditorService, IEditorService } from 'mo/services'; -import { container } from 'tsyringe'; -import { Action2, KeybindingWeight } from './common'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; import { constants } from 'mo/services/builtinService/const'; export class QuickRedo extends Action2 { diff --git a/src/monaco/quickSelectAllAction.ts b/src/monaco/quickSelectAllAction.ts index 46a1af055..d83e3fe3f 100644 --- a/src/monaco/quickSelectAllAction.ts +++ b/src/monaco/quickSelectAllAction.ts @@ -1,11 +1,12 @@ import 'reflect-metadata'; -import { localize } from 'mo/i18n/localize'; - -import { KeyMod, KeyCode } from 'mo/monaco'; import { container } from 'tsyringe'; + +import { localize } from 'mo/i18n/localize'; import { EditorService, IEditorService } from 'mo/services'; -import { Action2, KeybindingWeight } from './common'; import { constants } from 'mo/services/builtinService/const'; +import { KeyMod, KeyCode } from 'mo/monaco'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; export class QuickSelectAllAction extends Action2 { static readonly ID = constants.ACTION_QUICK_SELECT_ALL; diff --git a/src/monaco/quickTogglePanelAction.ts b/src/monaco/quickTogglePanelAction.ts index dda90e363..27782083e 100644 --- a/src/monaco/quickTogglePanelAction.ts +++ b/src/monaco/quickTogglePanelAction.ts @@ -1,16 +1,20 @@ -import { Action2, CATEGORIES, KeybindingWeight } from './common'; +import 'reflect-metadata'; +import { container } from 'tsyringe'; import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; + import { localize } from 'mo/i18n/localize'; -import { KeyMod, KeyCode } from 'mo/monaco'; -import { container } from 'tsyringe'; import { ILayoutService, IMenuBarService, LayoutService, MenuBarService, } from 'mo/services'; + +import { KeyMod, KeyCode } from 'mo/monaco'; import { constants } from 'mo/services/builtinService/const'; +import { Action2 } from 'mo/monaco/action'; +import { CATEGORIES, KeybindingWeight } from 'mo/monaco/common'; export class QuickTogglePanelAction extends Action2 { static readonly ID = constants.MENU_VIEW_PANEL; diff --git a/src/monaco/quickToggleSideBarAction.ts b/src/monaco/quickToggleSideBarAction.ts index 13cb3d897..ac728aad5 100644 --- a/src/monaco/quickToggleSideBarAction.ts +++ b/src/monaco/quickToggleSideBarAction.ts @@ -1,9 +1,10 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation'; import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; + import { localize } from 'mo/i18n/localize'; import { KeyMod, KeyCode } from 'mo/monaco'; -import { Action2, CATEGORIES, KeybindingWeight } from './common'; -import { container } from 'tsyringe'; import { ActivityBarService, IActivityBarService, @@ -16,6 +17,8 @@ import { } from 'mo/services'; import { ID_SIDE_BAR } from 'mo/common/id'; import type { UniqueId } from 'mo/common/types'; +import { Action2 } from 'mo/monaco/action'; +import { CATEGORIES, KeybindingWeight } from 'mo/monaco/common'; export class CommandQuickSideBarViewAction extends Action2 { static readonly ID = ID_SIDE_BAR; diff --git a/src/monaco/quickUndo.ts b/src/monaco/quickUndo.ts index bbae1c350..50c8e8bf4 100644 --- a/src/monaco/quickUndo.ts +++ b/src/monaco/quickUndo.ts @@ -1,10 +1,12 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; + import { localize } from 'mo/i18n/localize'; -import { KeyMod, KeyCode, Uri, editor as MonacoEditor } from 'mo/monaco'; import { EditorService, IEditorService } from 'mo/services'; -import { container } from 'tsyringe'; -import { Action2, KeybindingWeight } from './common'; import { constants } from 'mo/services/builtinService/const'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; +import { KeyMod, KeyCode, Uri, editor as MonacoEditor } from 'mo/monaco'; export class QuickUndo extends Action2 { static readonly ID = constants.ACTION_QUICK_UNDO; diff --git a/src/monaco/selectColorThemeAction.ts b/src/monaco/selectColorThemeAction.ts index 2f7cb0f2b..7d7149dc0 100644 --- a/src/monaco/selectColorThemeAction.ts +++ b/src/monaco/selectColorThemeAction.ts @@ -1,17 +1,19 @@ import 'reflect-metadata'; +import { container } from 'tsyringe'; import { localize } from 'monaco-editor/esm/vs/nls'; import { IQuickInputService, QuickPickInput, } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput'; -import { IColorTheme } from 'mo/model/colorTheme'; -import { KeyMod, KeyCode } from 'mo/monaco'; import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; -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 { KeyMod, KeyCode } from 'mo/monaco'; +import { Action2 } from 'mo/monaco/action'; +import { KeybindingWeight } from 'mo/monaco/common'; +import { IColorTheme } from 'mo/model/colorTheme'; import { constants } from 'mo/services/builtinService/const'; +import { ColorThemeService, IColorThemeService } from 'mo/services'; export class SelectColorThemeAction extends Action2 { static readonly ID = constants.ACTION_SELECT_THEME; diff --git a/src/services/__tests__/extensionService.test.ts b/src/services/__tests__/extensionService.test.ts index 6994e25ce..5d5547176 100644 --- a/src/services/__tests__/extensionService.test.ts +++ b/src/services/__tests__/extensionService.test.ts @@ -1,12 +1,13 @@ import 'reflect-metadata'; +import { cloneDeep } from 'lodash'; import { container } from 'tsyringe'; -import { ExtensionService } from '../extensionService'; +import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; + import { defaultExtensions } from 'mo/extensions'; import { IContribute, IExtension } from 'mo/model'; -import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; -import { Action2 } from 'mo/monaco/common'; +import { Action2 } from 'mo/monaco/action'; import logger from 'mo/common/logger'; -import { cloneDeep } from 'lodash'; +import { ExtensionService } from '../extensionService'; describe('Test ExtensionService', () => { const instance = container.resolve(ExtensionService); diff --git a/src/services/extensionService.ts b/src/services/extensionService.ts index 243da8718..04731c4cb 100644 --- a/src/services/extensionService.ts +++ b/src/services/extensionService.ts @@ -9,11 +9,12 @@ import { ColorThemeService, IColorThemeService, } from './theme/colorThemeService'; -import { Action2, IDisposable, registerAction2 } from 'mo/monaco/common'; +import { IDisposable } from 'mo/monaco/common'; import { IMonacoService, MonacoService } from 'mo/monaco/monacoService'; import { searchById } from 'mo/common/utils'; import type { UniqueId } from 'mo/common/types'; +import { Action2, registerAction2 } from 'mo/monaco/action'; export interface IExtensionService { /** diff --git a/stories/extensions/actions/quickOpen.ts b/stories/extensions/actions/quickOpen.ts index ee0118557..a187b38ee 100644 --- a/stories/extensions/actions/quickOpen.ts +++ b/stories/extensions/actions/quickOpen.ts @@ -2,7 +2,9 @@ import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/com import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes'; import { debounce } from 'lodash'; -import { Action2, KeybindingWeight, KeyCode, KeyMod } from 'mo/monaco'; +import { KeyCode, KeyMod } from 'mo/monaco'; +import { Action2 } from 'mo/monaco/action'; +import { KeybindingWeight } from 'mo/monaco/common'; export class QuickOpenAction extends Action2 { static readonly ID = 'QuickOpenFile'; From 75ee6f9685589db4defac7e8b9bc187a2b159b53 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:12:07 +0800 Subject: [PATCH 10/14] style: prettify codes --- stories/extensions/test/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stories/extensions/test/index.tsx b/stories/extensions/test/index.tsx index 7a5bb5924..085065dbf 100644 --- a/stories/extensions/test/index.tsx +++ b/stories/extensions/test/index.tsx @@ -8,7 +8,7 @@ import { randomId } from 'mo/common/utils'; export const ExtendsTestPane: IExtension = { id: 'ExtendsTestPane', - name: 'Test Pane ', + name: 'Test Pane', dispose() {}, activate() { const TEST_PANE_ID = 'ActivityBarTestPane'; From 96d68a20da1a31064640643763dfcef850c01c93 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:20:31 +0800 Subject: [PATCH 11/14] test: ignore the stories path --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 922df27f1..09b63a774 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,7 +11,7 @@ module.exports = { '**/__tests__/**/(*.)+(spec|test).[jt]s?(x)', '**/test/**/(*.)+(spec|test).[jt]s?(x)', ], - testPathIgnorePatterns: ['/node_modules/', 'esm', 'umd'], + testPathIgnorePatterns: ['/node_modules/', 'esm', 'umd', 'stories'], // The directory where Jest should output its coverage files coverageDirectory: 'coverage', transformIgnorePatterns: ['node_modules/(?!(monaco-editor|.*dnd.*)/)'], From 9eace295cee925f4ba479c8d62bc44cda19ff2fd Mon Sep 17 00:00:00 2001 From: xiaowei Date: Mon, 10 Jan 2022 16:43:30 +0800 Subject: [PATCH 12/14] test: unit test for registerAction2 --- src/monaco/__tests__/action.test.ts | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/monaco/__tests__/action.test.ts diff --git a/src/monaco/__tests__/action.test.ts b/src/monaco/__tests__/action.test.ts new file mode 100644 index 000000000..b4d184363 --- /dev/null +++ b/src/monaco/__tests__/action.test.ts @@ -0,0 +1,36 @@ +import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; + +import { Action2, registerAction2 } from 'mo/monaco/action'; +import { KeybindingWeight } from '../common'; + +describe('Test monaco action', () => { + test('Register an Action via Action2 class', () => { + const mockRun = jest.fn(); + class Test extends Action2 { + static readonly ID = 'TestAction'; + static readonly LABEL = 'Test Action2'; + constructor() { + super({ + id: Test.ID, + label: Test.LABEL, + title: Test.LABEL, + alias: Test.LABEL, + precondition: undefined, + f1: true, // Whether show the QuickOpenFile in Command Palette + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + when: undefined, + // eslint-disable-next-line new-cap + }, + }); + } + run = mockRun; + } + const testAction = registerAction2(Test); + const command = CommandsRegistry.getCommand(Test.ID); + command.handler(); + expect(testAction.dispose).not.toBeUndefined(); + expect(command).not.toBeUndefined(); + expect(mockRun).toBeCalled(); + }); +}); From 7e4ca59a9608dc45b2de96a0566068e47387ae7a Mon Sep 17 00:00:00 2001 From: xiaowei Date: Tue, 11 Jan 2022 15:34:36 +0800 Subject: [PATCH 13/14] test: unit tests for menu, keybinding branchs --- src/monaco/__tests__/action.test.ts | 66 +++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/monaco/__tests__/action.test.ts b/src/monaco/__tests__/action.test.ts index b4d184363..9c33f2749 100644 --- a/src/monaco/__tests__/action.test.ts +++ b/src/monaco/__tests__/action.test.ts @@ -1,4 +1,6 @@ import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands'; +import { MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions'; +import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey'; import { Action2, registerAction2 } from 'mo/monaco/action'; import { KeybindingWeight } from '../common'; @@ -15,12 +17,15 @@ describe('Test monaco action', () => { label: Test.LABEL, title: Test.LABEL, alias: Test.LABEL, - precondition: undefined, + precondition: true, f1: true, // Whether show the QuickOpenFile in Command Palette keybinding: { weight: KeybindingWeight.WorkbenchContrib, - when: undefined, - // eslint-disable-next-line new-cap + when: ContextKeyExpr.true, + }, + menu: { + id: 'testMenu', + name: 'test', }, }); } @@ -32,5 +37,60 @@ describe('Test monaco action', () => { expect(testAction.dispose).not.toBeUndefined(); expect(command).not.toBeUndefined(); expect(mockRun).toBeCalled(); + testAction.dispose(); + }); + + test('Register Menus via Action2 class', () => { + class Test extends Action2 { + static readonly ID = 'TestMenu'; + constructor() { + super({ + id: Test.ID, + precondition: true, + f1: false, // Whether show the QuickOpenFile in Command Palette + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.true, + }, + menu: [ + { + id: 'testMenu1', + name: 'test1', + }, + { + id: 'testMenu2', + name: 'test2', + }, + ], + }); + } + run() {} + } + registerAction2(Test); + const menu = MenuRegistry.getMenuItems('testMenu1'); + expect(menu.length).toBe(1); + }); + + test('Register Keybindings via Action2 class', () => { + class Test extends Action2 { + static readonly ID = 'testKeybinding'; + constructor() { + super({ + id: Test.ID, + precondition: false, + f1: true, // Whether show the QuickOpenFile in Command Palette + keybinding: [ + { + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.true, + }, + ], + }); + } + run() {} + } + registerAction2(Test); + const command = CommandsRegistry.getCommand(Test.ID); + expect(command).not.toBeUndefined(); }); }); From b2684e1479aabb56784c3b94c72d363b9a19038e Mon Sep 17 00:00:00 2001 From: xiaowei Date: Tue, 11 Jan 2022 15:47:53 +0800 Subject: [PATCH 14/14] chore(codecov): ignore website and stories paths --- codecov.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..9ee3e78de --- /dev/null +++ b/codecov.yml @@ -0,0 +1,3 @@ +ignore: + - 'website' + - 'stories'