Skip to content

Commit bfdf0bb

Browse files
authored
feat: support to dispose the Action (#599)
1 parent 08fd30f commit bfdf0bb

24 files changed

+351
-145
lines changed

codecov.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ignore:
2+
- 'website'
3+
- 'stories'

jest.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = {
1111
'**/__tests__/**/(*.)+(spec|test).[jt]s?(x)',
1212
'**/test/**/(*.)+(spec|test).[jt]s?(x)',
1313
],
14-
testPathIgnorePatterns: ['/node_modules/', 'esm', 'umd'],
14+
testPathIgnorePatterns: ['/node_modules/', 'esm', 'umd', 'stories'],
1515
// The directory where Jest should output its coverage files
1616
coverageDirectory: 'coverage',
1717
transformIgnorePatterns: ['node_modules/(?!(monaco-editor|.*dnd.*)/)'],

src/controller/extension.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { QuickCopyLineUp } from 'mo/monaco/quickCopyLineUp';
1919
import { QuickUndo } from 'mo/monaco/quickUndo';
2020
import { QuickRedo } from 'mo/monaco/quickRedo';
2121
import { QuickCreateFile } from 'mo/monaco/quickCreateFile';
22-
import type { Action2 } from 'mo/monaco/common';
22+
import type { Action2 } from 'mo/monaco/action';
2323

2424
export interface IExtensionController extends Partial<Controller> {}
2525

src/i18n/selectLocaleAction.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import 'reflect-metadata';
2+
import { container } from 'tsyringe';
23
import {
34
IQuickInputService,
45
QuickPickInput,
56
} from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput';
67
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
7-
import { container } from 'tsyringe';
8-
import { Action2 } from 'mo/monaco/common';
8+
99
import { localize } from './localize';
1010
import { ILocaleService, LocaleService } from './localeService';
1111
import { ILocale } from './localization';
12+
import { Action2 } from 'mo/monaco/action';
1213
import { KeyCode, KeyMod } from 'mo/monaco';
1314
import { constants } from 'mo/services/builtinService/const';
1415

src/monaco/__tests__/action.test.ts

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands';
2+
import { MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions';
3+
import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey';
4+
5+
import { Action2, registerAction2 } from 'mo/monaco/action';
6+
import { KeybindingWeight } from '../common';
7+
8+
describe('Test monaco action', () => {
9+
test('Register an Action via Action2 class', () => {
10+
const mockRun = jest.fn();
11+
class Test extends Action2 {
12+
static readonly ID = 'TestAction';
13+
static readonly LABEL = 'Test Action2';
14+
constructor() {
15+
super({
16+
id: Test.ID,
17+
label: Test.LABEL,
18+
title: Test.LABEL,
19+
alias: Test.LABEL,
20+
precondition: true,
21+
f1: true, // Whether show the QuickOpenFile in Command Palette
22+
keybinding: {
23+
weight: KeybindingWeight.WorkbenchContrib,
24+
when: ContextKeyExpr.true,
25+
},
26+
menu: {
27+
id: 'testMenu',
28+
name: 'test',
29+
},
30+
});
31+
}
32+
run = mockRun;
33+
}
34+
const testAction = registerAction2(Test);
35+
const command = CommandsRegistry.getCommand(Test.ID);
36+
command.handler();
37+
expect(testAction.dispose).not.toBeUndefined();
38+
expect(command).not.toBeUndefined();
39+
expect(mockRun).toBeCalled();
40+
testAction.dispose();
41+
});
42+
43+
test('Register Menus via Action2 class', () => {
44+
class Test extends Action2 {
45+
static readonly ID = 'TestMenu';
46+
constructor() {
47+
super({
48+
id: Test.ID,
49+
precondition: true,
50+
f1: false, // Whether show the QuickOpenFile in Command Palette
51+
keybinding: {
52+
weight: KeybindingWeight.WorkbenchContrib,
53+
when: ContextKeyExpr.true,
54+
},
55+
menu: [
56+
{
57+
id: 'testMenu1',
58+
name: 'test1',
59+
},
60+
{
61+
id: 'testMenu2',
62+
name: 'test2',
63+
},
64+
],
65+
});
66+
}
67+
run() {}
68+
}
69+
registerAction2(Test);
70+
const menu = MenuRegistry.getMenuItems('testMenu1');
71+
expect(menu.length).toBe(1);
72+
});
73+
74+
test('Register Keybindings via Action2 class', () => {
75+
class Test extends Action2 {
76+
static readonly ID = 'testKeybinding';
77+
constructor() {
78+
super({
79+
id: Test.ID,
80+
precondition: false,
81+
f1: true, // Whether show the QuickOpenFile in Command Palette
82+
keybinding: [
83+
{
84+
weight: KeybindingWeight.WorkbenchContrib,
85+
when: ContextKeyExpr.true,
86+
},
87+
],
88+
});
89+
}
90+
run() {}
91+
}
92+
registerAction2(Test);
93+
const command = CommandsRegistry.getCommand(Test.ID);
94+
expect(command).not.toBeUndefined();
95+
});
96+
});

src/monaco/action.ts

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle';
2+
import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey';
3+
import { KeybindingsRegistry } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry';
4+
import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands';
5+
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
6+
import {
7+
MenuRegistry,
8+
MenuId,
9+
} from 'monaco-editor/esm/vs/platform/actions/common/actions';
10+
import { IDisposable } from './common';
11+
12+
export abstract class Action2 {
13+
static readonly ID: string;
14+
constructor(
15+
readonly desc: Readonly<{
16+
/**
17+
* Specify visible in quick access view
18+
*/
19+
f1: boolean;
20+
[key: string]: any;
21+
}>
22+
) {}
23+
abstract run(accessor: ServicesAccessor, ...args: any[]): any;
24+
}
25+
26+
export function registerAction2(Ctor: { new (): Action2 }): IDisposable {
27+
const disposables = new DisposableStore();
28+
29+
const action = new Ctor();
30+
31+
const { f1, menu, keybinding, description, ...command } = action.desc;
32+
33+
// command
34+
disposables.add(
35+
CommandsRegistry.registerCommand({
36+
id: command.id,
37+
handler: (accessor, ...args) => action.run(accessor, ...args),
38+
description: description,
39+
})
40+
);
41+
42+
// menu
43+
if (Array.isArray(menu)) {
44+
disposables.add(
45+
MenuRegistry.appendMenuItems(
46+
menu.map((item) => ({
47+
id: item.id,
48+
item: { command, ...item },
49+
}))
50+
)
51+
);
52+
} else if (menu) {
53+
disposables.add(
54+
MenuRegistry.appendMenuItem(menu.id, { command, ...menu })
55+
);
56+
}
57+
if (f1) {
58+
disposables.add(
59+
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
60+
command,
61+
when: command.precondition,
62+
})
63+
);
64+
disposables.add(MenuRegistry.addCommand(command));
65+
}
66+
67+
// keybinding
68+
if (Array.isArray(keybinding)) {
69+
for (const item of keybinding) {
70+
KeybindingsRegistry.registerKeybindingRule({
71+
...item,
72+
id: command.id,
73+
when: command.precondition
74+
? ContextKeyExpr.and(command.precondition, item.when)
75+
: item.when,
76+
});
77+
}
78+
} else if (keybinding) {
79+
KeybindingsRegistry.registerKeybindingRule({
80+
...keybinding,
81+
id: command.id,
82+
when: command.precondition
83+
? ContextKeyExpr.and(command.precondition, keybinding.when)
84+
: keybinding.when,
85+
});
86+
}
87+
88+
return disposables;
89+
}

