Refresh master with initial release/0.24 snapshot (#332)

* Initial port of release/0.24 source code

* Fix additional headers

* Fix a typo in launch.json
This commit is contained in:
Karl Burtram
2017-12-15 15:38:57 -08:00
committed by GitHub
parent 271b3a0b82
commit 6ad0df0e3e
7118 changed files with 107999 additions and 56466 deletions

View File

@@ -1,191 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import collections = require('vs/base/common/collections');
import { Registry } from 'vs/platform/registry/common/platform';
import { IAction } from 'vs/base/common/actions';
import { KeybindingsRegistry, ICommandAndKeybindingRule } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IMessageService } from 'vs/platform/message/common/message';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import Severity from 'vs/base/common/severity';
export const Extensions = {
WorkbenchActions: 'workbench.contributions.actions'
};
export interface IActionProvider {
getActions(): IAction[];
}
export interface IWorkbenchActionRegistry {
/**
* Registers a workbench action to the platform. Workbench actions are not
* visible by default and can only be invoked through a keybinding if provided.
*/
registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string): void;
/**
* Unregisters a workbench action from the platform.
*/
unregisterWorkbenchAction(id: string): boolean;
/**
* Returns the workbench action descriptor for the given id or null if none.
*/
getWorkbenchAction(id: string): SyncActionDescriptor;
/**
* Returns an array of registered workbench actions known to the platform.
*/
getWorkbenchActions(): SyncActionDescriptor[];
/**
* Returns the alias associated with the given action or null if none.
*/
getAlias(actionId: string): string;
/**
* Returns the category for the given action or null if none.
*/
getCategory(actionId: string): string;
}
interface IActionMeta {
alias: string;
category?: string;
}
class WorkbenchActionRegistry implements IWorkbenchActionRegistry {
private workbenchActions: collections.IStringDictionary<SyncActionDescriptor>;
private mapActionIdToMeta: { [id: string]: IActionMeta; };
constructor() {
this.workbenchActions = Object.create(null);
this.mapActionIdToMeta = Object.create(null);
}
public registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string): void {
if (!this.workbenchActions[descriptor.id]) {
this.workbenchActions[descriptor.id] = descriptor;
registerWorkbenchCommandFromAction(descriptor);
let meta: IActionMeta = { alias };
if (typeof category === 'string') {
meta.category = category;
}
this.mapActionIdToMeta[descriptor.id] = meta;
}
}
public unregisterWorkbenchAction(id: string): boolean {
if (!this.workbenchActions[id]) {
return false;
}
delete this.workbenchActions[id];
delete this.mapActionIdToMeta[id];
return true;
}
public getWorkbenchAction(id: string): SyncActionDescriptor {
return this.workbenchActions[id] || null;
}
public getCategory(id: string): string {
return (this.mapActionIdToMeta[id] && this.mapActionIdToMeta[id].category) || null;
}
public getAlias(id: string): string {
return (this.mapActionIdToMeta[id] && this.mapActionIdToMeta[id].alias) || null;
}
public getWorkbenchActions(): SyncActionDescriptor[] {
return collections.values(this.workbenchActions);
}
public setWorkbenchActions(actions: SyncActionDescriptor[]): void {
this.workbenchActions = Object.create(null);
this.mapActionIdToMeta = Object.create(null);
actions.forEach(action => this.registerWorkbenchAction(action, ''), this);
}
}
Registry.add(Extensions.WorkbenchActions, new WorkbenchActionRegistry());
function registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor): void {
let when = descriptor.keybindingContext;
let weight = (typeof descriptor.keybindingWeight === 'undefined' ? KeybindingsRegistry.WEIGHT.workbenchContrib() : descriptor.keybindingWeight);
let keybindings = descriptor.keybindings;
let desc: ICommandAndKeybindingRule = {
id: descriptor.id,
handler: createCommandHandler(descriptor),
weight: weight,
when: when,
primary: keybindings && keybindings.primary,
secondary: keybindings && keybindings.secondary,
win: keybindings && keybindings.win,
mac: keybindings && keybindings.mac,
linux: keybindings && keybindings.linux
};
KeybindingsRegistry.registerCommandAndKeybindingRule(desc);
}
export function createCommandHandler(descriptor: SyncActionDescriptor): ICommandHandler {
return (accessor, args) => {
let messageService = accessor.get(IMessageService);
let instantiationService = accessor.get(IInstantiationService);
let telemetryService = accessor.get(ITelemetryService);
let partService = accessor.get(IPartService);
TPromise.as(triggerAndDisposeAction(instantiationService, telemetryService, partService, descriptor, args)).done(null, (err) => {
messageService.show(Severity.Error, err);
});
};
}
export function triggerAndDisposeAction(instantitationService: IInstantiationService, telemetryService: ITelemetryService, partService: IPartService, descriptor: SyncActionDescriptor, args: any): TPromise<any> {
let actionInstance = instantitationService.createInstance(descriptor.syncDescriptor);
actionInstance.label = descriptor.label || actionInstance.label;
// don't run the action when not enabled
if (!actionInstance.enabled) {
actionInstance.dispose();
return void 0;
}
const from = args && args.from || 'keybinding';
if (telemetryService) {
telemetryService.publicLog('workbenchActionExecuted', { id: actionInstance.id, from });
}
// run action when workbench is created
return partService.joinCreation().then(() => {
try {
return TPromise.as(actionInstance.run(undefined, { from })).then(() => {
actionInstance.dispose();
}, (err) => {
actionInstance.dispose();
return TPromise.wrapError(err);
});
} catch (err) {
actionInstance.dispose();
return TPromise.wrapError(err);
}
});
}

