Skip to content

Commit

Permalink
feat(menubar): add menu bar methods to service and support shortcut k…
Browse files Browse the repository at this point in the history
…eys (#298)

* feat: menu bar add new file function

* feat: add encapsulated event state automata

* feat: add menu bar action to menu bar controller

* feat: define menu function and export operation id

* feat: register view shortcut

* feat: add key code string constant

* feat: register the view method in the editor service

* feat: register select all keyboard listener class

* feat: register copy line up keyboard listener class

* refactor: register undo and redo to keybinding

* perf: extract function to keybinding

* feat: add new file to keybinding

* feat: use monaco service to get menu functions

* feat: register menubar onSelect to subscribers

* refactor: update the MenuBarService (#292)

* refactor: remove addRootMenu method, and rename initMenu to initMenus

* docs: add comments for the IMenuBarService interface

* perf: move create file or folder function in service

* feat: add new file to keybinding

* feat: register menubar onSelect to subscribers

* fix: increase call rigor

* feat: add story of open any file on disk

* feat: support file highlighting

* feat: register the view method in the editor service

* perf: extract function to keybinding

* feat: add new file to keybinding

* perf: better type description

Co-authored-by: Ziv <[email protected]>
  • Loading branch information
ProfBramble and wewoor authored Aug 5, 2021
1 parent fa5bae6 commit 3370b0f
Show file tree
Hide file tree
Showing 13 changed files with 378 additions and 75 deletions.
19 changes: 0 additions & 19 deletions src/controller/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import {
EDITOR_MENU_SHOW_OPENEDITORS,
EDITOR_MENU_SPILIT,
} from 'mo/model/workbench/editor';
import { undoRedoMenu } from 'mo/model/workbench/menuBar';
import { Controller } from 'mo/react/controller';

import { IMenuItemProps } from 'mo/components/menu';
import { STATUS_EDITOR_INFO } from 'mo/model/workbench/statusBar';
import { IMonacoEditorProps } from 'mo/components/monaco';
Expand Down Expand Up @@ -161,7 +159,6 @@ export class EditorController extends Controller implements IEditorController {
if (!editorInstance) return;

this.initEditorEvents(editorInstance, groupId);
this.registerActions(editorInstance);
this.editorService.updateGroup(groupId, {
editorInstance: editorInstance,
});
Expand All @@ -178,22 +175,6 @@ export class EditorController extends Controller implements IEditorController {
);
};

// TODO: Remove the below action register ?, because of the monaco Editor have integrated the undo/redo action
private registerActions = (editorInstance) => {
undoRedoMenu.forEach(({ id, label }) => {
editorInstance?.addAction({
id,
label,
run: () => {
editorInstance!.focus();
if (!document.execCommand(id)) {
editorInstance?.getModel()?.[id]();
}
},
});
});
};

public onClickActions = (action: IEditorActionsProps) => {
const { current } = this.editorService.getState();
if (!current) return;
Expand Down
5 changes: 3 additions & 2 deletions src/controller/explorer/folderTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import {
OPEN_TO_SIDE_COMMAND_ID,
FolderTreeEvent,
FileTypes,
FileType,
} from 'mo/model';
import { FolderTreeService, IFolderTreeService } from 'mo/services';

export interface IFolderTreeController {
readonly createTreeNode: (type: keyof typeof FileTypes) => void;
readonly createTreeNode: (type: FileType) => void;
readonly onClickContextMenu: (
contextMenu: IMenuItemProps,
treeNode: ITreeNodeItemProps
Expand Down Expand Up @@ -68,7 +69,7 @@ export class FolderTreeController
return menus;
};

public createTreeNode = (type: keyof typeof FileTypes) => {
public createTreeNode = (type: FileType) => {
const folderTreeState = this.folderTreeService.getState();
const { data, current } = folderTreeState?.folderTree || {};
// The current selected node id or the first root node
Expand Down
88 changes: 56 additions & 32 deletions src/controller/menuBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ import 'reflect-metadata';
import { container, singleton } from 'tsyringe';
import { IActivityBarItem, IMenuBarItem } from 'mo/model';
import {
MENU_FILE_REDO,
MENU_FILE_UNDO,
ACTION_QUICK_SELECT_ALL,
ACTION_QUICK_COPY_LINE_UP,
ACTION_QUICK_COMMAND,
ACTION_QUICK_UNDO,
ACTION_QUICK_REDO,
ACTION_QUICK_CREATE_FILE,
} from 'mo/model/keybinding';
import {
MENU_QUICK_COMMAND,
MENU_VIEW_ACTIVITYBAR,
MENU_VIEW_MENUBAR,
MENU_VIEW_PANEL,
MENU_VIEW_STATUSBAR,
} from 'mo/model/workbench/menuBar';
import { MenuBarEvent } from 'mo/model/workbench/menuBar';
import { Controller } from 'mo/react/controller';
import {
EditorService,
IEditorService,
IMenuBarService,
ILayoutService,
MenuBarService,
Expand All @@ -36,52 +42,58 @@ export interface IMenuBarController {
export class MenuBarController
extends Controller
implements IMenuBarController {
private readonly editorService: IEditorService;
private readonly menuBarService: IMenuBarService;
private readonly layoutService: ILayoutService;
private readonly monacoService: IMonacoService;
private automation = {
[ACTION_QUICK_CREATE_FILE]: () => this.createFile(),
[ACTION_QUICK_UNDO]: () => this.undo(),
[ACTION_QUICK_REDO]: () => this.redo(),
[ACTION_QUICK_SELECT_ALL]: () => this.selectAll(),
[ACTION_QUICK_COPY_LINE_UP]: () => this.copyLineUp(),
[MENU_VIEW_ACTIVITYBAR]: () => this.updateActivityBar(),
[MENU_VIEW_MENUBAR]: () => this.updateMenuBar(),
[MENU_VIEW_STATUSBAR]: () => this.updateStatusBar(),
[MENU_QUICK_COMMAND]: () => this.gotoQuickCommand(),
[ID_SIDE_BAR]: () => this.updateSideBar(),
[MENU_VIEW_PANEL]: () => this.updatePanel(),
};

constructor() {
super();
this.editorService = container.resolve(EditorService);
this.menuBarService = container.resolve(MenuBarService);
this.layoutService = container.resolve(LayoutService);
this.monacoService = container.resolve(MonacoService);
}

public readonly onClick = (event: React.MouseEvent, item: IMenuBarItem) => {
const menuId = item.id;
switch (menuId) {
case MENU_FILE_UNDO:
this.undo();
break;
case MENU_FILE_REDO:
this.redo();
break;
case MENU_VIEW_ACTIVITYBAR:
this.updateActivityBar();
break;
case MENU_VIEW_MENUBAR:
this.updateMenuBar();
break;
case MENU_VIEW_STATUSBAR:
this.updateStatusBar();
break;
case ID_SIDE_BAR:
this.updateSideBar();
break;
case MENU_VIEW_PANEL:
this.updatePanel();
break;
}
const menuId = item.id || '';

/**
* TODO: Two issues remain to be addressed
* 1、the default event is executed twice
* 2、we have no way of knowing whether user-defined events are executed internally
*/
this.emit(MenuBarEvent.onSelect, menuId);
this.automation[menuId]?.();
};

public createFile = () => {
this.monacoService.commandService.executeCommand(
ACTION_QUICK_CREATE_FILE
);
};

public undo = () => {
this.editorService.editorInstance?.getAction('undo').run();
this.monacoService.commandService.executeCommand(ACTION_QUICK_UNDO);
};

public redo = () => {
this.editorService.editorInstance?.getAction('redo').run();
this.monacoService.commandService.executeCommand(ACTION_QUICK_REDO);
};

public gotoQuickCommand = () => {
this.monacoService.commandService.executeCommand(ACTION_QUICK_COMMAND);
};

public updateActivityBar = () => {
Expand All @@ -94,6 +106,18 @@ export class MenuBarController
});
};

public selectAll = () => {
this.monacoService.commandService.executeCommand(
ACTION_QUICK_SELECT_ALL
);
};

public copyLineUp = () => {
this.monacoService.commandService.executeCommand(
ACTION_QUICK_COPY_LINE_UP
);
};

public updateMenuBar = () => {
this.layoutService.setMenuBarHidden();
const {
Expand Down
10 changes: 10 additions & 0 deletions src/extensions/keybinding/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { CommandQuickAccessViewAction } from 'mo/monaco/quickAccessViewAction';
import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction';
import { CommandQuickSideBarViewAction } from 'mo/monaco/quickToggleSideBarAction';
import { QuickTogglePanelAction } from 'mo/monaco/quickTogglePanelAction';
import { QuickSelectAllAction } from 'mo/monaco/quickSelectAllAction';
import { QuickCopyLineUp } from 'mo/monaco/quickCopyLineUp';
import { QuickRedo } from 'mo/monaco/quickRedo';
import { QuickUndo } from 'mo/monaco/quickUndo';
import { QuickCreateFile } from 'mo/monaco/quickCreateFile';

export const ExtendsKeybinding: IExtension = {
activate(extensionCtx: IExtensionService) {
Expand All @@ -15,5 +20,10 @@ export const ExtendsKeybinding: IExtension = {
extensionCtx.registerAction(SelectLocaleAction);
extensionCtx.registerAction(CommandQuickSideBarViewAction);
extensionCtx.registerAction(QuickTogglePanelAction);
extensionCtx.registerAction(QuickSelectAllAction);
extensionCtx.registerAction(QuickCopyLineUp);
extensionCtx.registerAction(QuickUndo);
extensionCtx.registerAction(QuickRedo);
extensionCtx.registerAction(QuickCreateFile);
},
};
11 changes: 10 additions & 1 deletion src/model/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export const KeyCodeString: Partial<{ [key in KeyCode]: string }> = {
[KeyCode.Backspace]: '⌫',
[KeyCode.Tab]: '⇥',
[KeyCode.Enter]: '↩︎',
[KeyCode.PageUp]: '↑',
[KeyCode.PageDown]: '↓',
[KeyCode.KEY_0]: '0',
[KeyCode.KEY_1]: '1',
[KeyCode.KEY_2]: '2',
Expand Down Expand Up @@ -62,8 +64,15 @@ export interface ISimpleKeybinding {
keyCode: KeyCode;
}

export const ACTION_QUICK_COMMAND = 'editor.action.quickCommand';
export const ACTION_QUICK_SELECT_ALL = 'editor.action.quickSelectAll';
export const ACTION_QUICK_COPY_LINE_UP = 'editor.action.copyLinesUpAction';
export const ACTION_QUICK_UNDO = 'editor.action.undo';
export const ACTION_QUICK_REDO = 'editor.action.redo';

export const ACTION_QUICK_CREATE_FILE = 'workbench.action.quickCreateFile';
export const ACTION_QUICK_CREATE_FOLDER = 'workbench.action.quickCreateFolder';
export const ACTION_QUICK_ACCESS_SETTINGS =
'workbench.action.quickAccessSettings';
export const ACTION_QUICK_COMMAND = 'editor.action.quickCommand';
export const ACTION_SELECT_THEME = 'workbench.action.selectTheme';
export const ACTION_SELECT_LOCALE = 'workbench.action.selectLocale';
39 changes: 19 additions & 20 deletions src/model/workbench/menuBar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as React from 'react';
import { localize } from 'mo/i18n/localize';
import { ID_SIDE_BAR } from 'mo/common/id';
import {
ACTION_QUICK_SELECT_ALL,
ACTION_QUICK_COPY_LINE_UP,
ACTION_QUICK_UNDO,
ACTION_QUICK_REDO,
ACTION_QUICK_CREATE_FILE,
} from 'mo/model/keybinding';

/**
* The activity bar event definition
Expand All @@ -9,7 +16,7 @@ export enum MenuBarEvent {
/**
* Selected an activity bar
*/
onClick = 'menuBar.onClick',
onSelect = 'menuBar.onSelect',
}

export interface IMenuBarItem {
Expand All @@ -23,8 +30,10 @@ export interface IMenuBar {
data?: IMenuBarItem[];
}

export const MENU_FILE_UNDO = 'undo';
export const MENU_FILE_REDO = 'redo';
export const MENU_FILE_OPEN = 'openFile';

export const MENU_QUICK_COMMAND = 'editor.action.quickCommand';

export const MENU_VIEW_MENUBAR = 'workbench.action.showMenuBar';
export const MENU_VIEW_ACTIVITYBAR = 'workbench.action.showActivityBar';
export const MENU_VIEW_STATUSBAR = 'workbench.action.showStatusBar';
Expand All @@ -37,11 +46,11 @@ export function builtInMenuBarData() {
name: localize('menu.file', 'File'),
data: [
{
id: 'New File',
id: ACTION_QUICK_CREATE_FILE,
name: localize('menu.newFile', 'New File'),
},
{
id: 'OpenFile',
id: MENU_FILE_OPEN,
name: localize('menu.open', 'Open'),
},
],
Expand All @@ -51,11 +60,11 @@ export function builtInMenuBarData() {
name: localize('menu.edit', 'Edit'),
data: [
{
id: MENU_FILE_UNDO,
id: ACTION_QUICK_UNDO,
name: localize('menu.undo', 'Undo'),
},
{
id: MENU_FILE_REDO,
id: ACTION_QUICK_REDO,
name: localize('menu.redo', 'Redo'),
},
],
Expand All @@ -65,11 +74,11 @@ export function builtInMenuBarData() {
name: localize('menu.selection', 'Selection'),
data: [
{
id: 'SelectAll',
id: ACTION_QUICK_SELECT_ALL,
name: localize('menu.selectAll', 'Select All'),
},
{
id: 'CopyLineUp',
id: ACTION_QUICK_COPY_LINE_UP,
name: localize('menu.copyLineUp', 'Copy Line Up'),
},
],
Expand All @@ -79,7 +88,7 @@ export function builtInMenuBarData() {
name: localize('menu.view', 'View'),
data: [
{
id: 'Command Palette',
id: MENU_QUICK_COMMAND,
name: localize('menu.commandPalette', 'Command Palette'),
},
{
Expand Down Expand Up @@ -148,16 +157,6 @@ export function builtInMenuBarData() {
];
}

export const undoRedoMenu = [
{
id: MENU_FILE_UNDO,
label: localize('menu.undo', 'Undo'),
},
{
id: MENU_FILE_REDO,
label: localize('menu.redo', 'Redo'),
},
];
export class MenuBarModel implements IMenuBar {
public data: IMenuBarItem[];

Expand Down
40 changes: 40 additions & 0 deletions src/monaco/quickCopyLineUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'reflect-metadata';
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 { ACTION_QUICK_COPY_LINE_UP } from 'mo/model/keybinding';

export class QuickCopyLineUp extends Action2 {
static readonly ID = ACTION_QUICK_COPY_LINE_UP;
static readonly LABEL = localize('menu.copyLineUp', 'Copy Line Up');
static readonly DESC = 'Copy Line Up';
private readonly editorService: IEditorService;

constructor() {
super({
id: QuickCopyLineUp.ID,
title: {
value: QuickCopyLineUp.LABEL,
original: QuickCopyLineUp.DESC,
},
label: QuickCopyLineUp.LABEL,
alias: QuickCopyLineUp.DESC,
f1: true,
keybinding: {
when: undefined,
weight: KeybindingWeight.WorkbenchContrib,
// eslint-disable-next-line new-cap
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.PageUp,
},
});
this.editorService = container.resolve(EditorService);
}

run() {
this.editorService.editorInstance
?.getAction(ACTION_QUICK_COPY_LINE_UP)
.run();
}
}
Loading

0 comments on commit 3370b0f

Please sign in to comment.