Skip to content

Commit

Permalink
Picker for non editor views (fixes #15262)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Nov 28, 2016
1 parent 976d2a0 commit adbc334
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/panel/panelPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
partService,
keybindingService,
instantiationService,
(<PanelRegistry>Registry.as(PanelExtensions.Panels)),
Registry.as<PanelRegistry>(PanelExtensions.Panels),
PanelPart.activePanelSettingsKey,
'panel',
'panel',
Expand Down
26 changes: 13 additions & 13 deletions src/vs/workbench/browser/parts/quickopen/quickopen.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,30 +128,30 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
});

function navigateKeybinding(shift: boolean): IKeybindings {
if (shift) {
return {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_P,
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_E, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Tab],
mac: {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_P,
secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Tab]
}
};
} else {
if (!shift) {
return {
primary: KeyMod.CtrlCmd | KeyCode.KEY_P,
secondary: [KeyMod.CtrlCmd | KeyCode.KEY_E, KeyMod.CtrlCmd | KeyCode.Tab],
secondary: [KeyMod.CtrlCmd | KeyCode.KEY_E, KeyMod.CtrlCmd | KeyCode.Tab, KeyMod.CtrlCmd | KeyCode.KEY_Q],
mac: {
primary: KeyMod.CtrlCmd | KeyCode.KEY_P,
secondary: [KeyMod.WinCtrl | KeyCode.Tab]
secondary: [KeyMod.WinCtrl | KeyCode.Tab, KeyMod.WinCtrl | KeyCode.KEY_Q]
}
};
}

return {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_P,
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_E, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Tab, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Q],
mac: {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_P,
secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Tab, KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_Q]
}
};
}

const registry = <IWorkbenchActionRegistry>Registry.as(ActionExtensions.WorkbenchActions);

registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalQuickOpenAction, GlobalQuickOpenAction.ID, GlobalQuickOpenAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_P, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_E], mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_P, secondary: null } }), 'Go to File...');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigateNextAction, QuickOpenNavigateNextAction.ID, QuickOpenNavigateNextAction.LABEL, navigateKeybinding(false), condition), 'Navigate Next in Quick Open');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigateNextAction, QuickOpenNavigateNextAction.ID, QuickOpenNavigateNextAction.LABEL, navigateKeybinding(false), condition, KeybindingsRegistry.WEIGHT.workbenchContrib(50)), 'Navigate Next in Quick Open');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigatePreviousAction, QuickOpenNavigatePreviousAction.ID, QuickOpenNavigatePreviousAction.LABEL, navigateKeybinding(true), condition, KeybindingsRegistry.WEIGHT.workbenchContrib(50)), 'Navigate Previous in Quick Open');
registry.registerWorkbenchAction(new SyncActionDescriptor(RemoveFromEditorHistoryAction, RemoveFromEditorHistoryAction.ID, RemoveFromEditorHistoryAction.LABEL), 'Remove From History');
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/sidebar/sidebarPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements ISidebar {
partService,
keybindingService,
instantiationService,
(<ViewletRegistry>Registry.as(ViewletExtensions.Viewlets)),
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets),
SidebarPart.activeViewletSettingsKey,
'sideBar',
'viewlet',
Expand Down
4 changes: 3 additions & 1 deletion src/vs/workbench/electron-browser/workbench.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ import 'vs/workbench/electron-browser/main';

import 'vs/workbench/parts/themes/test/electron-browser/themes.test.contribution';

import 'vs/workbench/parts/watermark/electron-browser/watermark';
import 'vs/workbench/parts/watermark/electron-browser/watermark';

import 'vs/workbench/parts/viewpicker/browser/viewpicker.contribution';
197 changes: 197 additions & 0 deletions src/vs/workbench/parts/viewpicker/browser/viewPickerHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';

import { TPromise } from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import { Registry } from 'vs/platform/platform';
import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
import errors = require('vs/base/common/errors');
import strings = require('vs/base/common/strings');
import scorer = require('vs/base/common/scorer');
import { Mode, IEntryRunContext, IAutoFocus, IQuickNavigateConfiguration } from 'vs/base/parts/quickopen/common/quickOpen';
import { QuickOpenModel, QuickOpenEntryGroup, QuickOpenEntry } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { QuickOpenHandler, QuickOpenAction } from 'vs/workbench/browser/quickopen';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IOutputService, Extensions as OutputExtensions, IOutputChannelRegistry } from 'vs/workbench/parts/output/common/output';
import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService';
import { Action } from 'vs/base/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';

export const VIEW_PICKER_PREFIX = 'view ';

export class ViewEntry extends QuickOpenEntryGroup {

constructor(
private label: string,
private open: () => void
) {
super();
}

public getLabel(): string {
return this.label;
}

public getAriaLabel(): string {
return nls.localize('entryAriaLabel', "{0}, view picker", this.getLabel());
}

public run(mode: Mode, context: IEntryRunContext): boolean {
if (mode === Mode.OPEN) {
return this.runOpen(context);
}

return super.run(mode, context);
}

private runOpen(context: IEntryRunContext): boolean {
setTimeout(() => {
this.open();
}, 0);

return true;
}
}