View File

@@ -0,0 +1,126 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { Registry } from 'vs/platform/registry/common/platform';
import { IAction } from 'vs/base/common/actions';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { IMessageService } from 'vs/platform/message/common/message';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import Severity from 'vs/base/common/severity';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
export const Extensions = {
WorkbenchActions: 'workbench.contributions.actions'
};
export interface IActionProvider {
getActions(): IAction[];
}
export interface IWorkbenchActionRegistry {
/**
* Registers a workbench action to the platform. Workbench actions are not
* visible by default and can only be invoked through a keybinding if provided.
*/
registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string): IDisposable;
}
Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionRegistry {
registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string): IDisposable {
return this._registerWorkbenchCommandFromAction(descriptor, alias, category);
}
private _registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor, alias: string, category?: string): IDisposable {
let registrations: IDisposable[] = [];
// command
registrations.push(CommandsRegistry.registerCommand(descriptor.id, this._createCommandHandler(descriptor)));
// keybinding
const when = descriptor.keybindingContext;
const weight = (typeof descriptor.keybindingWeight === 'undefined' ? KeybindingsRegistry.WEIGHT.workbenchContrib() : descriptor.keybindingWeight);
const keybindings = descriptor.keybindings;
KeybindingsRegistry.registerKeybindingRule({
id: descriptor.id,
weight: weight,
when: when,
primary: keybindings && keybindings.primary,
secondary: keybindings && keybindings.secondary,
win: keybindings && keybindings.win,
mac: keybindings && keybindings.mac,
linux: keybindings && keybindings.linux
});
// menu item
// TODO@Rob slightly weird if-check required because of
// https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/search/browser/search.contribution.ts#L266
if (descriptor.label) {
const command = {
id: descriptor.id,
title: { value: descriptor.label, original: alias },
category
};
MenuRegistry.addCommand(command);
registrations.push(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command }));
}
// TODO@alex,joh
// support removal of keybinding rule
// support removal of command-ui
return combinedDisposable(registrations);
}
private _createCommandHandler(descriptor: SyncActionDescriptor): ICommandHandler {
return (accessor, args) => {
const messageService = accessor.get(IMessageService);
const instantiationService = accessor.get(IInstantiationService);
const partService = accessor.get(IPartService);
TPromise.as(this._triggerAndDisposeAction(instantiationService, partService, descriptor, args)).done(null, (err) => {
messageService.show(Severity.Error, err);
});
};
}
private _triggerAndDisposeAction(instantitationService: IInstantiationService, partService: IPartService, descriptor: SyncActionDescriptor, args: any): TPromise<any> {
const actionInstance = instantitationService.createInstance(descriptor.syncDescriptor);
actionInstance.label = descriptor.label || actionInstance.label;
// don't run the action when not enabled
if (!actionInstance.enabled) {
actionInstance.dispose();
return void 0;
}
const from = args && args.from || 'keybinding';
// run action when workbench is created
return partService.joinCreation().then(() => {
try {
return TPromise.as(actionInstance.run(undefined, { from })).then(() => {
actionInstance.dispose();
}, (err) => {
actionInstance.dispose();
return TPromise.wrapError(err);
});
} catch (err) {
actionInstance.dispose();
return TPromise.wrapError(err);
}
});
}
});

View File

@@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Registry } from 'vs/platform/registry/common/platform';
import { IAction } from 'vs/base/common/actions';
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
export interface IActivity {
id: string;
name: string;
keybindingId?: string;
cssClass: string;
}
export interface IGlobalActivity extends IActivity {
getActions(): IAction[];
}
export const GlobalActivityExtensions = 'workbench.contributions.globalActivities';
export interface IGlobalActivityRegistry {
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void;
getActivities(): IConstructorSignature0<IGlobalActivity>[];
}
export class GlobalActivityRegistry implements IGlobalActivityRegistry {
private activityDescriptors = new Set<IConstructorSignature0<IGlobalActivity>>();
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void {
this.activityDescriptors.add(descriptor);
}
getActivities(): IConstructorSignature0<IGlobalActivity>[] {
const result: IConstructorSignature0<IGlobalActivity>[] = [];
this.activityDescriptors.forEach(d => result.push(d));
return result;
}
}
Registry.add(GlobalActivityExtensions, new GlobalActivityRegistry());

View File

