mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-01 17:23:35 -05:00
Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 (#8911)
* Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 * update distro * fix layering * update distro * fix tests
This commit is contained in:
@@ -13,7 +13,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { IDebugSession, IDebugService, IDebugModel, CONTEXT_LOADED_SCRIPTS_ITEM_TYPE } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugSession, IDebugService, CONTEXT_LOADED_SCRIPTS_ITEM_TYPE } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
@@ -26,17 +26,19 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { ResourceLabels, IResourceLabelProps, IResourceLabelOptions, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeRenderer, ITreeNode, ITreeFilter, TreeVisibility, TreeFilterResult, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeNode, ITreeFilter, TreeVisibility, TreeFilterResult, ITreeElement } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { WorkbenchAsyncDataTree, TreeResourceNavigator2 } from 'vs/platform/list/browser/listService';
|
||||
import { TreeResourceNavigator2, WorkbenchCompressibleObjectTree } from 'vs/platform/list/browser/listService';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { createMatches, FuzzyScore } from 'vs/base/common/filters';
|
||||
import { DebugContentProvider } from 'vs/workbench/contrib/debug/common/debugContentProvider';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import type { ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import type { ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
|
||||
|
||||
const SMART = true;
|
||||
const NEW_STYLE_COMPRESS = true;
|
||||
|
||||
// RFC 2396, Appendix A: https://www.ietf.org/rfc/rfc2396.txt
|
||||
const URI_SCHEMA_PATTERN = /^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/;
|
||||
@@ -49,7 +51,7 @@ class BaseTreeItem {
|
||||
private _children = new Map<string, BaseTreeItem>();
|
||||
private _source: Source | undefined;
|
||||
|
||||
constructor(private _parent: BaseTreeItem | undefined, private _label: string) {
|
||||
constructor(private _parent: BaseTreeItem | undefined, private _label: string, public readonly isIncompressible = false) {
|
||||
this._showedMoreThanOne = false;
|
||||
}
|
||||
|
||||
@@ -150,7 +152,7 @@ class BaseTreeItem {
|
||||
}
|
||||
|
||||
// skips intermediate single-child nodes
|
||||
getChildren(): Promise<BaseTreeItem[]> {
|
||||
getChildren(): BaseTreeItem[] {
|
||||
const child = this.oneChild();
|
||||
if (child) {
|
||||
return child.getChildren();
|
||||
@@ -159,7 +161,7 @@ class BaseTreeItem {
|
||||
for (let child of this._children.values()) {
|
||||
array.push(child);
|
||||
}
|
||||
return Promise.resolve(array.sort((a, b) => this.compare(a, b)));
|
||||
return array.sort((a, b) => this.compare(a, b));
|
||||
}
|
||||
|
||||
// skips intermediate single-child nodes
|
||||
@@ -205,7 +207,7 @@ class BaseTreeItem {
|
||||
}
|
||||
|
||||
private oneChild(): BaseTreeItem | undefined {
|
||||
if (SMART && !this._source && !this._showedMoreThanOne && !(this instanceof RootFolderTreeItem) && !(this instanceof SessionTreeItem)) {
|
||||
if (!this._source && !this._showedMoreThanOne && this.skipOneChild()) {
|
||||
if (this._children.size === 1) {
|
||||
return this._children.values().next().value;
|
||||
}
|
||||
@@ -216,22 +218,28 @@ class BaseTreeItem {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private skipOneChild(): boolean {
|
||||
if (NEW_STYLE_COMPRESS) {
|
||||
// if the root node has only one Session, don't show the session
|
||||
return this instanceof RootTreeItem;
|
||||
} else {
|
||||
return !(this instanceof RootFolderTreeItem) && !(this instanceof SessionTreeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RootFolderTreeItem extends BaseTreeItem {
|
||||
|
||||
constructor(parent: BaseTreeItem, public folder: IWorkspaceFolder) {
|
||||
super(parent, folder.name);
|
||||
super(parent, folder.name, true);
|
||||
}
|
||||
}
|
||||
|
||||
class RootTreeItem extends BaseTreeItem {
|
||||
|
||||
constructor(private _debugModel: IDebugModel, private _environmentService: IEnvironmentService, private _contextService: IWorkspaceContextService, private _labelService: ILabelService) {
|
||||
constructor(private _environmentService: IEnvironmentService, private _contextService: IWorkspaceContextService, private _labelService: ILabelService) {
|
||||
super(undefined, 'Root');
|
||||
this._debugModel.getSessions().forEach(session => {
|
||||
this.add(session);
|
||||
});
|
||||
}
|
||||
|
||||
add(session: IDebugSession): SessionTreeItem {
|
||||
@@ -248,14 +256,12 @@ class SessionTreeItem extends BaseTreeItem {
|
||||
private static readonly URL_REGEXP = /^(https?:\/\/[^/]+)(\/.*)$/;
|
||||
|
||||
private _session: IDebugSession;
|
||||
private _initialized: boolean;
|
||||
private _map = new Map<string, BaseTreeItem>();
|
||||
private _labelService: ILabelService;
|
||||
|
||||
constructor(labelService: ILabelService, parent: BaseTreeItem, session: IDebugSession, private _environmentService: IEnvironmentService, private rootProvider: IWorkspaceContextService) {
|
||||
super(parent, session.getLabel());
|
||||
super(parent, session.getLabel(), true);
|
||||
this._labelService = labelService;
|
||||
this._initialized = false;
|
||||
this._session = session;
|
||||
}
|
||||
|
||||
@@ -275,19 +281,6 @@ class SessionTreeItem extends BaseTreeItem {
|
||||
return true;
|
||||
}
|
||||
|
||||
getChildren(): Promise<BaseTreeItem[]> {
|
||||
|
||||
if (!this._initialized) {
|
||||
this._initialized = true;
|
||||
return this._session.getLoadedSources().then(paths => {
|
||||
paths.forEach(path => this.addPath(path));
|
||||
return super.getChildren();
|
||||
});
|
||||
}
|
||||
|
||||
return super.getChildren();
|
||||
}
|
||||
|
||||
protected compare(a: BaseTreeItem, b: BaseTreeItem): number {
|
||||
const acat = this.category(a);
|
||||
const bcat = this.category(b);
|
||||
@@ -388,11 +381,30 @@ class SessionTreeItem extends BaseTreeItem {
|
||||
}
|
||||
}
|
||||
|
||||
interface IViewState {
|
||||
readonly expanded: Set<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This maps a model item into a view model item.
|
||||
*/
|
||||
function asTreeElement(item: BaseTreeItem, viewState?: IViewState): ITreeElement<LoadedScriptsItem> {
|
||||
const children = item.getChildren();
|
||||
const collapsed = viewState ? !viewState.expanded.has(item.getId()) : !(item instanceof SessionTreeItem);
|
||||
|
||||
return {
|
||||
element: item,
|
||||
collapsed,
|
||||
collapsible: item.hasChildren(),
|
||||
children: children.map(i => asTreeElement(i, viewState))
|
||||
};
|
||||
}
|
||||
|
||||
export class LoadedScriptsView extends ViewPane {
|
||||
|
||||
private treeContainer!: HTMLElement;
|
||||
private loadedScriptsItemType: IContextKey<string>;
|
||||
private tree!: WorkbenchAsyncDataTree<LoadedScriptsItem, LoadedScriptsItem, FuzzyScore>;
|
||||
private tree!: WorkbenchCompressibleObjectTree<LoadedScriptsItem, FuzzyScore>;
|
||||
private treeLabels!: ResourceLabels;
|
||||
private changeScheduler!: RunOnceScheduler;
|
||||
private treeNeedsRefreshOnVisible = false;
|
||||
@@ -402,7 +414,7 @@ export class LoadedScriptsView extends ViewPane {
|
||||
options: IViewletViewOptions,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IContextKeyService readonly contextKeyService: IContextKeyService,
|
||||
@@ -411,7 +423,7 @@ export class LoadedScriptsView extends ViewPane {
|
||||
@IDebugService private readonly debugService: IDebugService,
|
||||
@ILabelService private readonly labelService: ILabelService
|
||||
) {
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService);
|
||||
}
|
||||
|
||||
@@ -423,20 +435,30 @@ export class LoadedScriptsView extends ViewPane {
|
||||
|
||||
this.filter = new LoadedScriptsFilter();
|
||||
|
||||
const root = new RootTreeItem(this.debugService.getModel(), this.environmentService, this.contextService, this.labelService);
|
||||
const root = new RootTreeItem(this.environmentService, this.contextService, this.labelService);
|
||||
|
||||
this.treeLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility });
|
||||
this._register(this.treeLabels);
|
||||
|
||||
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<LoadedScriptsItem, LoadedScriptsItem, FuzzyScore>>(WorkbenchAsyncDataTree, 'LoadedScriptsView', this.treeContainer, new LoadedScriptsDelegate(),
|
||||
this.tree = this.instantiationService.createInstance(WorkbenchCompressibleObjectTree,
|
||||
'LoadedScriptsView',
|
||||
this.treeContainer,
|
||||
new LoadedScriptsDelegate(),
|
||||
[new LoadedScriptsRenderer(this.treeLabels)],
|
||||
new LoadedScriptsDataSource(),
|
||||
{
|
||||
compressionEnabled: NEW_STYLE_COMPRESS,
|
||||
collapseByDefault: true,
|
||||
hideTwistiesOfChildlessElements: true,
|
||||
identityProvider: {
|
||||
getId: (element: LoadedScriptsItem) => element.getId()
|
||||
},
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: (element: LoadedScriptsItem) => element.getLabel()
|
||||
getKeyboardNavigationLabel: (element: LoadedScriptsItem) => {
|
||||
return element.getLabel();
|
||||
},
|
||||
getCompressedNodeKeyboardNavigationLabel: (elements: LoadedScriptsItem[]) => {
|
||||
return elements.map(e => e.getLabel()).join('/');
|
||||
}
|
||||
},
|
||||
filter: this.filter,
|
||||
accessibilityProvider: new LoadedSciptsAccessibilityProvider(),
|
||||
@@ -447,12 +469,14 @@ export class LoadedScriptsView extends ViewPane {
|
||||
}
|
||||
);
|
||||
|
||||
this.tree.setInput(root);
|
||||
const updateView = (viewState?: IViewState) => this.tree.setChildren(null, asTreeElement(root, viewState).children);
|
||||
|
||||
updateView();
|
||||
|
||||
this.changeScheduler = new RunOnceScheduler(() => {
|
||||
this.treeNeedsRefreshOnVisible = false;
|
||||
if (this.tree) {
|
||||
this.tree.updateChildren();
|
||||
updateView();
|
||||
}
|
||||
}, 300);
|
||||
this._register(this.changeScheduler);
|
||||
@@ -486,12 +510,19 @@ export class LoadedScriptsView extends ViewPane {
|
||||
}
|
||||
};
|
||||
|
||||
const addSourcePathsToSession = (session: IDebugSession) => {
|
||||
const sessionNode = root.add(session);
|
||||
return session.getLoadedSources().then(paths => {
|
||||
paths.forEach(path => sessionNode.addPath(path));
|
||||
scheduleRefreshOnVisible();
|
||||
});
|
||||
};
|
||||
|
||||
const registerSessionListeners = (session: IDebugSession) => {
|
||||
this._register(session.onDidChangeName(() => {
|
||||
// Re-add session, this will trigger proper sorting and id recalculation.
|
||||
root.remove(session.getId());
|
||||
root.add(session);
|
||||
scheduleRefreshOnVisible();
|
||||
addSourcePathsToSession(session);
|
||||
}));
|
||||
this._register(session.onDidLoadedSource(event => {
|
||||
let sessionRoot: SessionTreeItem;
|
||||
@@ -534,6 +565,38 @@ export class LoadedScriptsView extends ViewPane {
|
||||
this.changeScheduler.schedule();
|
||||
}
|
||||
}));
|
||||
|
||||
// feature: expand all nodes when filtering (not when finding)
|
||||
let viewState: IViewState | undefined;
|
||||
this._register(this.tree.onDidChangeTypeFilterPattern(pattern => {
|
||||
if (!this.tree.options.filterOnType) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!viewState && pattern) {
|
||||
const expanded = new Set<string>();
|
||||
const visit = (node: ITreeNode<BaseTreeItem | null, FuzzyScore>) => {
|
||||
if (node.element && !node.collapsed) {
|
||||
expanded.add(node.element.getId());
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
visit(child);
|
||||
}
|
||||
};
|
||||
|
||||
visit(this.tree.getNode());
|
||||
viewState = { expanded };
|
||||
this.tree.expandAll();
|
||||
} else if (!pattern && viewState) {
|
||||
this.tree.setFocus([]);
|
||||
updateView(viewState);
|
||||
viewState = undefined;
|
||||
}
|
||||
}));
|
||||
|
||||
// populate tree model with source paths from all debug sessions
|
||||
this.debugService.getModel().getSessions().forEach(session => addSourcePathsToSession(session));
|
||||
}
|
||||
|
||||
layoutBody(height: number, width: number): void {
|
||||
@@ -558,22 +621,11 @@ class LoadedScriptsDelegate implements IListVirtualDelegate<LoadedScriptsItem> {
|
||||
}
|
||||
}
|
||||
|
||||
class LoadedScriptsDataSource implements IAsyncDataSource<LoadedScriptsItem, LoadedScriptsItem> {
|
||||
|
||||
hasChildren(element: LoadedScriptsItem): boolean {
|
||||
return element.hasChildren();
|
||||
}
|
||||
|
||||
getChildren(element: LoadedScriptsItem): Promise<LoadedScriptsItem[]> {
|
||||
return element.getChildren();
|
||||
}
|
||||
}
|
||||
|
||||
interface ILoadedScriptsItemTemplateData {
|
||||
label: IResourceLabel;
|
||||
}
|
||||
|
||||
class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, FuzzyScore, ILoadedScriptsItemTemplateData> {
|
||||
class LoadedScriptsRenderer implements ICompressibleTreeRenderer<BaseTreeItem, FuzzyScore, ILoadedScriptsItemTemplateData> {
|
||||
|
||||
static readonly ID = 'lsrenderer';
|
||||
|
||||
@@ -594,9 +646,23 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, FuzzyScore, I
|
||||
renderElement(node: ITreeNode<BaseTreeItem, FuzzyScore>, index: number, data: ILoadedScriptsItemTemplateData): void {
|
||||
|
||||
const element = node.element;
|
||||
const label = element.getLabel();
|
||||
|
||||
this.render(element, label, data, node.filterData);
|
||||
}
|
||||
|
||||
renderCompressedElements(node: ITreeNode<ICompressedTreeNode<BaseTreeItem>, FuzzyScore>, index: number, data: ILoadedScriptsItemTemplateData, height: number | undefined): void {
|
||||
|
||||
const element = node.element.elements[node.element.elements.length - 1];
|
||||
const labels = node.element.elements.map(e => e.getLabel());
|
||||
|
||||
this.render(element, labels, data, node.filterData);
|
||||
}
|
||||
|
||||
private render(element: BaseTreeItem, labels: string | string[], data: ILoadedScriptsItemTemplateData, filterData: FuzzyScore | undefined) {
|
||||
|
||||
const label: IResourceLabelProps = {
|
||||
name: element.getLabel()
|
||||
name: labels
|
||||
};
|
||||
const options: IResourceLabelOptions = {
|
||||
title: element.getHoverLabel()
|
||||
@@ -621,7 +687,7 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, FuzzyScore, I
|
||||
options.fileKind = FileKind.FOLDER;
|
||||
}
|
||||
}
|
||||
options.matches = createMatches(node.filterData);
|
||||
options.matches = createMatches(filterData);
|
||||
|
||||
data.label.setResource(label, options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user