src/monaco/api.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes';
22
export type { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput';
3-
export { KeybindingWeight, Action2 } from './common';
3+
export { KeybindingWeight } from './common';
4+
export { Action2 } from './action';

src/monaco/common.ts

+4-90
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1-
import {
2-
IDisposable,
3-
DisposableStore,
4-
} from 'monaco-editor/esm/vs/base/common/lifecycle';
5-
import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey';
6-
import { KeybindingsRegistry } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry';
7-
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
8-
import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands';
91
import { localize } from 'monaco-editor/esm/vs/nls';
10-
import {
11-
MenuRegistry,
12-
MenuId,
13-
} from 'monaco-editor/esm/vs/platform/actions/common/actions';
2+
3+
export interface IDisposable {
4+
dispose(): void;
5+
}
146

157
export enum KeybindingWeight {
168
EditorCore = 0,
@@ -40,81 +32,3 @@ export const CATEGORIES = {
4032
original: 'Developer',
4133
},
4234
};
43-
44-
export abstract class Action2 {
45-
constructor(
46-
readonly desc: Readonly<{
47-
/**
48-
* Specify visible in quick access view
49-
*/
50-
f1: boolean;
51-
[key: string]: any;
52-
}>
53-
) {}
54-
abstract run(accessor: ServicesAccessor, ...args: any[]): any;
55-
}
56-
57-
export function registerAction2(ctor: { new (): Action2 }): IDisposable {
58-
const disposables = new DisposableStore();
59-
// eslint-disable-next-line new-cap
60-
const action = new ctor();
61-
62-
const { f1, menu, keybinding, description, ...command } = action.desc;
63-
64-
// command
65-
disposables.add(
66-
CommandsRegistry.registerCommand({
67-
id: command.id,
68-
handler: (accessor, ...args) => action.run(accessor, ...args),
69-
description: description,
70-
})
71-
);
72-
73-
// menu
74-
if (Array.isArray(menu)) {
75-
disposables.add(
76-
MenuRegistry.appendMenuItems(
77-
menu.map((item) => ({
78-
id: item.id,
79-
item: { command, ...item },
80-
}))
81-
)
82-
);
83-
} else if (menu) {
84-
disposables.add(
85-
MenuRegistry.appendMenuItem(menu.id, { command, ...menu })
86-
);
87-
}
88-
if (f1) {
89-
disposables.add(
90-
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
91-
command,
92-
when: command.precondition,
93-
})
94-
);
95-
disposables.add(MenuRegistry.addCommand(command));
96-
}
97-
98-
// keybinding
99-
if (Array.isArray(keybinding)) {
100-
for (const item of keybinding) {
101-
KeybindingsRegistry.registerKeybindingRule({
102-
...item,
103-
id: command.id,
104-
when: command.precondition
105-
? ContextKeyExpr.and(command.precondition, item.when)
106-
: item.when,
107-
});
108-
}
109-
} else if (keybinding) {
110-
KeybindingsRegistry.registerKeybindingRule({
111-
...keybinding,
112-
id: command.id,
113-
when: command.precondition
114-
? ContextKeyExpr.and(command.precondition, keybinding.when)
115-
: keybinding.when,
116-
});
117-
}
118-
119-
return disposables;
120-
}