@@ -11,10 +11,10 @@ import types = require('vs/base/common/types');
import URI from 'vs/base/common/uri';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { IEditor, IEditorViewState, IModel, ScrollType } from 'vs/editor/common/editorCommon';
import { IEditorInput, IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceInput, Position, Verbosity } from 'vs/platform/editor/common/editor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IEditorInput, IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceInput, Position, Verbosity, IEditor as IBaseEditor } from 'vs/platform/editor/common/editor';
import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { Registry } from 'vs/platform/registry/common/platform';
export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareEditorVisible', false);
@@ -24,19 +24,6 @@ export enum ConfirmResult {
CANCEL
}
export interface IEditorDescriptor {
getId(): string;
getName(): string;
describes(obj: any): boolean;
}
export const Extensions = {
Editors: 'workbench.contributions.editors'
};
/**
* Text diff editor id.
*/
@@ -51,34 +38,7 @@ export interface IFileInputFactory {
createFileInput(resource: URI, encoding: string, instantiationService: IInstantiationService): IFileEditorInput;
}
export interface IEditorRegistry {
/**
* Registers an editor to the platform for the given input type. The second parameter also supports an
* array of input classes to be passed in. If the more than one editor is registered for the same editor
* input, the input itself will be asked which editor it prefers if this method is provided. Otherwise
* the first editor in the list will be returned.
*
* @param editorInputDescriptor a constructor function that returns an instance of EditorInput for which the
* registered editor should be used for.
*/
registerEditor(descriptor: IEditorDescriptor, editorInputDescriptor: SyncDescriptor<EditorInput>): void;
registerEditor(descriptor: IEditorDescriptor, editorInputDescriptor: SyncDescriptor<EditorInput>[]): void;
/**
* Returns the editor descriptor for the given input or null if none.
*/
getEditor(input: EditorInput): IEditorDescriptor;
/**
* Returns the editor descriptor for the given identifier or null if none.
*/
getEditorById(editorId: string): IEditorDescriptor;
/**
* Returns an array of registered editors known to the platform.
*/
getEditors(): IEditorDescriptor[];
export interface IEditorInputFactoryRegistry {
/**
* Registers the file input factory to use for file inputs.
@@ -164,6 +124,13 @@ export abstract class EditorInput implements IEditorInput {
return this._onDispose.event;
}
/**
* Returns the associated resource of this input if any.
*/
public getResource(): URI {
return null;
}
/**
* Returns the name of this input that can be shown to the user. Examples include showing the name of the input
* above the editor area when the input is shown.
@@ -176,7 +143,7 @@ export abstract class EditorInput implements IEditorInput {
* Returns the description of this input that can be shown to the user. Examples include showing the description of
* the input above the editor area to the side of the name of the input.
*/
public getDescription(): string {
public getDescription(verbosity?: Verbosity): string {
return null;
}
@@ -207,6 +174,11 @@ export abstract class EditorInput implements IEditorInput {
* Subclasses should extend if they can contribute.
*/
public getTelemetryDescriptor(): object {
/* __GDPR__FRAGMENT__
"EditorTelemetryDescriptor" : {
"typeId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
return { typeId: this.getTypeId() };
}
@@ -289,6 +261,48 @@ export abstract class EditorInput implements IEditorInput {
}
}
export interface IEditorOpeningEvent {
input: IEditorInput;
options?: IEditorOptions;
position: Position;
/**
* Allows to prevent the opening of an editor by providing a callback
* that will be executed instead. By returning another editor promise
* it is possible to override the opening with another editor. It is ok
* to return a promise that resolves to NULL to prevent the opening
* altogether.
*/
prevent(callback: () => TPromise<IBaseEditor>): void;
}
export class EditorOpeningEvent {
private override: () => TPromise<IBaseEditor>;
constructor(private _input: IEditorInput, private _options: IEditorOptions, private _position: Position) {
}
public get input(): IEditorInput {
return this._input;
}
public get options(): IEditorOptions {
return this._options;
}
public get position(): Position {
return this._position;
}
public prevent(callback: () => TPromise<IBaseEditor>): void {
this.override = callback;
}
public isPrevented(): () => TPromise<IBaseEditor> {
return this.override;
}
}
export enum EncodingMode {
/**
@@ -321,11 +335,6 @@ export interface IEncodingSupport {
*/
export interface IFileEditorInput extends IEditorInput, IEncodingSupport {
/**
* Gets the absolute file resource URI this input is about.
*/
getResource(): URI;
/**
* Sets the preferred encodingt to use for this input.
*/
@@ -796,7 +805,22 @@ export const EditorOpenPositioning = {
LAST: 'last'
};
export const OPEN_POSITIONING_CONFIG = 'workbench.editor.openPositioning';
export interface IWorkbenchEditorConfiguration {
/* __GDPR__FRAGMENT__
"IWorkbenchEditorConfiguration" : {
"showTabs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"tabCloseButton": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"showIcons": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"enablePreview": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"enablePreviewFromQuickOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"closeOnFileDelete": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"openPositioning": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"revealIfOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"swipeToNavigate": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
workbench: {
editor: {
showTabs: boolean;
@@ -807,7 +831,8 @@ export interface IWorkbenchEditorConfiguration {
closeOnFileDelete: boolean;
openPositioning: 'left' | 'right' | 'first' | 'last';
revealIfOpen: boolean;
swipeToNavigate: boolean
swipeToNavigate: boolean,
labelFormat: 'default' | 'short' | 'medium' | 'long';
}
};
}
@@ -841,10 +866,6 @@ export interface IResourceOptions {
filter?: 'file' | 'untitled' | ['file', 'untitled'] | ['untitled', 'file'];
}
export function hasResource(editor: IEditorInput, options?: IResourceOptions): boolean {
return !!toResource(editor, options);
}
export function toResource(editor: IEditorInput, options?: IResourceOptions): URI {
if (!editor) {
return null;
@@ -855,7 +876,7 @@ export function toResource(editor: IEditorInput, options?: IResourceOptions): UR
editor = editor.master;
}
const resource = doGetEditorResource(editor);
const resource = editor.getResource();
if (!options || !options.filter) {
return resource; // return early if no filter is specified
}
@@ -885,14 +906,54 @@ export function toResource(editor: IEditorInput, options?: IResourceOptions): UR
return null;
}
// TODO@Ben every editor should have an associated resource
function doGetEditorResource(editor: IEditorInput): URI {
if (editor instanceof EditorInput && typeof (<any>editor).getResource === 'function') {
const candidate = (<any>editor).getResource();
if (candidate instanceof URI) {
return candidate;
class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
private instantiationService: IInstantiationService;
private fileInputFactory: IFileInputFactory;
private editorInputFactoryConstructors: { [editorInputId: string]: IConstructorSignature0<IEditorInputFactory> } = Object.create(null);
private editorInputFactoryInstances: { [editorInputId: string]: IEditorInputFactory } = Object.create(null);
constructor() {
}
public setInstantiationService(service: IInstantiationService): void {
this.instantiationService = service;
for (let key in this.editorInputFactoryConstructors) {
const element = this.editorInputFactoryConstructors[key];
this.createEditorInputFactory(key, element);
}
this.editorInputFactoryConstructors = {};
}
private createEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>): void {
const instance = this.instantiationService.createInstance(ctor);
this.editorInputFactoryInstances[editorInputId] = instance;
}
public registerFileInputFactory(factory: IFileInputFactory): void {
this.fileInputFactory = factory;
}
public getFileInputFactory(): IFileInputFactory {
return this.fileInputFactory;
}
public registerEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>): void {
if (!this.instantiationService) {
this.editorInputFactoryConstructors[editorInputId] = ctor;
} else {
this.createEditorInputFactory(editorInputId, ctor);
}
}
return null;
}
public getEditorInputFactory(editorInputId: string): IEditorInputFactory {
return this.editorInputFactoryInstances[editorInputId];
}
}
export const Extensions = {
EditorInputFactories: 'workbench.contributions.editor.inputFactories'
};
Registry.add(Extensions.EditorInputFactories, new EditorInputFactoryRegistry());

View File

@@ -6,11 +6,11 @@
'use strict';
import Event, { Emitter, once } from 'vs/base/common/event';
import { IEditorRegistry, Extensions, EditorInput, toResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, EditorOpenPositioning, SideBySideEditorInput } from 'vs/workbench/common/editor';
import { Extensions, IEditorInputFactoryRegistry, EditorInput, toResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, IStacksModelChangeEvent, EditorOpenPositioning, SideBySideEditorInput, OPEN_POSITIONING_CONFIG } from 'vs/workbench/common/editor';
import URI from 'vs/base/common/uri';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
@@ -84,7 +84,7 @@ export class EditorGroup implements IEditorGroup {
this.mru = [];
this.toDispose = [];
this.mapResourceToEditorCount = new ResourceMap<number>();
this.onConfigurationUpdated(configurationService.getConfiguration<IWorkbenchEditorConfiguration>());
this.onConfigurationUpdated();
this._onEditorActivated = new Emitter<EditorInput>();
this._onEditorOpened = new Emitter<EditorInput>();
@@ -110,13 +110,11 @@ export class EditorGroup implements IEditorGroup {
}
private registerListeners(): void {
this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(this.configurationService.getConfiguration<IWorkbenchEditorConfiguration>())));
this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)));
}
private onConfigurationUpdated(config: IWorkbenchEditorConfiguration): void {
if (config && config.workbench && config.workbench.editor) {
this.editorOpenPositioning = config.workbench.editor.openPositioning;
}
private onConfigurationUpdated(event?: IConfigurationChangeEvent): void {
this.editorOpenPositioning = this.configurationService.getValue(OPEN_POSITIONING_CONFIG);
}
public get id(): GroupIdentifier {
@@ -637,7 +635,7 @@ export class EditorGroup implements IEditorGroup {
}
public serialize(): ISerializedEditorGroup {
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
const registry = Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories);
// Serialize all editor inputs so that we can store them.
// Editors that cannot be serialized need to be ignored
@@ -671,7 +669,7 @@ export class EditorGroup implements IEditorGroup {
}
private deserialize(data: ISerializedEditorGroup): void {
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
const registry = Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories);
this._label = data.label;
this.editors = data.editors.map(e => {
@@ -755,7 +753,7 @@ export class EditorStacksModel implements IEditorStacksModel {
this._onWillCloseEditor = new Emitter<EditorCloseEvent>();
this._onEditorClosed = new Emitter<EditorCloseEvent>();
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupDeactivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty, this._onEditorLabelChange, this._onEditorClosed, this._onWillCloseEditor);
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupDeactivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty, this._onEditorLabelChange, this._onEditorOpened, this._onEditorClosed, this._onWillCloseEditor);
this.registerListeners();
}
@@ -1215,7 +1213,7 @@ export class EditorStacksModel implements IEditorStacksModel {
// Close the editor when it is no longer open in any group including diff editors
editorsToClose.forEach(editorToClose => {
const resource = toResource(editorToClose); // prefer resource to not close right-hand side editors of a diff editor
const resource = editorToClose ? editorToClose.getResource() : void 0; // prefer resource to not close right-hand side editors of a diff editor
if (!this.isOpen(resource || editorToClose)) {
editorToClose.close();
}

View File

@@ -8,8 +8,6 @@ import URI from 'vs/base/common/uri';
import Event, { Emitter } from 'vs/base/common/event';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { toResource } from 'vs/workbench/common/editor';
import { isEqual } from 'vs/base/common/paths';
import { IRange } from 'vs/editor/common/core/range';
import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
@@ -56,9 +54,10 @@ export class RangeHighlightDecorations implements IDisposable {
}
private getEditor(resourceRange: IRangeHighlightDecoration): editorCommon.ICommonCodeEditor {
const fileResource = toResource(this.editorService.getActiveEditorInput(), { filter: 'file' });
if (fileResource) {
if (isEqual(fileResource.fsPath, resourceRange.resource.fsPath)) {
const activeInput = this.editorService.getActiveEditorInput();
const resource = activeInput && activeInput.getResource();
if (resource) {
if (resource.toString() === resourceRange.resource.toString()) {
return <editorCommon.ICommonCodeEditor>this.editorService.getActiveEditor().getControl();
}
}

View File

@@ -11,6 +11,7 @@ import { IReference } from 'vs/base/common/lifecycle';
import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
/**
* A read-only text editor input whos contents are made of the provided resource that points to an existing
@@ -29,7 +30,8 @@ export class ResourceEditorInput extends EditorInput {
name: string,
description: string,
resource: URI,
@ITextModelService private textModelResolverService: ITextModelService
@ITextModelService private textModelResolverService: ITextModelService,
@IHashService private hashService: IHashService
) {
super();
@@ -70,8 +72,13 @@ export class ResourceEditorInput extends EditorInput {
public getTelemetryDescriptor(): object {
const descriptor = super.getTelemetryDescriptor();
descriptor['resource'] = telemetryURIDescriptor(this.resource);
descriptor['resource'] = telemetryURIDescriptor(this.resource, path => this.hashService.createSHA1(path));
/* __GDPR__FRAGMENT__
"EditorTelemetryDescriptor" : {
"resource": { "${inline}": [ "${URIDescriptor}" ] }
}
*/
return descriptor;
}

View File

@@ -7,9 +7,11 @@
import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import { suggestFilename } from 'vs/base/common/mime';
import { memoize } from 'vs/base/common/decorators';
import labels = require('vs/base/common/labels');
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import paths = require('vs/base/common/paths');
import resources = require('vs/base/common/resources');
import { EditorInput, IEncodingSupport, EncodingMode, ConfirmResult } from 'vs/workbench/common/editor';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -19,6 +21,8 @@ import Event, { Emitter } from 'vs/base/common/event';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Verbosity } from 'vs/platform/editor/common/editor';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
/**
* An editor input to be used for untitled text buffers.
@@ -45,7 +49,8 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
@IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@ITextFileService private textFileService: ITextFileService,
@IEnvironmentService private environmentService: IEnvironmentService
@IEnvironmentService private environmentService: IEnvironmentService,
@IHashService private hashService: IHashService
) {
super();
@@ -85,11 +90,80 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
}
public getName(): string {
return this.hasAssociatedFilePath ? paths.basename(this.resource.fsPath) : this.resource.fsPath;
return this.hasAssociatedFilePath ? resources.basenameOrAuthority(this.resource) : this.resource.path;
}
public getDescription(): string {
return this.hasAssociatedFilePath ? labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService) : null;
@memoize
private get shortDescription(): string {
return paths.basename(labels.getPathLabel(resources.dirname(this.resource), void 0, this.environmentService));
}
@memoize
private get mediumDescription(): string {
return labels.getPathLabel(resources.dirname(this.resource), this.contextService, this.environmentService);
}
@memoize
private get longDescription(): string {
return labels.getPathLabel(resources.dirname(this.resource), void 0, this.environmentService);
}
public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string {
if (!this.hasAssociatedFilePath) {
return null;
}
let description: string;
switch (verbosity) {
case Verbosity.SHORT:
description = this.shortDescription;
break;
case Verbosity.LONG:
description = this.longDescription;
break;
case Verbosity.MEDIUM:
default:
description = this.mediumDescription;
break;
}
return description;
}
@memoize
private get shortTitle(): string {
return this.getName();
}
@memoize
private get mediumTitle(): string {
return labels.getPathLabel(this.resource, this.contextService, this.environmentService);
}
@memoize
private get longTitle(): string {
return labels.getPathLabel(this.resource, void 0, this.environmentService);
}
public getTitle(verbosity: Verbosity): string {
if (!this.hasAssociatedFilePath) {
return this.getName();
}
let title: string;
switch (verbosity) {
case Verbosity.SHORT:
title = this.shortTitle;
break;
case Verbosity.MEDIUM:
title = this.mediumTitle;
break;
case Verbosity.LONG:
title = this.longTitle;
break;
}
return title;
}
public isDirty(): boolean {
@@ -180,8 +254,13 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
public getTelemetryDescriptor(): object {
const descriptor = super.getTelemetryDescriptor();
descriptor['resource'] = telemetryURIDescriptor(this.getResource());
descriptor['resource'] = telemetryURIDescriptor(this.getResource(), path => this.hashService.createSHA1(path));
/* __GDPR__FRAGMENT__
"EditorTelemetryDescriptor" : {
"resource": { "${inline}": [ "${URIDescriptor}" ] }
}
*/
return descriptor;
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IEncodingSupport } from 'vs/workbench/common/editor';
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
@@ -12,7 +12,6 @@ import URI from 'vs/base/common/uri';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { EndOfLinePreference } from 'vs/editor/common/editorCommon';
import { IFilesConfiguration, CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IMode } from 'vs/editor/common/modes';
@@ -20,13 +19,13 @@ import Event, { Emitter } from 'vs/base/common/event';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IBackupFileService, BACKUP_FILE_RESOLVE_OPTIONS } from 'vs/workbench/services/backup/common/backup';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
export class UntitledEditorModel extends BaseTextEditorModel implements IEncodingSupport {
public static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY;
private textModelChangeListener: IDisposable;
private configurationChangeListener: IDisposable;
private toDispose: IDisposable[];
private dirty: boolean;
private _onDidChangeContent: Emitter<void>;
@@ -49,18 +48,25 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
@IModelService modelService: IModelService,
@IBackupFileService private backupFileService: IBackupFileService,
@ITextFileService private textFileService: ITextFileService,
@IConfigurationService private configurationService: IConfigurationService
@ITextResourceConfigurationService private configurationService: ITextResourceConfigurationService
) {
super(modelService, modeService);
this.dirty = false;
this.versionId = 0;
this.toDispose = [];
this._onDidChangeContent = new Emitter<void>();
this.toDispose.push(this._onDidChangeContent);
this._onDidChangeDirty = new Emitter<void>();
this.toDispose.push(this._onDidChangeDirty);
this._onDidChangeEncoding = new Emitter<void>();
this.toDispose.push(this._onDidChangeEncoding);
this.contentChangeEventScheduler = new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY);
this.toDispose.push(this.contentChangeEventScheduler);
this.registerListeners();
}
@@ -88,11 +94,20 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
private registerListeners(): void {
// Config Changes
this.configurationChangeListener = this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(this.configurationService.getConfiguration<IFilesConfiguration>()));
this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationChange()));
}
private onConfigurationChange(configuration: IFilesConfiguration): void {
this.configuredEncoding = configuration && configuration.files && configuration.files.encoding;
private onConfigurationChange(): void {
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
const configuredEncoding = configuration && configuration.files && configuration.files.encoding;
if (this.configuredEncoding !== configuredEncoding) {
this.configuredEncoding = configuredEncoding;
if (!this.preferredEncoding) {
this._onDidChangeEncoding.fire(); // do not fire event if we have a preferred encoding set
}
}
}
public getVersionId(): number {
@@ -170,13 +185,16 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
this.setDirty(this.hasAssociatedFilePath || !!backupContent);
return this.doLoad(backupContent || this.initialValue || '').then(model => {
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>();
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
// Encoding
this.configuredEncoding = configuration && configuration.files && configuration.files.encoding;
// Listen to content changes
this.textModelChangeListener = this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged());
this.toDispose.push(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged()));
// Listen to mode changes
this.toDispose.push(this.textEditorModel.onDidChangeLanguage(() => this.onConfigurationChange())); // mode change can have impact on config
return model;
});
@@ -219,20 +237,6 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
public dispose(): void {
super.dispose();
if (this.textModelChangeListener) {
this.textModelChangeListener.dispose();
this.textModelChangeListener = null;
}
if (this.configurationChangeListener) {
this.configurationChangeListener.dispose();
this.configurationChangeListener = null;
}
this.contentChangeEventScheduler.dispose();
this._onDidChangeContent.dispose();
this._onDidChangeDirty.dispose();
this._onDidChangeEncoding.dispose();
this.toDispose = dispose(this.toDispose);
}
}

