Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1141,4 +1141,35 @@ declare module 'vscode' {
alwaysShow?: boolean;
}
//#endregion

//#region Tree Item Label Highlights
/**
* Label describing the [Tree item](#TreeItem)
*/
export interface TreeItemLabel {

/**
* A human-readable string describing the [Tree item](#TreeItem).
*/
label: string;

/**
* Ranges in the label to highlight.
*/
highlights?: [number, number][];

}

export class TreeItem2 extends TreeItem {
/**
* Label describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri).
*/
label?: string | TreeItemLabel | /* for compilation */ any;

/**
* @param label Label describing this item
* @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None)
*/
constructor(label: TreeItemLabel, collapsibleState?: TreeItemCollapsibleState);
}
}
1 change: 1 addition & 0 deletions src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ export function createApiFactory(
ThemeColor: extHostTypes.ThemeColor,
ThemeIcon: extHostTypes.ThemeIcon,
TreeItem: extHostTypes.TreeItem,
TreeItem2: extHostTypes.TreeItem,
TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState,
Uri: URI,
ViewColumn: extHostTypes.ViewColumn,
Expand Down
29 changes: 25 additions & 4 deletions src/vs/workbench/api/node/extHostTreeViews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,36 @@ import { URI } from 'vs/base/common/uri';
import { debounceEvent, Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol';
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/common/views';
import { ITreeItem, TreeViewItemHandleArg, ITreeItemLabel } from 'vs/workbench/common/views';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
import { asThenable } from 'vs/base/common/async';
import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/node/extHostTypes';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { isUndefinedOrNull, isString } from 'vs/base/common/types';
import { equals } from 'vs/base/common/arrays';
import { ILogService } from 'vs/platform/log/common/log';

type TreeItemHandle = string;

function toTreeItemLabel(label: any): ITreeItemLabel {
if (isString(label)) {
return { label };
}

if (label
&& typeof label === 'object'
&& typeof label.label === 'string') {
let highlights: [number, number][] = void 0;
if (Array.isArray(label.highlights)) {
highlights = (<[number, number][]>label.highlights).filter((highlight => highlight.length === 2 && typeof highlight[0] === 'number' && typeof highlight[1] === 'number'));
highlights = highlights.length ? highlights : void 0;
}
return { label: label.label, highlights };
}

return void 0;
}


export class ExtHostTreeViews implements ExtHostTreeViewsShape {

private treeViews: Map<string, ExtHostTreeView<any>> = new Map<string, ExtHostTreeView<any>>();
Expand Down Expand Up @@ -383,7 +403,7 @@ class ExtHostTreeView<T> extends Disposable {
const item = {
handle,
parentHandle: parent ? parent.item.handle : void 0,
label: extensionTreeItem.label,
label: toTreeItemLabel(extensionTreeItem.label),
resourceUri: extensionTreeItem.resourceUri,
tooltip: typeof extensionTreeItem.tooltip === 'string' ? extensionTreeItem.tooltip : void 0,
command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command) : void 0,
Expand All @@ -402,8 +422,9 @@ class ExtHostTreeView<T> extends Disposable {
return `${ExtHostTreeView.ID_HANDLE_PREFIX}/${id}`;
}

const treeItemLabel = toTreeItemLabel(label);
const prefix: string = parent ? parent.item.handle : ExtHostTreeView.LABEL_HANDLE_PREFIX;
let elementId = label ? label : resourceUri ? basename(resourceUri.path) : '';
let elementId = treeItemLabel ? treeItemLabel.label : resourceUri ? basename(resourceUri.path) : '';
elementId = elementId.indexOf('/') !== -1 ? elementId.replace('/', '//') : elementId;
const existingHandle = this.nodes.has(element) ? this.nodes.get(element).item.handle : void 0;
const childrenNodes = (this.getChildrenNodes(parent) || []);
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/api/node/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1791,16 +1791,16 @@ export enum ProgressLocation {

export class TreeItem {

label?: string;
label?: string | vscode.TreeItemLabel;
resourceUri?: URI;
iconPath?: string | URI | { light: string | URI; dark: string | URI };
command?: vscode.Command;
contextValue?: string;
tooltip?: string;

constructor(label: string, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(arg1: string | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) {
constructor(arg1: string | vscode.TreeItemLabel | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) {
if (arg1 instanceof URI) {
this.resourceUri = arg1;
} else {
Expand Down
14 changes: 8 additions & 6 deletions src/vs/workbench/browser/parts/views/customView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuItemActionItem, fillInActionBarActions, fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewsService, ITreeViewer, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer } from 'vs/workbench/common/views';
import { IViewsService, ITreeViewer, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views';
import { IViewletViewOptions, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
Expand Down Expand Up @@ -164,7 +164,7 @@ class TitleMenus implements IDisposable {
}

class Root implements ITreeItem {
label = 'root';
label = { label: 'root' };
handle = '0';
parentHandle = null;
collapsibleState = TreeItemCollapsibleState.Expanded;
Expand Down Expand Up @@ -513,7 +513,7 @@ class TreeRenderer implements IRenderer {
DOM.addClass(container, 'custom-view-tree-node-item');

const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, {});
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, { supportHighlights: true });
DOM.addClass(resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
const actionsContainer = DOM.append(resourceLabel.element, DOM.$('.actions'));
const actionBar = new ActionBar(actionsContainer, {
Expand All @@ -526,7 +526,9 @@ class TreeRenderer implements IRenderer {

renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void {
const resource = node.resourceUri ? URI.revive(node.resourceUri) : null;
const label = node.label ? node.label : resource ? basename(resource.path) : '';
const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource.path) } : void 0;
const label = treeItemLabel ? treeItemLabel.label : void 0;
const matches = treeItemLabel ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : void 0;
const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark;
const iconUrl = icon ? URI.revive(icon) : null;
const title = node.tooltip ? node.tooltip : resource ? void 0 : label;
Expand All @@ -537,9 +539,9 @@ class TreeRenderer implements IRenderer {

if (resource || node.themeIcon) {
const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] });
templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
} else {
templateData.resourceLabel.setLabel({ name: label }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'] });
templateData.resourceLabel.setLabel({ name: label }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
}

templateData.icon.style.backgroundImage = iconUrl ? `url('${iconUrl.toString(true)}')` : '';
Expand Down
10 changes: 9 additions & 1 deletion src/vs/workbench/common/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,14 @@ export enum TreeItemCollapsibleState {
Expanded = 2
}

export interface ITreeItemLabel {

label: string;

highlights?: [number, number][];

}

export interface ITreeItem {

handle: string;
Expand All @@ -288,7 +296,7 @@ export interface ITreeItem {

collapsibleState: TreeItemCollapsibleState;

label?: string;
label?: ITreeItemLabel;

icon?: UriComponents;

Expand Down
Loading