提交 76a920c1 编写于 作者: B Benjamin Pasero

first cut of commands for explorer (for #4557)

上级 f3d76318
......@@ -292,6 +292,10 @@ export class ExplorerViewlet extends Viewlet {
return this.actionRunner;
}
public getViewletState(): FileViewletState {
return this.viewletState;
}
public getOptimalWidth(): number {
const additionalMargin = 16;
const openedEditorsViewWidth = this.openEditorsVisible ? this.openEditorsView.getOptimalWidth() : 0;
......
......@@ -23,6 +23,10 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import { openFolderPickerCommand, openWindowCommand, openFileInNewWindowCommand, openFocussedExplorerItemCommand, deleteFocussedExplorerItemCommand, moveFocussedExplorerItemToTrashCommand, openFocussedExplorerSideBySideItemCommand, renameFocussedExplorerItemCommand } from 'vs/workbench/parts/files/browser/fileCommands';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
class FilesViewerActionContributor extends ActionBarContributor {
......@@ -194,4 +198,66 @@ if (isMacintosh) {
} else {
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'Files: Open File...', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'Files: Open Folder...', category);
}
\ No newline at end of file
}
// Commands
CommandsRegistry.registerCommand('_files.openFolderPicker', openFolderPickerCommand);
CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand);
CommandsRegistry.registerCommand('workbench.action.files.openFileInNewWindow', openFileInNewWindowCommand);
const explorerFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has('explorerViewletVisible'), ContextKeyExpr.has('explorerFocus'));
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.files.action.open',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: explorerFocusCondition,
primary: KeyCode.Enter,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.DownArrow
},
handler: openFocussedExplorerItemCommand
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.files.action.openToSide',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: explorerFocusCondition,
primary: KeyMod.CtrlCmd | KeyCode.Enter,
mac: {
primary: KeyMod.WinCtrl | KeyCode.Enter
},
handler: openFocussedExplorerSideBySideItemCommand
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.files.action.triggerRename',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: explorerFocusCondition,
primary: KeyCode.F2,
mac: {
primary: KeyCode.Enter
},
handler: renameFocussedExplorerItemCommand
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.files.action.moveFileToTrash',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: explorerFocusCondition,
primary: KeyCode.Delete,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.Backspace
},
handler: moveFocussedExplorerItemToTrashCommand
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.files.action.delete',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: explorerFocusCondition,
primary: KeyMod.Shift | KeyCode.Delete,
mac: {
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace
},
handler: deleteFocussedExplorerItemCommand
});
\ No newline at end of file
......@@ -647,10 +647,14 @@ export class BaseDeleteFileAction extends BaseFileAction {
}
// Read context
if (context && context.event) {
const bypassTrash = (isMacintosh && context.event.altKey) || (!isMacintosh && context.event.shiftKey);
if (bypassTrash) {
this.useTrash = false;
if (context) {
if (context.event) {
const bypassTrash = (isMacintosh && context.event.altKey) || (!isMacintosh && context.event.shiftKey);
if (bypassTrash) {
this.useTrash = false;
}
} else if (typeof context.useTrash === 'boolean') {
this.useTrash = context.useTrash;
}
}
......@@ -1859,22 +1863,12 @@ export function keybindingForAction(id: string, keybindingService: IKeybindingSe
switch (id) {
case GlobalNewUntitledFileAction.ID:
return new Keybinding(KeyMod.CtrlCmd | KeyCode.KEY_N);
case TriggerRenameFileAction.ID:
return new Keybinding(isMacintosh ? KeyCode.Enter : KeyCode.F2);
case SaveFileAction.ID:
return new Keybinding(KeyMod.CtrlCmd | KeyCode.KEY_S);
case MoveFileToTrashAction.ID:
return new Keybinding(isMacintosh ? KeyMod.CtrlCmd | KeyCode.Backspace : KeyCode.Delete);
case CopyFileAction.ID:
return new Keybinding(KeyMod.CtrlCmd | KeyCode.KEY_C);
case PasteFileAction.ID:
return new Keybinding(KeyMod.CtrlCmd | KeyCode.KEY_V);
case OpenToSideAction.ID:
if (isMacintosh) {
return new Keybinding(KeyMod.WinCtrl | KeyCode.Enter);
} else {
return new Keybinding(KeyMod.CtrlCmd | KeyCode.Enter);
}
}
if (keybindingService) {
......
......@@ -6,6 +6,7 @@
'use strict';
import paths = require('vs/base/common/paths');
import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { toResource } from 'vs/workbench/common/editor';
......@@ -15,6 +16,9 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ExplorerViewlet } from 'vs/workbench/parts/files/browser/explorerViewlet';
import { VIEWLET_ID } from 'vs/workbench/parts/files/common/files';
import { FileStat } from 'vs/workbench/parts/files/common/explorerViewModel';
import errors = require('vs/base/common/errors');
import { ITree } from 'vs/base/parts/tree/browser/tree';
// Commands
......@@ -61,4 +65,62 @@ export const revealInExplorerCommand = (accessor: ServicesAccessor, resource: UR
}
}
});
};
\ No newline at end of file
};
export const openFocussedExplorerItemCommand = (accessor: ServicesAccessor) => openFocussedExplorerItem(accessor, false);
export const openFocussedExplorerSideBySideItemCommand = (accessor: ServicesAccessor) => openFocussedExplorerItem(accessor, true);
function openFocussedExplorerItem(accessor: ServicesAccessor, sideBySide: boolean): void {
withFocussedExplorerItem(accessor).then(res => {
if (res) {
// Directory: Toggle expansion
if (res.item.isDirectory) {
res.tree.toggleExpansion(res.item);
}
// File: Open
else {
res.tree.setFocus(res.item, { origin: 'keyboard' });
const editorService = accessor.get(IWorkbenchEditorService);
editorService.openEditor({ resource: res.item.resource }, sideBySide).done(null, errors.onUnexpectedError);
}
}
});
}
export const renameFocussedExplorerItemCommand = (accessor: ServicesAccessor) => {
runExplorerActionOnFocussedItem(accessor, 'workbench.files.action.triggerRename');
};
export const deleteFocussedExplorerItemCommand = (accessor: ServicesAccessor) => {
runExplorerActionOnFocussedItem(accessor, 'workbench.files.action.moveFileToTrash', { useTrash: false });
};
export const moveFocussedExplorerItemToTrashCommand = (accessor: ServicesAccessor) => {
runExplorerActionOnFocussedItem(accessor, 'workbench.files.action.moveFileToTrash', { useTrash: true });
};
function withFocussedExplorerItem(accessor: ServicesAccessor): TPromise<{ viewlet: ExplorerViewlet, tree: ITree, item: FileStat }> {
const viewletService = accessor.get(IViewletService);
return viewletService.openViewlet(VIEWLET_ID, false).then((viewlet: ExplorerViewlet) => {
const tree = viewlet.getExplorerView().getViewer();
// Ignore if in highlight mode
if (tree.getHighlight()) {
return void 0;
}
return { viewlet, tree, item: tree.getFocus() };
});
};
function runExplorerActionOnFocussedItem(accessor: ServicesAccessor, id: string, context?: any): void {
withFocussedExplorerItem(accessor).then(res => {
if (res) {
res.viewlet.getViewletState().actionProvider.runAction(res.tree, res.item, id, context).done(null, errors.onUnexpectedError);
}
});
}
\ No newline at end of file
......@@ -372,7 +372,6 @@ export class FileAccessibilityProvider implements IAccessibilityProvider {
// Explorer Controller
export class FileController extends DefaultController {
private didCatchEnterDown: boolean;
private state: FileViewletState;
private contributedContextMenu: IMenu;
......@@ -391,35 +390,10 @@ export class FileController extends DefaultController {
this.contributedContextMenu = menuService.createMenu(MenuId.ExplorerContext, contextKeyService);
this.didCatchEnterDown = false;
// Open
this.downKeyBindingDispatcher.set(isMacintosh ? KeyMod.CtrlCmd | KeyCode.DownArrow : KeyCode.Enter, (t, e) => this.onEnterDown(t, e));
this.upKeyBindingDispatcher.set(isMacintosh ? KeyMod.CtrlCmd | KeyCode.DownArrow : KeyCode.Enter, (t, e) => this.onEnterUp(t, e));
// Open to the side
if (isMacintosh) {
this.upKeyBindingDispatcher.set(KeyMod.WinCtrl | KeyCode.Enter, (t, e) => this.onModifierEnterUp(t, e)); // Mac: somehow Cmd+Enter does not work
} else {
this.upKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.Enter, (t, e) => this.onModifierEnterUp(t, e));
}
// Rename
this.downKeyBindingDispatcher.set(isMacintosh ? KeyCode.Enter : KeyCode.F2, (t, e) => this.onF2(t, e));
// Copy / Paste
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.KEY_C, (t, e) => this.onCopy(t, e));
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.KEY_V, (t, e) => this.onPaste(t, e));
// Delete
if (isMacintosh) {
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.Backspace, (t, e) => this.onDelete(t, e));
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace, (t, e) => this.onDelete(t, e));
} else {
this.downKeyBindingDispatcher.set(KeyCode.Delete, (t, e) => this.onDelete(t, e));
this.downKeyBindingDispatcher.set(KeyMod.Shift | KeyCode.Delete, (t, e) => this.onDelete(t, e));
}
this.state = state;
}
......@@ -529,63 +503,6 @@ export class FileController extends DefaultController {
return true;
}
private onEnterDown(tree: ITree, event: IKeyboardEvent): boolean {
if (tree.getHighlight()) {
return false;
}
const payload = { origin: 'keyboard' };
const stat: FileStat = tree.getFocus();
if (stat) {
// Directory: Toggle expansion
if (stat.isDirectory) {
tree.toggleExpansion(stat);
}
// File: Open
else {
tree.setFocus(stat, payload);
this.openEditor(stat, false, false);
}
}
this.didCatchEnterDown = true;
return true;
}
private onEnterUp(tree: ITree, event: IKeyboardEvent): boolean {
if (!this.didCatchEnterDown || tree.getHighlight()) {
return false;
}
const stat: FileStat = tree.getFocus();
if (stat && !stat.isDirectory) {
this.openEditor(stat, false, false);
}
this.didCatchEnterDown = false;
return true;
}
private onModifierEnterUp(tree: ITree, event: IKeyboardEvent): boolean {
if (tree.getHighlight()) {
return false;
}
const stat: FileStat = tree.getFocus();
if (stat && !stat.isDirectory) {
this.openEditor(stat, false, true);
}
this.didCatchEnterDown = false;
return true;
}
private onCopy(tree: ITree, event: IKeyboardEvent): boolean {
const stat: FileStat = tree.getFocus();
if (stat) {
......@@ -619,29 +536,6 @@ export class FileController extends DefaultController {
}
}
private onF2(tree: ITree, event: IKeyboardEvent): boolean {
const stat: FileStat = tree.getFocus();
if (stat) {
this.runAction(tree, stat, 'workbench.files.action.triggerRename').done();
return true;
}
return false;
}
private onDelete(tree: ITree, event: IKeyboardEvent): boolean {
const stat: FileStat = tree.getFocus();
if (stat) {
this.runAction(tree, stat, 'workbench.files.action.moveFileToTrash', event).done();
return true;
}
return false;
}
private runAction(tree: ITree, stat: FileStat, id: string, event?: IKeyboardEvent): TPromise<any> {
return this.state.actionProvider.runAction(tree, stat, id, { event });
}
......
......@@ -14,7 +14,7 @@ import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/
import { asFileResource } from 'vs/workbench/parts/files/common/files';
import { copyPathCommand, GlobalCopyPathAction, CopyPathAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { RevealInOSAction } from 'vs/workbench/parts/files/browser/fileActions';
import { revealInOSCommand, openFolderPickerCommand, openWindowCommand, openFileInNewWindowCommand, revealInExplorerCommand } from 'vs/workbench/parts/files/browser/fileCommands';
import { revealInOSCommand, revealInExplorerCommand } from 'vs/workbench/parts/files/browser/fileCommands';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands';
......@@ -61,11 +61,6 @@ workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(Global
const actionsRegistry = Registry.as<IActionBarRegistry>(ActionBarExtensions.Actionbar);
actionsRegistry.registerActionBarContributor(Scope.VIEWER, FileViewerActionContributor);
// Commands
CommandsRegistry.registerCommand('_files.openFolderPicker', openFolderPickerCommand);
CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand);
CommandsRegistry.registerCommand('workbench.action.files.openFileInNewWindow', openFileInNewWindowCommand);
// Editor Title Context Menu
appendEditorTitleContextMenuItem('_workbench.action.files.revealInOS', RevealInOSAction.LABEL, revealInOSCommand);
appendEditorTitleContextMenuItem('_workbench.action.files.copyPath', CopyPathAction.LABEL, copyPathCommand);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册