View File

@@ -11,8 +11,8 @@ import paths = require('vs/base/common/paths');
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ParsedExpression, IExpression } from 'vs/base/common/glob';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { ParsedExpression, IExpression, parse } from 'vs/base/common/glob';
import { basename } from 'vs/base/common/paths';
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -23,11 +23,13 @@ export class ResourceContextKey implements IContextKey<URI> {
static Filename = new RawContextKey<string>('resourceFilename', undefined);
static LangId = new RawContextKey<string>('resourceLangId', undefined);
static Resource = new RawContextKey<URI>('resource', undefined);
static Extension = new RawContextKey<string>('resourceExtname', undefined);
private _resourceKey: IContextKey<URI>;
private _schemeKey: IContextKey<string>;
private _filenameKey: IContextKey<string>;
private _langIdKey: IContextKey<string>;
private _extensionKey: IContextKey<string>;
constructor(
@IContextKeyService contextKeyService: IContextKeyService,
@@ -37,6 +39,7 @@ export class ResourceContextKey implements IContextKey<URI> {
this._filenameKey = ResourceContextKey.Filename.bindTo(contextKeyService);
this._langIdKey = ResourceContextKey.LangId.bindTo(contextKeyService);
this._resourceKey = ResourceContextKey.Resource.bindTo(contextKeyService);
this._extensionKey = ResourceContextKey.Extension.bindTo(contextKeyService);
}
set(value: URI) {
@@ -44,12 +47,15 @@ export class ResourceContextKey implements IContextKey<URI> {
this._schemeKey.set(value && value.scheme);
this._filenameKey.set(value && basename(value.fsPath));
this._langIdKey.set(value && this._modeService.getModeIdByFilenameOrFirstLine(value.fsPath));
this._extensionKey.set(value && paths.extname(value.fsPath));
}
reset(): void {
this._schemeKey.reset();
this._langIdKey.reset();
this._resourceKey.reset();
this._langIdKey.reset();
this._extensionKey.reset();
}
public get(): URI {
@@ -59,7 +65,7 @@ export class ResourceContextKey implements IContextKey<URI> {
export class ResourceGlobMatcher {
private static readonly NO_ROOT = null;
private static readonly NO_ROOT: string = null;
private _onExpressionChange: Emitter<void>;
private toUnbind: IDisposable[];
@@ -68,7 +74,7 @@ export class ResourceGlobMatcher {
constructor(
private globFn: (root?: URI) => IExpression,
private parseFn: (expression: IExpression) => ParsedExpression,
private shouldUpdate: (event: IConfigurationChangeEvent) => boolean,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IConfigurationService private configurationService: IConfigurationService
) {
@@ -90,33 +96,27 @@ export class ResourceGlobMatcher {
}
private registerListeners(): void {
this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(() => this.onConfigurationChanged()));
this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
}
private onConfigurationChanged(): void {
this.updateExcludes(true);
}
private onDidChangeWorkspaceRoots(): void {
this.updateExcludes(true);
this.toUnbind.push(this.configurationService.onDidChangeConfiguration(e => {
if (this.shouldUpdate(e)) {
this.updateExcludes(true);
}
}));
this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateExcludes(true)));
}
private updateExcludes(fromEvent: boolean): void {
let changed = false;
// Add excludes per workspaces that got added
if (this.contextService.hasWorkspace()) {
this.contextService.getWorkspace().roots.forEach(root => {
const rootExcludes = this.globFn(root);
if (!this.mapRootToExpressionConfig.has(root.toString()) || !objects.equals(this.mapRootToExpressionConfig.get(root.toString()), rootExcludes)) {
changed = true;
this.contextService.getWorkspace().folders.forEach(folder => {
const rootExcludes = this.globFn(folder.uri);
if (!this.mapRootToExpressionConfig.has(folder.uri.toString()) || !objects.equals(this.mapRootToExpressionConfig.get(folder.uri.toString()), rootExcludes)) {
changed = true;
this.mapRootToParsedExpression.set(root.toString(), this.parseFn(rootExcludes));
this.mapRootToExpressionConfig.set(root.toString(), objects.clone(rootExcludes));
}
});
}
this.mapRootToParsedExpression.set(folder.uri.toString(), parse(rootExcludes));
this.mapRootToExpressionConfig.set(folder.uri.toString(), objects.clone(rootExcludes));
}
});
// Remove excludes per workspace no longer present
this.mapRootToExpressionConfig.forEach((value, root) => {
@@ -124,7 +124,7 @@ export class ResourceGlobMatcher {
return; // always keep this one
}
if (!this.contextService.getRoot(URI.parse(root))) {
if (!this.contextService.getWorkspaceFolder(URI.parse(root))) {
this.mapRootToParsedExpression.delete(root);
this.mapRootToExpressionConfig.delete(root);
@@ -137,7 +137,7 @@ export class ResourceGlobMatcher {
if (!this.mapRootToExpressionConfig.has(ResourceGlobMatcher.NO_ROOT) || !objects.equals(this.mapRootToExpressionConfig.get(ResourceGlobMatcher.NO_ROOT), globalExcludes)) {
changed = true;
this.mapRootToParsedExpression.set(ResourceGlobMatcher.NO_ROOT, this.parseFn(globalExcludes));
this.mapRootToParsedExpression.set(ResourceGlobMatcher.NO_ROOT, parse(globalExcludes));
this.mapRootToExpressionConfig.set(ResourceGlobMatcher.NO_ROOT, objects.clone(globalExcludes));
}
@@ -147,11 +147,11 @@ export class ResourceGlobMatcher {
}
public matches(resource: URI): boolean {
const root = this.contextService.getRoot(resource);
const folder = this.contextService.getWorkspaceFolder(resource);
let expressionForRoot: ParsedExpression;
if (root && this.mapRootToParsedExpression.has(root.toString())) {
expressionForRoot = this.mapRootToParsedExpression.get(root.toString());
if (folder && this.mapRootToParsedExpression.has(folder.uri.toString())) {
expressionForRoot = this.mapRootToParsedExpression.get(folder.uri.toString());
} else {
expressionForRoot = this.mapRootToParsedExpression.get(ResourceGlobMatcher.NO_ROOT);
}
@@ -161,8 +161,8 @@ export class ResourceGlobMatcher {
// a glob pattern of "src/**" will not match on an absolute path "/folder/src/file.txt"
// but can match on "src/file.txt"
let resourcePathToMatch: string;
if (root) {
resourcePathToMatch = paths.normalize(paths.relative(root.fsPath, resource.fsPath));
if (folder) {
resourcePathToMatch = paths.normalize(paths.relative(folder.uri.fsPath, resource.fsPath));
} else {
resourcePathToMatch = resource.fsPath;
}
@@ -173,4 +173,4 @@ export class ResourceGlobMatcher {
public dispose(): void {
this.toUnbind = dispose(this.toUnbind);
}
}
}

View File

@@ -118,7 +118,7 @@ export const PANEL_BORDER = registerColor('panel.border', {
dark: Color.fromHex('#808080').transparent(0.35),
light: Color.fromHex('#808080').transparent(0.35),
hc: contrastBorder
}, nls.localize('panelBorder', "Panel border color on the top separating to the editor. Panels are shown below the editor area and contain views like output and integrated terminal."));
}, nls.localize('panelBorder', "Panel border color to separate the panel from the editor. Panels are shown below the editor area and contain views like output and integrated terminal."));
export const PANEL_ACTIVE_TITLE_FOREGROUND = registerColor('panelTitle.activeForeground', {
dark: '#E7E7E7',
@@ -138,6 +138,11 @@ export const PANEL_ACTIVE_TITLE_BORDER = registerColor('panelTitle.activeBorder'
hc: contrastBorder
}, nls.localize('panelActiveTitleBorder', "Border color for the active panel title. Panels are shown below the editor area and contain views like output and integrated terminal."));
export const PANEL_DRAG_AND_DROP_BACKGROUND = registerColor('panel.dropBackground', {
dark: Color.white.transparent(0.12),
light: Color.fromHex('#3399FF').transparent(0.18),
hc: Color.white.transparent(0.12)
}, nls.localize('panelDragAndDropBackground', "Drag and drop feedback color for the panel title items. The color should have transparency so that the panel entries can still shine through. Panels are shown below the editor area and contain views like output and integrated terminal."));
// < --- Status --- >
@@ -224,6 +229,7 @@ export const ACTIVITY_BAR_BORDER = registerColor('activityBar.border', {
hc: contrastBorder
}, nls.localize('activityBarBorder', "Activity bar border color separating to the side bar. The activity bar is showing on the far left or right and allows to switch between views of the side bar."));
export const ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND = registerColor('activityBar.dropBackground', {
dark: Color.white.transparent(0.12),
light: Color.white.transparent(0.12),
@@ -243,7 +249,6 @@ export const ACTIVITY_BAR_BADGE_FOREGROUND = registerColor('activityBarBadge.for
}, nls.localize('activityBarBadgeForeground', "Activity notification badge foreground color. The activity bar is showing on the far left or right and allows to switch between views of the side bar."));
// < --- Side Bar --- >
export const SIDE_BAR_BACKGROUND = registerColor('sideBar.background', {

View File

@@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import Event from 'vs/base/common/event';
import { Command } from 'vs/editor/common/modes';
export type TreeViewItemHandleArg = {
$treeViewId: string,
$treeItemHandle: number
};
export enum TreeItemCollapsibleState {
None = 0,
Collapsed = 1,
Expanded = 2
}
export interface ITreeItem {
handle: number;
label: string;
icon?: string;
iconDark?: string;
contextValue?: string;
command?: Command;
children?: ITreeItem[];
collapsibleState?: TreeItemCollapsibleState;
}
export interface ITreeViewDataProvider {
onDidChange: Event<ITreeItem[] | undefined | null>;
onDispose: Event<void>;
getElements(): TPromise<ITreeItem[]>;
getChildren(element: ITreeItem): TPromise<ITreeItem[]>;
}