src/monaco/index.ts

-2
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,3 @@ import 'monaco-editor/esm/vs/editor/standalone/browser/referenceSearch/standalon
2222
import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast';
2323

2424
export * from 'monaco-editor/esm/vs/editor/editor.api.js';
25-
26-
export { KeybindingWeight, Action2 } from './common';

src/monaco/quickAccessSettingsAction.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import 'reflect-metadata';
2+
import { container } from 'tsyringe';
23
import { localize } from 'monaco-editor/esm/vs/nls';
3-
import { KeyMod, KeyCode } from 'mo/monaco';
44
import { KeyChord } from 'monaco-editor/esm/vs/base/common/keyCodes';
5-
import { ISettingsService, SettingsService } from 'mo/services';
65
import { ServicesAccessor } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation';
7-
import { container } from 'tsyringe';
8-
import { Action2, KeybindingWeight } from './common';
6+
7+
import { KeyMod, KeyCode } from 'mo/monaco';
8+
import { KeybindingWeight } from 'mo/monaco/common';
9+
import { Action2 } from 'mo/monaco/action';
910
import { constants } from 'mo/services/builtinService/const';
11+
import { ISettingsService, SettingsService } from 'mo/services';
1012

1113
export class QuickAccessSettings extends Action2 {
1214
static readonly ID = constants.ACTION_QUICK_ACCESS_SETTINGS;

src/monaco/quickAccessViewAction.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import 'reflect-metadata';
2+
import { container } from 'tsyringe';
3+
24
import { localize } from 'monaco-editor/esm/vs/nls';
35
import { DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle';
46
import { QuickCommandNLS } from 'monaco-editor/esm/vs/editor/common/standaloneStrings';
@@ -24,12 +26,12 @@ import {
2426
import { stripIcons } from 'monaco-editor/esm/vs/base/common/iconLabels';
2527

2628
import { KeyMod, KeyCode, editor as MonacoEditor } from 'mo/monaco';
27-
import { container } from 'tsyringe';
2829
import { EditorService, IEditorService } from 'mo/services';
29-
import { Action2, KeybindingWeight } from './common';
30-
import { MonacoService } from './monacoService';
31-
import { registerQuickAccessProvider } from './quickAccessProvider';
3230
import { constants } from 'mo/services/builtinService/const';
31+
import { Action2 } from 'mo/monaco/action';
32+
import { KeybindingWeight } from 'mo/monaco/common';
33+
import { MonacoService } from 'mo/monaco/monacoService';
34+
import { registerQuickAccessProvider } from 'mo/monaco/quickAccessProvider';
3335

3436
export class CommandQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider {
3537
static PREFIX = '>';

src/monaco/quickCopyLineUp.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import 'reflect-metadata';
2+
import { container } from 'tsyringe';
23
import { localize } from 'mo/i18n/localize';
34
import { KeyMod, KeyCode } from 'mo/monaco';
45
import { EditorService, IEditorService } from 'mo/services';
5-
import { container } from 'tsyringe';
6-
import { Action2, KeybindingWeight } from './common';
6+
77
import { constants } from 'mo/services/builtinService/const';
8+
import { KeybindingWeight } from 'mo/monaco/common';
9+
import { Action2 } from 'mo/monaco/action';
810

911
export class QuickCopyLineUp extends Action2 {
1012
static readonly ID = constants.ACTION_QUICK_COPY_LINE_UP;

0 commit comments

Comments
 (0)