提交 e151b49c 编写于 作者: J Johannes Rieken

Merge pull request #1989 from Microsoft/joh/quickPick2

Allow details in quick pick
......@@ -33,7 +33,10 @@ export class HighlightedLabel implements IDisposable {
return this.domNode;
}
set(text: string = '', highlights?: IHighlight[]) {
set(text: string, highlights: IHighlight[] = []) {
if (!text) {
text = '';
}
if (this.didEverRender && this.text === text && objects.equals(this.highlights, highlights)) {
return;
}
......
......@@ -18,6 +18,7 @@ import {compareAnything, compareByPrefix} from 'vs/base/common/comparers';
import {ActionBar, IActionItem} from 'vs/base/browser/ui/actionbar/actionbar';
import {LegacyRenderer, ILegacyTemplateData} from 'vs/base/parts/tree/browser/treeDefaults';
import {HighlightedLabel} from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import {OcticonLabel} from 'vs/base/browser/ui/octiconLabel/octiconLabel';
import DOM = require('vs/base/browser/dom');
import scorer = require('vs/base/common/scorer');
......@@ -37,6 +38,7 @@ export class QuickOpenEntry {
private id: string;
private labelHighlights: IHighlight[];
private descriptionHighlights: IHighlight[];
private detailHighlights: IHighlight[];
private hidden: boolean;
private labelPrefix: string;
......@@ -68,9 +70,9 @@ export class QuickOpenEntry {
}
/**
* Meta information about the entry that is optional and can be shown to the right of the label
* Detail information about the entry that is optional and can be shown below the label
*/
public getMeta(): string {
public getDetail(): string {
return null;
}
......@@ -120,16 +122,17 @@ export class QuickOpenEntry {
/**
* Allows to set highlight ranges that should show up for the entry label and optionally description if set.
*/
public setHighlights(labelHighlights: IHighlight[], descriptionHighlights?: IHighlight[]): void {
public setHighlights(labelHighlights: IHighlight[], descriptionHighlights?: IHighlight[], detailHighlights?: IHighlight[]): void {
this.labelHighlights = labelHighlights;
this.descriptionHighlights = descriptionHighlights;
this.detailHighlights = detailHighlights;
}
/**
* Allows to return highlight ranges that should show up for the entry label and description.
*/
public getHighlights(): [IHighlight[] /* Label */, IHighlight[] /* Description */] {
return [this.labelHighlights, this.descriptionHighlights];
public getHighlights(): [IHighlight[] /* Label */, IHighlight[] /* Description */, IHighlight[] /* Detail */] {
return [this.labelHighlights, this.descriptionHighlights, this.detailHighlights];
}
/**
......@@ -358,8 +361,8 @@ export class QuickOpenEntryGroup extends QuickOpenEntry {
return this.entry ? this.entry.getLabel() : super.getLabel();
}
public getMeta(): string {
return this.entry ? this.entry.getMeta() : super.getMeta();
public getDetail(): string {
return this.entry ? this.entry.getDetail() : super.getDetail();
}
public getResource(): URI {
......@@ -378,7 +381,7 @@ export class QuickOpenEntryGroup extends QuickOpenEntry {
return this.entry;
}
public getHighlights(): [IHighlight[], IHighlight[]] {
public getHighlights(): [IHighlight[], IHighlight[], IHighlight[]] {
return this.entry ? this.entry.getHighlights() : super.getHighlights();
}
......@@ -446,7 +449,7 @@ export interface IQuickOpenEntryTemplateData {
icon: HTMLSpanElement;
prefix: HTMLSpanElement;
label: HighlightedLabel;
meta: HTMLSpanElement;
detail: HighlightedLabel;
description: HighlightedLabel;
actionBar: ActionBar;
}
......@@ -471,7 +474,9 @@ class Renderer implements IRenderer<QuickOpenEntry> {
if (entry instanceof QuickOpenEntryItem) {
return (<QuickOpenEntryItem>entry).getHeight();
}
if (entry.getDetail()) {
return 44;
}
return 22;
}
......@@ -533,26 +538,27 @@ class Renderer implements IRenderer<QuickOpenEntry> {
// Label
let label = new HighlightedLabel(entry);
// Meta
let meta = document.createElement('span');
entry.appendChild(meta);
DOM.addClass(meta, 'quick-open-entry-meta');
// Description
let descriptionContainer = document.createElement('span');
entry.appendChild(descriptionContainer);
DOM.addClass(descriptionContainer, 'quick-open-entry-description');
let description = new HighlightedLabel(descriptionContainer);
// Detail
let detailContainer = document.createElement('div');
entry.appendChild(detailContainer);
DOM.addClass(detailContainer, 'quick-open-entry-meta');
let detail = new HighlightedLabel(detailContainer);
return {
container: container,
icon: icon,
prefix: prefix,
label: label,
meta: meta,
description: description,
group: group,
actionBar: actionBar
container,
icon,
prefix,
label,
detail,
description,
group,
actionBar
};
}
......@@ -603,7 +609,7 @@ class Renderer implements IRenderer<QuickOpenEntry> {
// Normal Entry
if (entry instanceof QuickOpenEntry) {
let highlights = entry.getHighlights();
let [labelHighlights, descriptionHighlights, detailHighlights] = entry.getHighlights();
// Icon
let iconClass = entry.getIcon() ? ('quick-open-entry-icon ' + entry.getIcon()) : '';
......@@ -613,16 +619,14 @@ class Renderer implements IRenderer<QuickOpenEntry> {
let prefix = entry.getPrefix() || '';
data.prefix.textContent = prefix;
let labelHighlights = highlights[0];
data.label.set(entry.getLabel() || '', labelHighlights || []);
// Label
data.label.set(entry.getLabel(), labelHighlights || []);
// Meta
let metaLabel = entry.getMeta() || '';
data.meta.textContent = metaLabel;
data.detail.set(entry.getDetail(), detailHighlights);
// Description
let descriptionHighlights = highlights[1];
data.description.set(entry.getDescription() || '', descriptionHighlights || []);
data.description.set(entry.getDescription(), descriptionHighlights || []);
}
}
......
......@@ -75,7 +75,6 @@
.quick-open-widget .quick-open-tree .quick-open-entry-meta {
opacity: 0.7;
margin-left: 0.5em;
}
.quick-open-widget .quick-open-tree .quick-open-entry-description {
......
......@@ -26,18 +26,16 @@ var SCOPE_PREFIX = ':';
class SymbolEntry extends QuickOpenModel.QuickOpenEntryGroup {
private name:string;
private meta:string;
private type: string;
private description: string;
private range:EditorCommon.IRange;
private editor:EditorCommon.ICommonCodeEditor;
private decorator:EditorQuickOpen.IDecorator;
constructor(name:string, meta:string, type:string, description:string, range:EditorCommon.IRange, highlights:QuickOpenModel.IHighlight[], editor:EditorCommon.ICommonCodeEditor, decorator:EditorQuickOpen.IDecorator) {
constructor(name:string, type:string, description:string, range:EditorCommon.IRange, highlights:QuickOpenModel.IHighlight[], editor:EditorCommon.ICommonCodeEditor, decorator:EditorQuickOpen.IDecorator) {
super();
this.name = name;
this.meta = meta;
this.type = type;
this.description = description;
this.range = range;
......@@ -50,10 +48,6 @@ class SymbolEntry extends QuickOpenModel.QuickOpenEntryGroup {
return this.name;
}
public getMeta():string {
return this.meta;
}
public getIcon():string {
return this.type;
}
......@@ -210,18 +204,6 @@ export class QuickOutlineAction extends EditorQuickOpen.BaseEditorQuickOpenActio
for (var i = 0; i < flattened.length; i++) {
var element = flattened[i];
var label = Strings.trim(element.label);
var meta:string = null;
// Parse out parameters from method/function if present
if (element.type === 'method' || element.type === 'function') {
var indexOf = label.indexOf('(');
if (indexOf > 0) {
meta = label.substr(indexOf);
label = label.substr(0, indexOf);
} else {
meta = '()'; // otherwise make clear this is a method by adding ()
}
}
// Check for meatch
var highlights = Filters.matchesFuzzy(normalizedSearchValue, label);
......@@ -234,7 +216,7 @@ export class QuickOutlineAction extends EditorQuickOpen.BaseEditorQuickOpenActio
}
// Add
results.push(new SymbolEntry(label, meta, element.type, description, element.range, highlights, this.editor, this));
results.push(new SymbolEntry(label, element.type, description, element.range, highlights, this.editor, this));
}
}
......
......@@ -1059,14 +1059,19 @@ declare namespace vscode {
export interface QuickPickItem {
/**
* A label. Will be rendered prominent.
* A human readable string which is rendered prominent.
*/
label: string;
/**
* A description. Will be rendered less prominent.
* A human readable string which is rendered less prominent.
*/
description: string;
/**
* A human readable string which is rendered less prominent.
*/
detail?: string;
}
/**
......@@ -1078,6 +1083,11 @@ declare namespace vscode {
*/
matchOnDescription?: boolean;
/**
* An optional flag to include the detail when filtering the picks.
*/
matchOnDetail?: boolean;
/**
* An optional string to show as place holder in the input box to guide the user what to pick on.
*/
......
......@@ -40,7 +40,8 @@ export class ExtHostQuickOpen {
let quickPickWidget = this._proxy.$show({
autoFocus: { autoFocusFirstEntry: true },
placeHolder: options && options.placeHolder,
matchOnDescription: options && options.matchOnDescription
matchOnDescription: options && options.matchOnDescription,
matchOnDetail: options && options.matchOnDetail
});
return itemsPromise.then(items => {
......@@ -51,17 +52,20 @@ export class ExtHostQuickOpen {
let item = items[handle];
let label: string;
let description: string;
let detail: string;
if (typeof item === 'string') {
label = item;
} else {
label = item.label;
description = item.description;
detail = item.detail;
}
pickItems.push({
label,
description,
handle
handle,
detail
});
}
......
......@@ -269,7 +269,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
let model = new QuickOpenModel();
let entries = picks.map((e) => {
if (typeof e === 'string') {
return new PickOpenEntry(e, null, () => progress(e));
return new PickOpenEntry(e, null, null, () => progress(e));
}
let entry = (<IPickOpenEntryItem>e);
......@@ -278,7 +278,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
return new PickOpenItem(entry.label, entry.description, entry.height, entry.render.bind(entry), () => progress(e));
}
return new PickOpenEntry(entry.label, entry.description, () => progress(e));
return new PickOpenEntry(entry.label, entry.description, entry.detail, () => progress(e));
});
if (picks.length === 0) {
......@@ -338,16 +338,17 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
else {
entries.forEach((entry) => {
let labelHighlights = filters.matchesFuzzy(value, entry.getLabel());
let descriptionHighlights: filters.IMatch[] = null;
if (options.matchOnDescription) {
descriptionHighlights = filters.matchesFuzzy(value, entry.getDescription());
}
let descriptionHighlights = options.matchOnDescription
&& filters.matchesFuzzy(value, entry.getDescription());
let detailHighlights = options.matchOnDetail && entry.getDetail()
&& filters.matchesFuzzy(value, entry.getDetail());
if (labelHighlights || descriptionHighlights) {
entry.setHighlights(labelHighlights, descriptionHighlights);
if (labelHighlights || descriptionHighlights || detailHighlights) {
entry.setHighlights(labelHighlights, descriptionHighlights, detailHighlights);
entry.setHidden(false);
} else {
entry.setHighlights(null, null);
entry.setHighlights(null, null, null);
entry.setHidden(true);
}
});
......@@ -853,11 +854,13 @@ class PlaceholderQuickOpenEntry extends QuickOpenEntry {
class PickOpenEntry extends PlaceholderQuickOpenEntry {
private _selected: boolean;
private description: string;
private detail: string;
constructor(label: string, description?: string, private onPreview?: () => void) {
constructor(label: string, description?: string, detail?: string, private onPreview?: () => void) {
super(label);
this.description = description;
this.detail = detail;
}
public get selected(): boolean {
......@@ -868,6 +871,10 @@ class PickOpenEntry extends PlaceholderQuickOpenEntry {
return this.description;
}
public getDetail(): string {
return this.detail;
}
public run(mode: Mode, context: IContext): boolean {
if (mode === Mode.OPEN) {
this._selected = true;
......
......@@ -231,19 +231,17 @@ class SymbolEntry extends EditorQuickOpenEntryGroup {
private editorService: IWorkbenchEditorService;
private index: number;
private name: string;
private meta: string;
private type: string;
private icon: string;
private description: string;
private range: IRange;
private handler: GotoSymbolHandler;
constructor(index: number, name: string, meta: string, type: string, description: string, icon: string, range: IRange, highlights: IHighlight[], editorService: IWorkbenchEditorService, handler: GotoSymbolHandler) {
constructor(index: number, name: string, type: string, description: string, icon: string, range: IRange, highlights: IHighlight[], editorService: IWorkbenchEditorService, handler: GotoSymbolHandler) {
super();
this.index = index;
this.name = name;
this.meta = meta;
this.type = type;
this.icon = icon;
this.description = description;
......@@ -261,10 +259,6 @@ class SymbolEntry extends EditorQuickOpenEntryGroup {
return this.name;
}
public getMeta(): string {
return this.meta;
}
public getIcon(): string {
return this.icon;
}
......@@ -460,7 +454,6 @@ export class GotoSymbolHandler extends QuickOpenHandler {
for (let i = 0; i < flattened.length; i++) {
let element = flattened[i];
let label = strings.trim(element.label);
let meta: string = null;
// Show parent scope as description
let description: string = element.containerLabel;
......@@ -470,7 +463,7 @@ export class GotoSymbolHandler extends QuickOpenHandler {
// Add
let icon = element.icon || element.type;
results.push(new SymbolEntry(i, label, meta, element.type, description, icon, element.range, null, this.editorService, this));
results.push(new SymbolEntry(i, label, element.type, description, icon, element.range, null, this.editorService, this));
}
return results;
......
......@@ -14,6 +14,7 @@ export interface IPickOpenEntry {
id?: string;
label: string;
description?: string;
detail?: string;
}
export interface IPickOptions {
......@@ -32,6 +33,11 @@ export interface IPickOptions {
* an optional flag to include the description when filtering the picks
*/
matchOnDescription?: boolean;
/**
* an optional flag to include the detail when filtering the picks
*/
matchOnDetail?: boolean;
}
export interface IInputOptions {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册