export class ViewPickerHandler extends QuickOpenHandler {

constructor(
@IViewletService private viewletService: IViewletService,
@IOutputService private outputService: IOutputService,
@ITerminalService private terminalService: ITerminalService,
@IPanelService private panelService: IPanelService
) {
super();
}

public getResults(searchValue: string): TPromise<QuickOpenModel> {
searchValue = searchValue.trim();
const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase();

const viewEntries = this.getViewEntries();

const entries = viewEntries.filter(e => {
if (!searchValue) {
return true;
}

if (!scorer.matches(e.getLabel(), normalizedSearchValueLowercase)) {
return false;
}

const {labelHighlights, descriptionHighlights} = QuickOpenEntry.highlight(e, searchValue);
e.setHighlights(labelHighlights, descriptionHighlights);

return true;
});

return TPromise.as(new QuickOpenModel(entries));
}

private getViewEntries(): ViewEntry[] {
const viewEntries: ViewEntry[] = [];

// Viewlets
const viewlets = this.viewletService.getViewlets();
viewlets.forEach((viewlet, index) => {
const entry = new ViewEntry(viewlet.name, () => this.viewletService.openViewlet(viewlet.id, true).done(null, errors.onUnexpectedError));
viewEntries.push(entry);

if (index === 0) {
entry.setGroupLabel(nls.localize('views', "Views"));
}
});

// Panels
const panels = Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels();
panels.forEach((panel, index) => {
const entry = new ViewEntry(panel.name, () => this.panelService.openPanel(panel.id, true).done(null, errors.onUnexpectedError));
if (index === 0) {
entry.setShowBorder(true);
entry.setGroupLabel(nls.localize('panels', "Panels"));
}

viewEntries.push(entry);
});

// Terminals
const terminals = this.terminalService.terminalInstances;
terminals.forEach((terminal, index) => {
const entry = new ViewEntry(nls.localize('terminalTitle', "{0}: {1}", index + 1, terminal.title), () => {
this.terminalService.showPanel(true).done(() => {
this.terminalService.setActiveInstance(terminal);
}, errors.onUnexpectedError);
});

if (index === 0) {
entry.setShowBorder(true);
entry.setGroupLabel(nls.localize('terminals', "Terminal"));
}

viewEntries.push(entry);
});

// Output Channels
const channels = Registry.as<IOutputChannelRegistry>(OutputExtensions.OutputChannels).getChannels();
channels.forEach((channel, index) => {
const entry = new ViewEntry(channel.label, () => this.outputService.getChannel(channel.id).show().done(null, errors.onUnexpectedError));

if (index === 0) {
entry.setShowBorder(true);
entry.setGroupLabel(nls.localize('channels', "Output"));
}

viewEntries.push(entry);
});

return viewEntries;
}

public getAutoFocus(searchValue: string, quickNavigateConfiguration: IQuickNavigateConfiguration): IAutoFocus {
return {
autoFocusFirstEntry: !!searchValue || !!quickNavigateConfiguration
};
}
}

export class OpenViewPickerAction extends QuickOpenAction {

public static ID = 'workbench.action.openView';
public static LABEL = nls.localize('openView', "Open View");

constructor(
id: string,
label: string,
@IQuickOpenService quickOpenService: IQuickOpenService
) {
super(id, label, VIEW_PICKER_PREFIX, quickOpenService);
}
}

export class QuickOpenViewPickerAction extends Action {

public static ID = 'workbench.action.quickOpenView';
public static LABEL = nls.localize('quickOpenView', "Quick Open View");

constructor(
id: string,
label: string,
@IQuickOpenService private quickOpenService: IQuickOpenService,
@IKeybindingService private keybindingService: IKeybindingService
) {
super(id, label);
}

public run(): TPromise<any> {
const keys = this.keybindingService.lookupKeybindings(this.id);

this.quickOpenService.show(VIEW_PICKER_PREFIX, { quickNavigateConfiguration: { keybindings: keys } });

return TPromise.as(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

'use strict';

import { Registry } from 'vs/platform/platform';
import nls = require('vs/nls');
import { QuickOpenHandlerDescriptor, IQuickOpenRegistry, Extensions as QuickOpenExtensions } from 'vs/workbench/browser/quickopen';
import { VIEW_PICKER_PREFIX, OpenViewPickerAction, QuickOpenViewPickerAction } from 'vs/workbench/parts/viewpicker/browser/viewPickerHandler';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';

Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerQuickOpenHandler(
new QuickOpenHandlerDescriptor(
'vs/workbench/parts/viewpicker/browser/viewPickerHandler',
'ViewPickerHandler',
VIEW_PICKER_PREFIX,
[
{
prefix: VIEW_PICKER_PREFIX,
needsEditor: false,
description: nls.localize('viewPickerDescription', "Open View")
}
]
)
);

const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenViewPickerAction, OpenViewPickerAction.ID, OpenViewPickerAction.LABEL), 'Open View');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenViewPickerAction, QuickOpenViewPickerAction.ID, QuickOpenViewPickerAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_Q, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_Q }, linux: { primary: null } }), 'Quick Open View');

0 comments on commit adbc334

Please sign in to comment.