diff --git a/src/vs/base/browser/ui/list/list.css b/src/vs/base/browser/ui/list/list.css index 64bbf7167c6..a10b9a83103 100644 --- a/src/vs/base/browser/ui/list/list.css +++ b/src/vs/base/browser/ui/list/list.css @@ -47,12 +47,12 @@ .vs-dark .monaco-list-row:hover { background-color: rgba(255, 255, 255, 0.08); } .hc-black .monaco-list-row:hover { outline: 1px dashed #f38518; background: transparent; } -/* Selection */ -.monaco-list-row.selected { background-color: #4FA7FF; color: white; } -.vs-dark .monaco-list-row.selected { background-color: #0E639C; color: white; } -.hc-black .monaco-list-row.selected { border: 1px solid #f38518; } - /* Focus */ .monaco-list-row.focused { background-color: #DCEBFC; } .vs-dark .monaco-list-row.focused { background-color: #073655; } .hc-black .monaco-list-row.focused { outline: 1px dotted #f38518; background: transparent } + +/* Selection */ +.monaco-list-row.selected { background-color: #4FA7FF; color: white; } +.vs-dark .monaco-list-row.selected { background-color: #0E639C; color: white; } +.hc-black .monaco-list-row.selected { border: 1px solid #f38518; } diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 0676a9e3ab2..d80880b8d49 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -93,6 +93,30 @@ export class PagedList { return this.list.scrollTop; } + focusNext(n?: number, loop?: boolean): void { + this.list.focusNext(n, loop); + } + + focusPrevious(n?: number, loop?: boolean): void { + this.list.focusPrevious(n, loop); + } + + selectNext(n?: number, loop?: boolean): void { + this.list.selectNext(n, loop); + } + + selectPrevious(n?: number, loop?: boolean): void { + this.list.selectPrevious(n, loop); + } + + getFocus(): number[] { + return this.list.getFocus(); + } + + setSelection(...indexes: number[]): void { + this.list.setSelection(...indexes); + } + layout(height?: number): void { this.list.layout(height); } diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 4dfb48f44b2..83a31054150 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -239,6 +239,10 @@ export class List implements IDisposable { this.setSelection(Math.max(index, 0)); } + getSelection(): number[] { + return this.selection.get(); + } + setFocus(...indexes: number[]): void { this.eventBufferer.bufferEvents(() => { indexes = indexes.concat(this.focus.set(...indexes)); @@ -265,7 +269,7 @@ export class List implements IDisposable { let lastPageIndex = this.view.indexAt(this.view.getScrollTop() + this.view.renderHeight); lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1; const lastPageElement = this.view.element(lastPageIndex); - const currentlyFocusedElement = this.getFocus()[0]; + const currentlyFocusedElement = this.getFocusedElements()[0]; if (currentlyFocusedElement !== lastPageElement) { this.setFocus(lastPageIndex); @@ -291,7 +295,7 @@ export class List implements IDisposable { } const firstPageElement = this.view.element(firstPageIndex); - const currentlyFocusedElement = this.getFocus()[0]; + const currentlyFocusedElement = this.getFocusedElements()[0]; if (currentlyFocusedElement !== firstPageElement) { this.setFocus(firstPageIndex); @@ -306,8 +310,12 @@ export class List implements IDisposable { } } - getFocus(): T[] { - return this.focus.get().map(i => this.view.element(i)); + getFocus(): number[] { + return this.focus.get(); + } + + getFocusedElements(): T[] { + return this.getFocus().map(i => this.view.element(i)); } reveal(index: number, relativeTop?: number): void { diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index a4ec74e26b9..56481279c39 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -143,7 +143,7 @@ class Delegate implements IDelegate { constructor(private listProvider: () => List) { } getHeight(element: CompletionItem): number { - const focus = this.listProvider().getFocus()[0]; + const focus = this.listProvider().getFocusedElements()[0]; if (element.suggestion.documentationLabel && element === focus) { return FocusHeight; @@ -735,7 +735,7 @@ export class SuggestWidget implements IContentWidget, IDisposable { case State.Loading: return !this.isAuto; default: - const focus = this.list.getFocus()[0]; + const focus = this.list.getFocusedElements()[0]; if (focus) { this.list.setSelection(this.completionModel.items.indexOf(focus)); } else { @@ -756,7 +756,7 @@ export class SuggestWidget implements IContentWidget, IDisposable { return; } - const item = this.list.getFocus()[0]; + const item = this.list.getFocusedElements()[0]; if (!item || !item.suggestion.documentationLabel) { return; @@ -820,7 +820,7 @@ export class SuggestWidget implements IContentWidget, IDisposable { } else if (this.state === State.Details) { height = 12 * UnfocusedHeight; } else { - const focus = this.list.getFocus()[0]; + const focus = this.list.getFocusedElements()[0]; const focusHeight = focus ? this.delegate.getHeight(focus) : UnfocusedHeight; height = focusHeight; @@ -839,7 +839,7 @@ export class SuggestWidget implements IContentWidget, IDisposable { if (this.state !== State.Details) { this.details.render(null); } else { - this.details.render(this.list.getFocus()[0]); + this.details.render(this.list.getFocusedElements()[0]); } } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 0979f9c3dc2..23c95824ace 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -124,9 +124,20 @@ export class ExtensionsViewlet extends Viewlet { } private onSearchKeyDown(e: StandardKeyboardEvent): void { - if (e.keyCode === KeyCode.Escape) { - this.searchBox.value = ''; - this.triggerSearch(0); + switch (e.keyCode) { + case KeyCode.DownArrow: + this.list.focusNext(); + break; + case KeyCode.UpArrow: + this.list.focusPrevious(); + break; + case KeyCode.Enter: + this.list.setSelection(...this.list.getFocus()); + break; + case KeyCode.Escape: + this.searchBox.value = ''; + this.triggerSearch(0); + break; } }