mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode bd0efff9e3f36d6b3e1045cee9887003af8034d7
This commit is contained in:
@@ -9,11 +9,13 @@ import { IConstructorSignature2, createDecorator, BrandedService, ServicesAccess
|
||||
import { IKeybindings, KeybindingsRegistry, IKeybindingRule } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ContextKeyExpr, IContextKeyService, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICommandService, CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { UriDto } from 'vs/base/common/types';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { LinkedList } from 'vs/base/common/linkedList';
|
||||
|
||||
export interface ILocalizedString {
|
||||
value: string;
|
||||
@@ -159,33 +161,51 @@ export interface IMenuService {
|
||||
|
||||
export type ICommandsMap = Map<string, ICommandAction>;
|
||||
|
||||
export interface IMenuRegistryChangeEvent {
|
||||
has(id: MenuId): boolean;
|
||||
}
|
||||
|
||||
export interface IMenuRegistry {
|
||||
readonly onDidChangeMenu: Event<IMenuRegistryChangeEvent>;
|
||||
addCommands(newCommands: Iterable<ICommandAction>): IDisposable;
|
||||
addCommand(userCommand: ICommandAction): IDisposable;
|
||||
getCommand(id: string): ICommandAction | undefined;
|
||||
getCommands(): ICommandsMap;
|
||||
appendMenuItems(items: Iterable<{ id: MenuId, item: IMenuItem | ISubmenuItem }>): IDisposable;
|
||||
appendMenuItem(menu: MenuId, item: IMenuItem | ISubmenuItem): IDisposable;
|
||||
getMenuItems(loc: MenuId): Array<IMenuItem | ISubmenuItem>;
|
||||
readonly onDidChangeMenu: Event<MenuId>;
|
||||
}
|
||||
|
||||
export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
|
||||
|
||||
private readonly _commands = new Map<string, ICommandAction>();
|
||||
private readonly _menuItems = new Map<MenuId, Array<IMenuItem | ISubmenuItem>>();
|
||||
private readonly _onDidChangeMenu = new Emitter<MenuId>();
|
||||
private readonly _menuItems = new Map<MenuId, LinkedList<IMenuItem | ISubmenuItem>>();
|
||||
private readonly _onDidChangeMenu = new Emitter<IMenuRegistryChangeEvent>();
|
||||
|
||||
readonly onDidChangeMenu: Event<MenuId> = this._onDidChangeMenu.event;
|
||||
readonly onDidChangeMenu: Event<IMenuRegistryChangeEvent> = this._onDidChangeMenu.event;
|
||||
|
||||
addCommand(command: ICommandAction): IDisposable {
|
||||
this._commands.set(command.id, command);
|
||||
this._onDidChangeMenu.fire(MenuId.CommandPalette);
|
||||
return {
|
||||
dispose: () => {
|
||||
if (this._commands.delete(command.id)) {
|
||||
this._onDidChangeMenu.fire(MenuId.CommandPalette);
|
||||
}
|
||||
return this.addCommands(Iterable.single(command));
|
||||
}
|
||||
|
||||
private readonly _commandPaletteChangeEvent: IMenuRegistryChangeEvent = {
|
||||
has: id => id === MenuId.CommandPalette
|
||||
};
|
||||
|
||||
addCommands(commands: Iterable<ICommandAction>): IDisposable {
|
||||
for (const command of commands) {
|
||||
this._commands.set(command.id, command);
|
||||
}
|
||||
this._onDidChangeMenu.fire(this._commandPaletteChangeEvent);
|
||||
return toDisposable(() => {
|
||||
let didChange = false;
|
||||
for (const command of commands) {
|
||||
didChange = this._commands.delete(command.id) || didChange;
|
||||
}
|
||||
};
|
||||
if (didChange) {
|
||||
this._onDidChangeMenu.fire(this._commandPaletteChangeEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getCommand(id: string): ICommandAction | undefined {
|
||||
@@ -199,28 +219,44 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
|
||||
}
|
||||
|
||||
appendMenuItem(id: MenuId, item: IMenuItem | ISubmenuItem): IDisposable {
|
||||
let array = this._menuItems.get(id);
|
||||
if (!array) {
|
||||
array = [item];
|
||||
this._menuItems.set(id, array);
|
||||
} else {
|
||||
array.push(item);
|
||||
}
|
||||
this._onDidChangeMenu.fire(id);
|
||||
return {
|
||||
dispose: () => {
|
||||
const idx = array!.indexOf(item);
|
||||
if (idx >= 0) {
|
||||
array!.splice(idx, 1);
|
||||
this._onDidChangeMenu.fire(id);
|
||||
}
|
||||
return this.appendMenuItems(Iterable.single({ id, item }));
|
||||
}
|
||||
|
||||
appendMenuItems(items: Iterable<{ id: MenuId, item: IMenuItem | ISubmenuItem }>): IDisposable {
|
||||
|
||||
const changedIds = new Set<MenuId>();
|
||||
const toRemove = new LinkedList<Function>();
|
||||
|
||||
for (const { id, item } of items) {
|
||||
let list = this._menuItems.get(id);
|
||||
if (!list) {
|
||||
list = new LinkedList();
|
||||
this._menuItems.set(id, list);
|
||||
}
|
||||
};
|
||||
toRemove.push(list.push(item));
|
||||
changedIds.add(id);
|
||||
}
|
||||
|
||||
this._onDidChangeMenu.fire(changedIds);
|
||||
|
||||
return toDisposable(() => {
|
||||
if (toRemove.size > 0) {
|
||||
for (let fn of toRemove) {
|
||||
fn();
|
||||
}
|
||||
this._onDidChangeMenu.fire(changedIds);
|
||||
toRemove.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getMenuItems(id: MenuId): Array<IMenuItem | ISubmenuItem> {
|
||||
const result = (this._menuItems.get(id) || []).slice(0);
|
||||
|
||||
let result: Array<IMenuItem | ISubmenuItem>;
|
||||
if (this._menuItems.has(id)) {
|
||||
result = [...this._menuItems.get(id)!];
|
||||
} else {
|
||||
result = [];
|
||||
}
|
||||
if (id === MenuId.CommandPalette) {
|
||||
// CommandPalette is special because it shows
|
||||
// all commands by default
|
||||
@@ -232,12 +268,12 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
|
||||
private _appendImplicitItems(result: Array<IMenuItem | ISubmenuItem>) {
|
||||
const set = new Set<string>();
|
||||
|
||||
const temp = result.filter(item => { return isIMenuItem(item); }) as IMenuItem[];
|
||||
|
||||
for (const { command, alt } of temp) {
|
||||
set.add(command.id);
|
||||
if (alt) {
|
||||
set.add(alt.id);
|
||||
for (const item of result) {
|
||||
if (isIMenuItem(item)) {
|
||||
set.add(item.command.id);
|
||||
if (item.alt) {
|
||||
set.add(item.alt.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._commands.forEach((command, id) => {
|
||||
@@ -441,14 +477,13 @@ export function registerAction2(ctor: { new(): Action2 }): IDisposable {
|
||||
|
||||
// menu
|
||||
if (Array.isArray(menu)) {
|
||||
for (let item of menu) {
|
||||
disposables.add(MenuRegistry.appendMenuItem(item.id, { command: { ...command }, ...item }));
|
||||
}
|
||||
disposables.add(MenuRegistry.appendMenuItems(menu.map(item => ({ id: item.id, item: { command, ...item } }))));
|
||||
|
||||
} else if (menu) {
|
||||
disposables.add(MenuRegistry.appendMenuItem(menu.id, { command: { ...command }, ...menu }));
|
||||
disposables.add(MenuRegistry.appendMenuItem(menu.id, { command, ...menu }));
|
||||
}
|
||||
if (f1) {
|
||||
disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: command }));
|
||||
disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command }));
|
||||
}
|
||||
|
||||
// keybinding
|
||||
|
||||
@@ -45,7 +45,7 @@ class Menu implements IMenu {
|
||||
// rebuild this menu whenever the menu registry reports an
|
||||
// event for this MenuId
|
||||
this._dispoables.add(Event.debounce(
|
||||
Event.filter(MenuRegistry.onDidChangeMenu, menuId => menuId === this._id),
|
||||
Event.filter(MenuRegistry.onDidChangeMenu, set => set.has(this._id)),
|
||||
() => { },
|
||||
50
|
||||
)(this._build, this));
|
||||
|
||||
Reference in New Issue
Block a user