Skip to content

Commit

Permalink
add commands list.expandSelectionDown and list.expandSelectionUp (for #…
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Jan 11, 2018
1 parent d5e1727 commit 8962e0e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 31 deletions.
4 changes: 4 additions & 0 deletions src/vs/base/browser/ui/list/listPaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export class PagedList<T> {
this.list.setSelection(indexes);
}

getSelection(): number[] {
return this.list.getSelection();
}

layout(height?: number): void {
this.list.layout(height);
}
Expand Down
122 changes: 112 additions & 10 deletions src/vs/workbench/electron-browser/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,33 @@ import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiS
import { PagedList } from 'vs/base/browser/ui/list/listPaging';
import { range } from 'vs/base/common/arrays';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ITree } from 'vs/base/parts/tree/browser/tree';

// --- List Commands

export function registerCommands(): void {

function focusDown(accessor: ServicesAccessor, arg2?: number): void {
const focused = accessor.get(IListService).lastFocusedList;
const count = typeof arg2 === 'number' ? arg2 : 1;

// List
if (focused instanceof List || focused instanceof PagedList) {
const list = focused;

list.focusNext(count);
list.reveal(list.getFocus()[0]);
}

// Tree
else if (focused) {
const tree = focused;

tree.focusNext(count, { origin: 'keyboard' });
tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError);
}
}

KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'list.focusDown',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
Expand All @@ -36,28 +58,93 @@ export function registerCommands(): void {
primary: KeyCode.DownArrow,
secondary: [KeyMod.WinCtrl | KeyCode.KEY_N]
},
handler: (accessor, arg2) => focusDown(accessor, arg2)
});

function expandMultiSelection(focused: List<any> | PagedList<any> | ITree, previousFocus: any): void {

// List
if (focused instanceof List || focused instanceof PagedList) {
const list = focused;

const focus = list.getFocus() ? list.getFocus()[0] : void 0;
const selection = list.getSelection();
if (selection && selection.indexOf(focus) >= 0) {
list.setSelection(selection.filter(s => s !== previousFocus));
} else {
list.setSelection(selection.concat(focus));
}
}

// Tree
else if (focused) {
const tree = focused;

const focus = tree.getFocus();
const selection = tree.getSelection();
if (selection && selection.indexOf(focus) >= 0) {
tree.setSelection(selection.filter(s => s !== previousFocus));
} else {
tree.setSelection(selection.concat(focus));
}
}
}

KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'list.expandSelectionDown',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: WorkbenchListFocusContextKey,
primary: KeyMod.Shift | KeyCode.DownArrow,
handler: (accessor, arg2) => {
const focused = accessor.get(IListService).lastFocusedList;
const count = typeof arg2 === 'number' ? arg2 : 1;

// List
if (focused instanceof List || focused instanceof PagedList) {
const list = focused;

list.focusNext(count);
list.reveal(list.getFocus()[0]);
// Focus down first
const previousFocus = list.getFocus() ? list.getFocus()[0] : void 0;
focusDown(accessor, arg2);

// Then adjust selection
expandMultiSelection(focused, previousFocus);
}

// Tree
else if (focused) {
const tree = focused;

tree.focusNext(count, { origin: 'keyboard' });
tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError);
// Focus down first
const previousFocus = tree.getFocus();
focusDown(accessor, arg2);

// Then adjust selection
expandMultiSelection(focused, previousFocus);
}
}
});

function focusUp(accessor: ServicesAccessor, arg2?: number): void {
const focused = accessor.get(IListService).lastFocusedList;
const count = typeof arg2 === 'number' ? arg2 : 1;

// List
if (focused instanceof List || focused instanceof PagedList) {
const list = focused;

list.focusPrevious(count);
list.reveal(list.getFocus()[0]);
}

// Tree
else if (focused) {
const tree = focused;

tree.focusPrevious(count, { origin: 'keyboard' });
tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError);
}
}

KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'list.focusUp',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
Expand All @@ -67,24 +154,39 @@ export function registerCommands(): void {
primary: KeyCode.UpArrow,
secondary: [KeyMod.WinCtrl | KeyCode.KEY_P]
},
handler: (accessor, arg2) => focusUp(accessor, arg2)
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'list.expandSelectionUp',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: WorkbenchListFocusContextKey,
primary: KeyMod.Shift | KeyCode.UpArrow,
handler: (accessor, arg2) => {
const focused = accessor.get(IListService).lastFocusedList;
const count = typeof arg2 === 'number' ? arg2 : 1;

// List
if (focused instanceof List || focused instanceof PagedList) {
const list = focused;

list.focusPrevious(count);
list.reveal(list.getFocus()[0]);
// Focus up first
const previousFocus = list.getFocus() ? list.getFocus()[0] : void 0;
focusUp(accessor, arg2);

// Then adjust selection
expandMultiSelection(focused, previousFocus);
}

// Tree
else if (focused) {
const tree = focused;

tree.focusPrevious(count, { origin: 'keyboard' });
tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError);
// Focus up first
const previousFocus = tree.getFocus();
focusUp(accessor, arg2);

// Then adjust selection
expandMultiSelection(focused, previousFocus);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,27 +427,6 @@ export class FileController extends DefaultController implements IDisposable {
return true;
}

public onKeyDown(tree: ITree, event: IKeyboardEvent): boolean {
if (event.shiftKey && (event.keyCode === KeyCode.DownArrow || event.keyCode === KeyCode.UpArrow)) {
const previousFocus = tree.getFocus();
if (event.keyCode === KeyCode.DownArrow) {
tree.focusNext();
} else {
tree.focusPrevious();
}

const focus = tree.getFocus();
const selection = tree.getSelection();
if (selection && selection.indexOf(focus) >= 0) {
tree.setSelection(selection.filter(s => s !== previousFocus));
} else {
tree.setSelection(selection.concat(focus));
}
}

return super.onKeyDown(tree, event);
}

public onContextMenu(tree: ITree, stat: FileStat | Model, event: ContextMenuEvent): boolean {
if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') {
return false;
Expand Down

0 comments on commit 8962e0e

Please sign in to comment.