mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 11:08:51 +01:00
Merge remote-tracking branch 'upstream/master' into rmacfarlane/review
This commit is contained in:
@@ -17,7 +17,6 @@ import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -29,7 +28,8 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
|
||||
export interface IUserFriendlyViewsContainerDescriptor {
|
||||
id: string;
|
||||
@@ -80,12 +80,11 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
|
||||
private registerTestViewContainer(): void {
|
||||
const id = 'test';
|
||||
const title = localize('test', "Test");
|
||||
const cssClass = `extensionViewlet-${id}`;
|
||||
const cssClass = `extensionViewlet-test`;
|
||||
const icon = require.toUrl('./media/test.svg');
|
||||
|
||||
this.registerCustomViewlet({ id, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass);
|
||||
this.registerCustomViewlet({ id: ViewLocation.TEST.id, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass);
|
||||
}
|
||||
|
||||
private handleAndRegisterCustomViewContainers() {
|
||||
@@ -139,13 +138,13 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
const cssClass = `extensionViewlet-${descriptor.id}`;
|
||||
// TODO@extensionLocation
|
||||
const icon = join(extension.extensionLocation.fsPath, descriptor.icon);
|
||||
this.registerCustomViewlet({ id: descriptor.id, title: descriptor.title, icon }, TEST_VIEW_CONTAINER_ORDER + index + 1, cssClass);
|
||||
this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, TEST_VIEW_CONTAINER_ORDER + index + 1, cssClass);
|
||||
});
|
||||
}
|
||||
|
||||
private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor, order: number, cssClass: string): void {
|
||||
const viewletRegistry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets);
|
||||
const id = `workbench.view.extension.${descriptor.id}`;
|
||||
const id = descriptor.id;
|
||||
|
||||
if (!viewletRegistry.getViewlet(id)) {
|
||||
|
||||
@@ -158,7 +157,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@@ -184,9 +183,9 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
constructor(
|
||||
id: string, label: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IWorkbenchEditorService editorService: IWorkbenchEditorService
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label, id, viewletService, editorService);
|
||||
super(id, label, id, viewletService, editorGroupService);
|
||||
}
|
||||
}
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
@@ -205,4 +204,4 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(ViewsContainersExtensionHandler, LifecyclePhase.Starting);
|
||||
workbenchRegistry.registerWorkbenchContribution(ViewsContainersExtensionHandler, LifecyclePhase.Starting);
|
||||
|
||||
@@ -7,22 +7,150 @@
|
||||
import { localize } from 'vs/nls';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { ViewLocation, ViewsRegistry, ICustomViewDescriptor } from 'vs/workbench/common/views';
|
||||
import { CustomTreeViewPanel } from 'vs/workbench/browser/parts/views/customViewPanel';
|
||||
import { CustomTreeViewPanel, CustomTreeViewer } from 'vs/workbench/browser/parts/views/customView';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { coalesce, } from 'vs/base/common/arrays';
|
||||
import { viewsContainersExtensionPoint } from 'vs/workbench/api/browser/viewsContainersExtensionPoint';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
|
||||
namespace schema {
|
||||
interface IUserFriendlyViewDescriptor {
|
||||
id: string;
|
||||
name: string;
|
||||
when?: string;
|
||||
}
|
||||
|
||||
export interface IUserFriendlyViewDescriptor {
|
||||
id: string;
|
||||
name: string;
|
||||
when?: string;
|
||||
const viewDescriptor: IJSONSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
description: localize('vscode.extension.contributes.view.id', 'Identifier of the view. Use this to register a data provider through `vscode.window.registerTreeDataProviderForView` API. Also to trigger activating your extension by registering `onView:${id}` event to `activationEvents`.'),
|
||||
type: 'string'
|
||||
},
|
||||
name: {
|
||||
description: localize('vscode.extension.contributes.view.name', 'The human-readable name of the view. Will be shown'),
|
||||
type: 'string'
|
||||
},
|
||||
when: {
|
||||
description: localize('vscode.extension.contributes.view.when', 'Condition which must be true to show this view'),
|
||||
type: 'string'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const viewsContribution: IJSONSchema = {
|
||||
description: localize('vscode.extension.contributes.views', "Contributes views to the editor"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'explorer': {
|
||||
description: localize('views.explorer', "Contributes views to Explorer container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'debug': {
|
||||
description: localize('views.debug', "Contributes views to Debug container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'scm': {
|
||||
description: localize('views.scm', "Contributes views to SCM container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'test': {
|
||||
description: localize('views.test', "Contributes views to Test container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
additionalProperties: {
|
||||
description: localize('views.contributed', "Contributes views to contributed views container"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const viewsExtensionPoint: IExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }> = ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }>('views', [viewsContainersExtensionPoint], viewsContribution);
|
||||
|
||||
class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
this.handleAndRegisterCustomViews();
|
||||
}
|
||||
|
||||
export function isValidViewDescriptors(viewDescriptors: IUserFriendlyViewDescriptor[], collector: ExtensionMessageCollector): boolean {
|
||||
private handleAndRegisterCustomViews() {
|
||||
viewsExtensionPoint.setHandler(extensions => {
|
||||
for (let extension of extensions) {
|
||||
const { value, collector } = extension;
|
||||
|
||||
forEach(value, entry => {
|
||||
if (!this.isValidViewDescriptors(entry.value, collector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let location = this.getViewLocation(entry.key);
|
||||
if (!location) {
|
||||
collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key));
|
||||
location = ViewLocation.Explorer;
|
||||
}
|
||||
const registeredViews = ViewsRegistry.getViews(location);
|
||||
const viewIds = [];
|
||||
const viewDescriptors = coalesce(entry.value.map(item => {
|
||||
// validate
|
||||
if (viewIds.indexOf(item.id) !== -1) {
|
||||
collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the location `{1}`", item.id, location.id));
|
||||
return null;
|
||||
}
|
||||
if (registeredViews.some(v => v.id === item.id)) {
|
||||
collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the location `{1}`", item.id, location.id));
|
||||
return null;
|
||||
}
|
||||
|
||||
const viewDescriptor = <ICustomViewDescriptor>{
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
ctor: CustomTreeViewPanel,
|
||||
location,
|
||||
when: ContextKeyExpr.deserialize(item.when),
|
||||
canToggleVisibility: true,
|
||||
collapsed: this.showCollapsed(location),
|
||||
treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, this.getProgressLocation(location))
|
||||
};
|
||||
|
||||
viewIds.push(viewDescriptor.id);
|
||||
return viewDescriptor;
|
||||
}));
|
||||
ViewsRegistry.registerViews(viewDescriptors);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getProgressLocation(location: ViewLocation): ProgressLocation {
|
||||
switch (location.id) {
|
||||
case ViewLocation.Explorer.id:
|
||||
return ProgressLocation.Explorer;
|
||||
case ViewLocation.SCM.id:
|
||||
return ProgressLocation.Scm;
|
||||
case ViewLocation.Debug.id:
|
||||
return null /* No debug progress location yet */;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private isValidViewDescriptors(viewDescriptors: IUserFriendlyViewDescriptor[], collector: ExtensionMessageCollector): boolean {
|
||||
if (!Array.isArray(viewDescriptors)) {
|
||||
collector.error(localize('requirearray', "views must be an array"));
|
||||
return false;
|
||||
@@ -46,114 +174,26 @@ namespace schema {
|
||||
return true;
|
||||
}
|
||||
|
||||
const viewDescriptor: IJSONSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
description: localize('vscode.extension.contributes.view.id', 'Identifier of the view. Use this to register a data provider through `vscode.window.registerTreeDataProviderForView` API. Also to trigger activating your extension by registering `onView:${id}` event to `activationEvents`.'),
|
||||
type: 'string'
|
||||
},
|
||||
name: {
|
||||
description: localize('vscode.extension.contributes.view.name', 'The human-readable name of the view. Will be shown'),
|
||||
type: 'string'
|
||||
},
|
||||
when: {
|
||||
description: localize('vscode.extension.contributes.view.when', 'Condition which must be true to show this view'),
|
||||
type: 'string'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const viewsContribution: IJSONSchema = {
|
||||
description: localize('vscode.extension.contributes.views', "Contributes views to the editor"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'explorer': {
|
||||
description: localize('views.explorer', "Contributes views to Explorer container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'debug': {
|
||||
description: localize('views.debug', "Contributes views to Debug container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'scm': {
|
||||
description: localize('views.scm', "Contributes views to SCM container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
},
|
||||
'test': {
|
||||
description: localize('views.test', "Contributes views to Test container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
additionalProperties: {
|
||||
description: localize('views.contributed', "Contributes views to contributed views container"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
private getViewLocation(value: string): ViewLocation {
|
||||
switch (value) {
|
||||
case 'explorer': return ViewLocation.Explorer;
|
||||
case 'debug': return ViewLocation.Debug;
|
||||
case 'scm': return ViewLocation.SCM;
|
||||
default: return ViewLocation.get(`workbench.view.extension.${value}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getViewLocation(value: string): ViewLocation {
|
||||
switch (value) {
|
||||
case 'explorer': return ViewLocation.Explorer;
|
||||
case 'debug': return ViewLocation.Debug;
|
||||
case 'scm': return ViewLocation.SCM;
|
||||
default: return ViewLocation.get(`workbench.view.extension.${value}`);
|
||||
private showCollapsed(location: ViewLocation): boolean {
|
||||
switch (location) {
|
||||
case ViewLocation.Explorer:
|
||||
case ViewLocation.SCM:
|
||||
case ViewLocation.Debug:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyViewDescriptor[] }>('views', [viewsContainersExtensionPoint], schema.viewsContribution)
|
||||
.setHandler((extensions) => {
|
||||
for (let extension of extensions) {
|
||||
const { value, collector } = extension;
|
||||
|
||||
forEach(value, entry => {
|
||||
if (!schema.isValidViewDescriptors(entry.value, collector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let location = getViewLocation(entry.key);
|
||||
if (!location) {
|
||||
collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key));
|
||||
location = ViewLocation.Explorer;
|
||||
}
|
||||
const registeredViews = ViewsRegistry.getViews(location);
|
||||
const viewIds = [];
|
||||
const viewDescriptors = coalesce(entry.value.map(item => {
|
||||
const viewDescriptor = <ICustomViewDescriptor>{
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
ctor: CustomTreeViewPanel,
|
||||
location,
|
||||
when: ContextKeyExpr.deserialize(item.when),
|
||||
canToggleVisibility: true,
|
||||
collapsed: true,
|
||||
treeView: true
|
||||
};
|
||||
|
||||
// validate
|
||||
if (viewIds.indexOf(viewDescriptor.id) !== -1) {
|
||||
collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id));
|
||||
return null;
|
||||
}
|
||||
if (registeredViews.some(v => v.id === viewDescriptor.id)) {
|
||||
collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id));
|
||||
return null;
|
||||
}
|
||||
|
||||
viewIds.push(viewDescriptor.id);
|
||||
return viewDescriptor;
|
||||
}));
|
||||
ViewsRegistry.registerViews(viewDescriptors);
|
||||
});
|
||||
}
|
||||
});
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(ViewsContainersExtensionHandler, LifecyclePhase.Starting);
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import uri from 'vs/base/common/uri';
|
||||
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable, ITerminalSettings, IDebugAdapter, IDebugAdapterProvider } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable, ITerminalSettings, IDebugAdapter, IDebugAdapterProvider, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import {
|
||||
ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext,
|
||||
@@ -18,6 +18,8 @@ import { AbstractDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/common/debugUtils';
|
||||
import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal';
|
||||
import { AbstractTerminalLauncher } from 'vs/workbench/parts/debug/electron-browser/terminalSupport';
|
||||
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadDebugService)
|
||||
@@ -28,11 +30,13 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
private _breakpointEventsActive: boolean;
|
||||
private _debugAdapters: Map<number, ExtensionHostDebugAdapter>;
|
||||
private _debugAdaptersHandleCounter = 1;
|
||||
private _terminalLauncher: ITerminalLauncher;
|
||||
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IDebugService private debugService: IDebugService
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@ITerminalService private terminalService: ITerminalService,
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDebugService);
|
||||
this._toDispose = [];
|
||||
@@ -73,7 +77,10 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
}
|
||||
|
||||
runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
|
||||
return this._proxy.$runInTerminal(args, config);
|
||||
if (!this._terminalLauncher) {
|
||||
this._terminalLauncher = new ExtensionTerminalLauncher(this.terminalService, this._proxy);
|
||||
}
|
||||
return this._terminalLauncher.runInTerminal(args, config);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -295,3 +302,25 @@ class ExtensionHostDebugAdapter extends AbstractDebugAdapter {
|
||||
return this._proxy.$stopDASession(this._handle);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionTerminalLauncher extends AbstractTerminalLauncher {
|
||||
|
||||
constructor(
|
||||
@ITerminalService terminalService: ITerminalService,
|
||||
private _proxy: ExtHostDebugServiceShape
|
||||
) {
|
||||
super(terminalService);
|
||||
}
|
||||
|
||||
protected runInExternalTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
|
||||
return this._proxy.$runInTerminal(args, config);
|
||||
}
|
||||
|
||||
protected isBusy(processId: number): TPromise<boolean> {
|
||||
return this._proxy.$isTerminalBusy(processId);
|
||||
}
|
||||
|
||||
protected prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<any> {
|
||||
return this._proxy.$prepareCommandForTerminal(args, config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITextModel, DefaultEndOfLine } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
|
||||
import { MainThreadDocumentContentProvidersShape, ExtHostContext, ExtHostDocumentContentProvidersShape, MainContext, IExtHostContext } from '../node/extHost.protocol';
|
||||
import { createTextBuffer } from 'vs/editor/common/model/textModel';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
@@ -28,8 +27,7 @@ export class MainThreadDocumentContentProviders implements MainThreadDocumentCon
|
||||
@ITextModelService private readonly _textModelResolverService: ITextModelService,
|
||||
@IModeService private readonly _modeService: IModeService,
|
||||
@IModelService private readonly _modelService: IModelService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IEditorGroupService editorGroupService: IEditorGroupService
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentContentProviders);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { IModelService, shouldSynchronizeModel } from 'vs/editor/common/services
|
||||
import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle';
|
||||
import { TextFileModelChangeEvent, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IFileService, FileOperation } from 'vs/platform/files/common/files';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { ExtHostContext, MainThreadDocumentsShape, ExtHostDocumentsShape, IExtHostContext } from '../node/extHost.protocol';
|
||||
@@ -119,6 +119,12 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
|
||||
}
|
||||
}));
|
||||
|
||||
this._toDispose.push(fileService.onAfterOperation(e => {
|
||||
if (e.operation === FileOperation.MOVE) {
|
||||
this._proxy.$onDidRename(e.resource, e.target.resource);
|
||||
}
|
||||
}));
|
||||
|
||||
this._modelToDisposeMap = Object.create(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,9 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ExtHostContext, ExtHostDocumentsAndEditorsShape, IModelAddedData, ITextEditorAddData, IDocumentsAndEditorsDelta, IExtHostContext, MainContext } from '../node/extHost.protocol';
|
||||
import { MainThreadTextEditor } from './mainThreadEditor';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { Position as EditorPosition, IEditor } from 'vs/platform/editor/common/editor';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { EditorViewColumn, editorGroupToViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { IEditor } from 'vs/workbench/common/editor';
|
||||
import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { MainThreadDocuments } from 'vs/workbench/api/electron-browser/mainThreadDocuments';
|
||||
import { MainThreadTextEditors } from 'vs/workbench/api/electron-browser/mainThreadEditors';
|
||||
@@ -21,8 +22,8 @@ import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
|
||||
import { isCodeEditor, isDiffEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { isDiffEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
|
||||
|
||||
@@ -160,7 +161,7 @@ class MainThreadDocumentAndEditorStateComputer {
|
||||
private readonly _onDidChangeState: (delta: DocumentAndEditorStateDelta) => void,
|
||||
@IModelService private readonly _modelService: IModelService,
|
||||
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
|
||||
@IWorkbenchEditorService private readonly _workbenchEditorService: IWorkbenchEditorService
|
||||
@IEditorService private readonly _editorService: IEditorService
|
||||
) {
|
||||
this._modelService.onModelAdded(this._updateStateOnModelAdd, this, this._toDispose);
|
||||
this._modelService.onModelRemoved(this._updateState, this, this._toDispose);
|
||||
@@ -251,25 +252,19 @@ class MainThreadDocumentAndEditorStateComputer {
|
||||
}
|
||||
|
||||
// active editor: if none of the previous editors had focus we try
|
||||
// to match the action workbench editor with one of editor we have
|
||||
// to match the active workbench editor with one of editor we have
|
||||
// just computed
|
||||
if (!activeEditor) {
|
||||
const workbenchEditor = this._workbenchEditorService.getActiveEditor();
|
||||
if (workbenchEditor) {
|
||||
const workbenchEditorControl = workbenchEditor.getControl();
|
||||
let candidate: ICodeEditor;
|
||||
if (isCodeEditor(workbenchEditorControl)) {
|
||||
candidate = workbenchEditorControl;
|
||||
} else if (isDiffEditor(workbenchEditorControl)) {
|
||||
candidate = workbenchEditorControl.getModifiedEditor();
|
||||
}
|
||||
if (candidate) {
|
||||
editors.forEach(snapshot => {
|
||||
if (candidate === snapshot.editor) {
|
||||
activeEditor = snapshot.id;
|
||||
}
|
||||
});
|
||||
}
|
||||
let candidate = this._editorService.activeTextEditorWidget;
|
||||
if (isDiffEditor(candidate)) {
|
||||
candidate = candidate.getModifiedEditor();
|
||||
}
|
||||
if (candidate) {
|
||||
editors.forEach(snapshot => {
|
||||
if (candidate === snapshot.editor) {
|
||||
activeEditor = snapshot.id;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,14 +300,14 @@ export class MainThreadDocumentsAndEditors {
|
||||
extHostContext: IExtHostContext,
|
||||
@IModelService private readonly _modelService: IModelService,
|
||||
@ITextFileService private readonly _textFileService: ITextFileService,
|
||||
@IWorkbenchEditorService private readonly _workbenchEditorService: IWorkbenchEditorService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IModeService modeService: IModeService,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITextModelService textModelResolverService: ITextModelService,
|
||||
@IUntitledEditorService untitledEditorService: IUntitledEditorService,
|
||||
@IEditorGroupService editorGroupService: IEditorGroupService,
|
||||
@IBulkEditService bulkEditService: IBulkEditService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@IBulkEditService bulkEditService: IBulkEditService
|
||||
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentsAndEditors);
|
||||
@@ -320,11 +315,11 @@ export class MainThreadDocumentsAndEditors {
|
||||
const mainThreadDocuments = new MainThreadDocuments(this, extHostContext, this._modelService, modeService, this._textFileService, fileService, textModelResolverService, untitledEditorService);
|
||||
extHostContext.set(MainContext.MainThreadDocuments, mainThreadDocuments);
|
||||
|
||||
const mainThreadTextEditors = new MainThreadTextEditors(this, extHostContext, codeEditorService, bulkEditService, this._workbenchEditorService, editorGroupService);
|
||||
const mainThreadTextEditors = new MainThreadTextEditors(this, extHostContext, codeEditorService, bulkEditService, this._editorService, this._editorGroupService);
|
||||
extHostContext.set(MainContext.MainThreadTextEditors, mainThreadTextEditors);
|
||||
|
||||
// It is expected that the ctor of the state computer calls our `_onDelta`.
|
||||
this._stateComputer = new MainThreadDocumentAndEditorStateComputer(delta => this._onDelta(delta), _modelService, codeEditorService, _workbenchEditorService);
|
||||
this._stateComputer = new MainThreadDocumentAndEditorStateComputer(delta => this._onDelta(delta), _modelService, codeEditorService, this._editorService);
|
||||
|
||||
this._toDispose = [
|
||||
mainThreadDocuments,
|
||||
@@ -426,10 +421,10 @@ export class MainThreadDocumentsAndEditors {
|
||||
};
|
||||
}
|
||||
|
||||
private _findEditorPosition(editor: MainThreadTextEditor): EditorPosition {
|
||||
for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) {
|
||||
private _findEditorPosition(editor: MainThreadTextEditor): EditorViewColumn {
|
||||
for (let workbenchEditor of this._editorService.visibleControls) {
|
||||
if (editor.matches(workbenchEditor)) {
|
||||
return workbenchEditor.position;
|
||||
return editorGroupToViewColumn(this._editorGroupService, workbenchEditor.group);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEditor } from 'vs/platform/editor/common/editor';
|
||||
import { IEditor } from 'vs/workbench/common/editor';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { localize } from 'vs/nls';
|
||||
import { disposed } from 'vs/base/common/errors';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { equals as objectEquals } from 'vs/base/common/objects';
|
||||
@@ -15,10 +18,11 @@ import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISelection } from 'vs/editor/common/core/selection';
|
||||
import { IDecorationOptions, IDecorationRenderOptions, ILineChange } from 'vs/editor/common/editorCommon';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import { ITextEditorOptions, Position as EditorPosition } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn, viewColumnToEditorGroup, editorGroupToViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IApplyEditsOptions, ITextEditorConfigurationUpdate, IUndoStopOptions, TextEditorRevealType, WorkspaceEditDto, reviveWorkspaceEditDto } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { ExtHostContext, ExtHostEditorsShape, IExtHostContext, ITextDocumentShowOptions, ITextEditorPositionData, MainThreadTextEditorsShape } from '../node/extHost.protocol';
|
||||
import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors';
|
||||
import { MainThreadTextEditor } from './mainThreadEditor';
|
||||
@@ -27,7 +31,6 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
|
||||
private _proxy: ExtHostEditorsShape;
|
||||
private _documentsAndEditors: MainThreadDocumentsAndEditors;
|
||||
private _workbenchEditorService: IWorkbenchEditorService;
|
||||
private _toDispose: IDisposable[];
|
||||
private _textEditorsListenersMap: { [editorId: string]: IDisposable[]; };
|
||||
private _editorPositionData: ITextEditorPositionData;
|
||||
@@ -38,12 +41,11 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
extHostContext: IExtHostContext,
|
||||
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
@IWorkbenchEditorService workbenchEditorService: IWorkbenchEditorService,
|
||||
@IEditorGroupService editorGroupService: IEditorGroupService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostEditors);
|
||||
this._documentsAndEditors = documentsAndEditors;
|
||||
this._workbenchEditorService = workbenchEditorService;
|
||||
this._toDispose = [];
|
||||
this._textEditorsListenersMap = Object.create(null);
|
||||
this._editorPositionData = null;
|
||||
@@ -51,8 +53,8 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
this._toDispose.push(documentsAndEditors.onTextEditorAdd(editors => editors.forEach(this._onTextEditorAdd, this)));
|
||||
this._toDispose.push(documentsAndEditors.onTextEditorRemove(editors => editors.forEach(this._onTextEditorRemove, this)));
|
||||
|
||||
this._toDispose.push(editorGroupService.onEditorsChanged(() => this._updateActiveAndVisibleTextEditors()));
|
||||
this._toDispose.push(editorGroupService.onEditorGroupMoved(() => this._updateActiveAndVisibleTextEditors()));
|
||||
this._toDispose.push(this._editorService.onDidVisibleEditorsChange(() => this._updateActiveAndVisibleTextEditors()));
|
||||
this._toDispose.push(this._editorGroupService.onDidRemoveGroup(() => this._updateActiveAndVisibleTextEditors()));
|
||||
|
||||
this._registeredDecorationTypes = Object.create(null);
|
||||
}
|
||||
@@ -96,10 +98,10 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
|
||||
private _getTextEditorPositionData(): ITextEditorPositionData {
|
||||
let result: ITextEditorPositionData = Object.create(null);
|
||||
for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) {
|
||||
for (let workbenchEditor of this._editorService.visibleControls) {
|
||||
const id = this._documentsAndEditors.findTextEditorIdFor(workbenchEditor);
|
||||
if (id) {
|
||||
result[id] = workbenchEditor.position;
|
||||
result[id] = editorGroupToViewColumn(this._editorGroupService, workbenchEditor.group);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -121,7 +123,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
options: editorOptions
|
||||
};
|
||||
|
||||
return this._workbenchEditorService.openEditor(input, options.position).then(editor => {
|
||||
return this._editorService.openEditor(input, viewColumnToEditorGroup(this._editorGroupService, options.position)).then(editor => {
|
||||
if (!editor) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -129,14 +131,14 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
});
|
||||
}
|
||||
|
||||
$tryShowEditor(id: string, position: EditorPosition): TPromise<void> {
|
||||
$tryShowEditor(id: string, position?: EditorViewColumn): TPromise<void> {
|
||||
let mainThreadEditor = this._documentsAndEditors.getEditor(id);
|
||||
if (mainThreadEditor) {
|
||||
let model = mainThreadEditor.getModel();
|
||||
return this._workbenchEditorService.openEditor({
|
||||
return this._editorService.openEditor({
|
||||
resource: model.uri,
|
||||
options: { preserveFocus: false }
|
||||
}, position).then(() => { return; });
|
||||
}, viewColumnToEditorGroup(this._editorGroupService, position)).then(() => { return; });
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -144,10 +146,10 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
$tryHideEditor(id: string): TPromise<void> {
|
||||
let mainThreadEditor = this._documentsAndEditors.getEditor(id);
|
||||
if (mainThreadEditor) {
|
||||
let editors = this._workbenchEditorService.getVisibleEditors();
|
||||
let editors = this._editorService.visibleControls;
|
||||
for (let editor of editors) {
|
||||
if (mainThreadEditor.matches(editor)) {
|
||||
return this._workbenchEditorService.closeEditor(editor.position, editor.input).then(() => { return; });
|
||||
return editor.group.closeEditor(editor.input).then(() => { return; });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,3 +244,33 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
return TPromise.as(diffEditor.getLineChanges());
|
||||
}
|
||||
}
|
||||
|
||||
// --- commands
|
||||
|
||||
CommandsRegistry.registerCommand('_workbench.open', function (accessor: ServicesAccessor, args: [URI, IEditorOptions, EditorViewColumn]) {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
|
||||
const [resource, options, position] = args;
|
||||
|
||||
return editorService.openEditor({ resource, options }, viewColumnToEditorGroup(editorGroupService, position)).then(() => void 0);
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand('_workbench.diff', function (accessor: ServicesAccessor, args: [URI, URI, string, string, IEditorOptions, EditorViewColumn]) {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
|
||||
let [leftResource, rightResource, label, description, options, position] = args;
|
||||
|
||||
if (!options || typeof options !== 'object') {
|
||||
options = {
|
||||
preserveFocus: false
|
||||
};
|
||||
}
|
||||
|
||||
if (!label) {
|
||||
label = localize('diffLeftRightLabel', "{0} ⟷ {1}", leftResource.toString(true), rightResource.toString(true));
|
||||
}
|
||||
|
||||
return editorService.openEditor({ leftResource, rightResource, label, description, options }, viewColumnToEditorGroup(editorGroupService, position)).then(() => void 0);
|
||||
});
|
||||
@@ -307,7 +307,10 @@ class CodeActionOnParticipant implements ISaveParticipant {
|
||||
}
|
||||
|
||||
private async getActionsToRun(model: ITextModel, codeActionsOnSave: CodeActionKind[]) {
|
||||
const actions = await getCodeActions(model, model.getFullModelRange(), { kind: CodeActionKind.Source, includeSourceActions: true });
|
||||
const actions = await getCodeActions(model, model.getFullModelRange(), {
|
||||
type: 'auto',
|
||||
filter: { kind: CodeActionKind.Source, includeSourceActions: true },
|
||||
});
|
||||
const actionsToRun = actions.filter(returnedAction => returnedAction.kind && codeActionsOnSave.some(onSaveKind => onSaveKind.contains(returnedAction.kind)));
|
||||
return actionsToRun;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { PPromise, TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IFileMatch, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, QueryType, IRawFileMatch2, ISearchCompleteStats, IFolderQuery } from 'vs/platform/search/common/search';
|
||||
import { IFileMatch, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, QueryType, IRawFileMatch2, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { ExtHostContext, ExtHostSearchShape, IExtHostContext, MainContext, MainThreadSearchShape } from '../node/extHost.protocol';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -58,7 +57,6 @@ class SearchOperation {
|
||||
|
||||
constructor(
|
||||
readonly progress: (match: IFileMatch) => any,
|
||||
readonly folders: IFolderQuery[],
|
||||
readonly id: number = ++SearchOperation._idPool,
|
||||
readonly matches = new Map<string, IFileMatch>()
|
||||
) {
|
||||
@@ -102,6 +100,9 @@ class RemoteSearchProvider implements ISearchResultProvider {
|
||||
}
|
||||
|
||||
const folderQueriesForScheme = query.folderQueries.filter(fq => fq.folder.scheme === this._scheme);
|
||||
if (!folderQueriesForScheme.length) {
|
||||
return TPromise.wrap(null);
|
||||
}
|
||||
|
||||
query = {
|
||||
...query,
|
||||
@@ -112,7 +113,7 @@ class RemoteSearchProvider implements ISearchResultProvider {
|
||||
|
||||
return new PPromise((resolve, reject, report) => {
|
||||
|
||||
const search = new SearchOperation(report, query.folderQueries);
|
||||
const search = new SearchOperation(report);
|
||||
this._searches.set(search.id, search);
|
||||
|
||||
outer = query.type === QueryType.File
|
||||
@@ -142,14 +143,8 @@ class RemoteSearchProvider implements ISearchResultProvider {
|
||||
const searchOp = this._searches.get(session);
|
||||
if (Array.isArray(dataOrUri)) {
|
||||
dataOrUri.forEach(m => {
|
||||
const folderQuery = searchOp.folders[m.resource.folderIdx];
|
||||
if (!folderQuery) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fullUri = URI.file(path.join(folderQuery.folder.fsPath, m.resource.relativePath));
|
||||
searchOp.addMatch({
|
||||
resource: fullUri,
|
||||
resource: URI.revive(m.resource),
|
||||
lineMatches: m.lineMatches
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ import URI from 'vs/base/common/uri';
|
||||
import * as Objects from 'vs/base/common/objects';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as Types from 'vs/base/common/types';
|
||||
import * as Platform from 'vs/base/common/platform';
|
||||
|
||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
@@ -21,12 +22,11 @@ import {
|
||||
} from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { ITaskService, TaskFilter } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
|
||||
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { ExtHostContext, MainThreadTaskShape, ExtHostTaskShape, MainContext, IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import {
|
||||
TaskDefinitionDTO, TaskExecutionDTO, ProcessExecutionOptionsDTO, TaskPresentationOptionsDTO,
|
||||
ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO
|
||||
ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO
|
||||
} from 'vs/workbench/api/shared/tasks';
|
||||
|
||||
export { TaskDTO, TaskHandleDTO, TaskExecutionDTO, TaskFilterDTO };
|
||||
@@ -357,6 +357,7 @@ namespace TaskFilterDTO {
|
||||
@extHostNamedCustomer(MainContext.MainThreadTask)
|
||||
export class MainThreadTask implements MainThreadTaskShape {
|
||||
|
||||
private _extHostContext: IExtHostContext;
|
||||
private _proxy: ExtHostTaskShape;
|
||||
private _activeHandles: { [handle: number]: boolean; };
|
||||
|
||||
@@ -471,4 +472,35 @@ export class MainThreadTask implements MainThreadTaskShape {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public $registerTaskSystem(key: string, info: TaskSystemInfoDTO): void {
|
||||
let platform: Platform.Platform;
|
||||
switch (info.platform) {
|
||||
case 'win32':
|
||||
platform = Platform.Platform.Windows;
|
||||
break;
|
||||
case 'darwin':
|
||||
platform = Platform.Platform.Mac;
|
||||
break;
|
||||
case 'linux':
|
||||
platform = Platform.Platform.Linux;
|
||||
break;
|
||||
default:
|
||||
platform = Platform.platform;
|
||||
}
|
||||
this._taskService.registerTaskSystem(key, {
|
||||
platform: platform,
|
||||
fileSystemScheme: key,
|
||||
context: this._extHostContext,
|
||||
resolveVariables: (workspaceFolder: IWorkspaceFolder, variables: Set<string>): TPromise<Map<string, string>> => {
|
||||
let vars: string[] = [];
|
||||
variables.forEach(item => vars.push(item));
|
||||
return this._proxy.$resolveVariables(workspaceFolder.uri, vars).then(values => {
|
||||
let result = new Map<string, string>();
|
||||
Object.keys(values).forEach(key => result.set(key, values[key]));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from '../node/extHost.protocol';
|
||||
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeViewer } from 'vs/workbench/common/views';
|
||||
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeViewer, ViewsRegistry, ICustomViewDescriptor } from 'vs/workbench/common/views';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -30,10 +30,10 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
$registerTreeViewDataProvider(treeViewId: string): void {
|
||||
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
|
||||
this._dataProviders.set(treeViewId, dataProvider);
|
||||
const treeViewer = this.viewsService.getTreeViewer(treeViewId);
|
||||
if (treeViewer) {
|
||||
treeViewer.dataProvider = dataProvider;
|
||||
this.registerListeners(treeViewId, treeViewer);
|
||||
const viewer = this.getTreeViewer(treeViewId);
|
||||
if (viewer) {
|
||||
viewer.dataProvider = dataProvider;
|
||||
this.registerListeners(treeViewId, viewer);
|
||||
} else {
|
||||
this.notificationService.error('No view is registered with id: ' + treeViewId);
|
||||
}
|
||||
@@ -42,13 +42,13 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
$reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options?: { select?: boolean }): TPromise<void> {
|
||||
return this.viewsService.openView(treeViewId)
|
||||
.then(() => {
|
||||
const viewer = this.viewsService.getTreeViewer(treeViewId);
|
||||
const viewer = this.getTreeViewer(treeViewId);
|
||||
return viewer ? viewer.reveal(item, parentChain, options) : null;
|
||||
});
|
||||
}
|
||||
|
||||
$refresh(treeViewId: string, itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeItem }): TPromise<void> {
|
||||
const viewer = this.viewsService.getTreeViewer(treeViewId);
|
||||
const viewer = this.getTreeViewer(treeViewId);
|
||||
const dataProvider = this._dataProviders.get(treeViewId);
|
||||
if (viewer && dataProvider) {
|
||||
const itemsToRefresh = dataProvider.getItemsToRefresh(itemsToRefreshByHandle);
|
||||
@@ -63,9 +63,14 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
this._register(treeViewer.onDidChangeSelection(items => this._proxy.$setSelection(treeViewId, items.map(({ handle }) => handle))));
|
||||
}
|
||||
|
||||
private getTreeViewer(treeViewId: string): ITreeViewer {
|
||||
const viewDescriptor: ICustomViewDescriptor = <ICustomViewDescriptor>ViewsRegistry.getView(treeViewId);
|
||||
return viewDescriptor ? viewDescriptor.treeViewer : null;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._dataProviders.forEach((dataProvider, treeViewId) => {
|
||||
const treeViewer = this.viewsService.getTreeViewer(treeViewId);
|
||||
const treeViewer = this.getTreeViewer(treeViewId);
|
||||
if (treeViewer) {
|
||||
treeViewer.dataProvider = null;
|
||||
}
|
||||
|
||||
@@ -8,16 +8,16 @@ import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Position } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn, viewColumnToEditorGroup, editorGroupToViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { WebviewEditor } from 'vs/workbench/parts/webview/electron-browser/webviewEditor';
|
||||
import { WebviewEditorInput } from 'vs/workbench/parts/webview/electron-browser/webviewEditorInput';
|
||||
import { IWebviewEditorService, WebviewInputOptions, WebviewReviver } from 'vs/workbench/parts/webview/electron-browser/webviewEditorService';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IWebviewEditorService, WebviewInputOptions, WebviewReviver, ICreateWebViewShowOptions } from 'vs/workbench/parts/webview/electron-browser/webviewEditorService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { extHostNamedCustomer } from './extHostCustomers';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadWebviews)
|
||||
@@ -40,17 +40,17 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IEditorGroupService editorGroupService: IEditorGroupService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@ILifecycleService lifecycleService: ILifecycleService,
|
||||
@IWorkbenchEditorService private readonly _editorService: IWorkbenchEditorService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@IWebviewEditorService private readonly _webviewService: IWebviewEditorService,
|
||||
@IOpenerService private readonly _openerService: IOpenerService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
|
||||
) {
|
||||
this._proxy = context.getProxy(ExtHostContext.ExtHostWebviews);
|
||||
editorGroupService.onEditorsChanged(this.onEditorsChanged, this, this._toDispose);
|
||||
editorGroupService.onEditorGroupMoved(this.onEditorGroupMoved, this, this._toDispose);
|
||||
_editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this, this._toDispose);
|
||||
_editorService.onDidVisibleEditorsChange(this.onVisibleEditorsChanged, this, this._toDispose);
|
||||
|
||||
this._toDispose.push(_webviewService.registerReviver(MainThreadWebviews.viewType, this));
|
||||
|
||||
@@ -67,11 +67,20 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
handle: WebviewPanelHandle,
|
||||
viewType: string,
|
||||
title: string,
|
||||
showOptions: { viewColumn: Position, preserveFocus: boolean },
|
||||
showOptions: { viewColumn: EditorViewColumn | null, preserveFocus: boolean },
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: UriComponents
|
||||
): void {
|
||||
const webview = this._webviewService.createWebview(MainThreadWebviews.viewType, title, showOptions, options, URI.revive(extensionLocation), this.createWebviewEventDelegate(handle));
|
||||
const mainThreadShowOptions: ICreateWebViewShowOptions = Object.create(null);
|
||||
if (showOptions) {
|
||||
mainThreadShowOptions.preserveFocus = showOptions.preserveFocus;
|
||||
mainThreadShowOptions.group = viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn);
|
||||
}
|
||||
|
||||
const webview = this._webviewService.createWebview(MainThreadWebviews.viewType, title, mainThreadShowOptions, {
|
||||
...options,
|
||||
localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(URI.revive) : undefined
|
||||
}, URI.revive(extensionLocation), this.createWebviewEventDelegate(handle));
|
||||
webview.state = {
|
||||
viewType: viewType,
|
||||
state: undefined
|
||||
@@ -96,18 +105,20 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
webview.html = value;
|
||||
}
|
||||
|
||||
$reveal(handle: WebviewPanelHandle, viewColumn: Position | null, preserveFocus: boolean): void {
|
||||
$reveal(handle: WebviewPanelHandle, viewColumn: EditorViewColumn | null, preserveFocus: boolean): void {
|
||||
const webview = this.getWebview(handle);
|
||||
if (webview.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webviewService.revealWebview(webview, viewColumn, preserveFocus);
|
||||
const targetGroup = this._editorGroupService.getGroup(viewColumnToEditorGroup(this._editorGroupService, viewColumn));
|
||||
|
||||
this._webviewService.revealWebview(webview, targetGroup || this._editorGroupService.activeGroup, preserveFocus);
|
||||
}
|
||||
|
||||
async $postMessage(handle: WebviewPanelHandle, message: any): TPromise<boolean> {
|
||||
const webview = this.getWebview(handle);
|
||||
const editors = this._editorService.getVisibleEditors()
|
||||
const editors = this._editorService.visibleControls
|
||||
.filter(e => e instanceof WebviewEditor)
|
||||
.map(e => e as WebviewEditor)
|
||||
.filter(e => e.input.matches(webview));
|
||||
@@ -129,19 +140,21 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
|
||||
reviveWebview(webview: WebviewEditorInput): TPromise<void> {
|
||||
const viewType = webview.state.viewType;
|
||||
return this._extensionService.activateByEvent(`onView:${viewType}`).then(() => {
|
||||
return this._extensionService.activateByEvent(`onWebviewPanel:${viewType}`).then(() => {
|
||||
const handle = 'revival-' + MainThreadWebviews.revivalPool++;
|
||||
this._webviews.set(handle, webview);
|
||||
webview._events = this.createWebviewEventDelegate(handle);
|
||||
|
||||
let state;
|
||||
try {
|
||||
state = JSON.parse(webview.state.state);
|
||||
} catch {
|
||||
state = {};
|
||||
let state = undefined;
|
||||
if (webview.state.state) {
|
||||
try {
|
||||
state = JSON.parse(webview.state.state);
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), state, webview.position, webview.options)
|
||||
return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webview.group), webview.options)
|
||||
.then(undefined, () => {
|
||||
webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType);
|
||||
});
|
||||
@@ -149,11 +162,11 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
}
|
||||
|
||||
canRevive(webview: WebviewEditorInput): boolean {
|
||||
if (webview.isDisposed()) {
|
||||
if (webview.isDisposed() || !webview.state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (this._revivers.has(webview.viewType) || webview.reviver !== null);
|
||||
return this._revivers.has(webview.state.viewType) || !!webview.reviver;
|
||||
}
|
||||
|
||||
private _onWillShutdown(): TPromise<boolean> {
|
||||
@@ -187,8 +200,8 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
return webview;
|
||||
}
|
||||
|
||||
private onEditorsChanged() {
|
||||
const activeEditor = this._editorService.getActiveEditor();
|
||||
private onActiveEditorChanged() {
|
||||
const activeEditor = this._editorService.activeControl;
|
||||
let newActiveWebview: { input: WebviewEditorInput, handle: WebviewPanelHandle } | undefined = undefined;
|
||||
if (activeEditor && activeEditor.input instanceof WebviewEditorInput) {
|
||||
for (const handle of map.keys(this._webviews)) {
|
||||
@@ -202,7 +215,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
|
||||
if (newActiveWebview && newActiveWebview.handle === this._activeWebview) {
|
||||
// Webview itself unchanged but position may have changed
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, true, newActiveWebview.input.position);
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, true, editorGroupToViewColumn(this._editorGroupService, newActiveWebview.input.group));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,29 +223,32 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
if (typeof this._activeWebview !== 'undefined') {
|
||||
const oldActiveWebview = this._webviews.get(this._activeWebview);
|
||||
if (oldActiveWebview) {
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(this._activeWebview, false, oldActiveWebview.position);
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(this._activeWebview, false, editorGroupToViewColumn(this._editorGroupService, oldActiveWebview.group));
|
||||
}
|
||||
}
|
||||
|
||||
// Then for newly active
|
||||
if (newActiveWebview) {
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, true, activeEditor.position);
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, true, editorGroupToViewColumn(this._editorGroupService, activeEditor.group));
|
||||
this._activeWebview = newActiveWebview.handle;
|
||||
} else {
|
||||
this._activeWebview = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private onEditorGroupMoved(): void {
|
||||
for (const workbenchEditor of this._editorService.getVisibleEditors()) {
|
||||
private onVisibleEditorsChanged(): void {
|
||||
for (const workbenchEditor of this._editorService.visibleControls) {
|
||||
if (!workbenchEditor.input) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webviews.forEach((input, handle) => {
|
||||
if (workbenchEditor.input.matches(input) && input.position !== workbenchEditor.position) {
|
||||
input.updatePosition(workbenchEditor.position);
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(handle, handle === this._activeWebview, workbenchEditor.position);
|
||||
const inputPosition = editorGroupToViewColumn(this._editorGroupService, input.group);
|
||||
const editorPosition = editorGroupToViewColumn(this._editorGroupService, workbenchEditor.group);
|
||||
|
||||
if (workbenchEditor.input.matches(input) && inputPosition !== editorPosition) {
|
||||
input.updateGroup(workbenchEditor.group.id);
|
||||
this._proxy.$onDidChangeWebviewPanelViewState(handle, handle === this._activeWebview, editorPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import URI from 'vs/base/common/uri';
|
||||
import * as vscode from 'vscode';
|
||||
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// The following commands are registered on both sides separately.
|
||||
@@ -70,21 +71,21 @@ export class OpenAPICommand {
|
||||
public static ID = 'vscode.open';
|
||||
public static execute(executor: ICommandsExecutor, resource: URI, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions): Thenable<any> {
|
||||
let options: ITextEditorOptions;
|
||||
let column: EditorPosition;
|
||||
let position: EditorViewColumn;
|
||||
|
||||
if (columnOrOptions) {
|
||||
if (typeof columnOrOptions === 'number') {
|
||||
column = typeConverters.ViewColumn.from(columnOrOptions);
|
||||
position = typeConverters.ViewColumn.from(columnOrOptions);
|
||||
} else {
|
||||
options = typeConverters.TextEditorOptions.from(columnOrOptions);
|
||||
column = typeConverters.ViewColumn.from(columnOrOptions.viewColumn);
|
||||
position = typeConverters.ViewColumn.from(columnOrOptions.viewColumn);
|
||||
}
|
||||
}
|
||||
|
||||
return executor.executeCommand('_workbench.open', [
|
||||
resource,
|
||||
options,
|
||||
column
|
||||
position
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export function createApiFactory(
|
||||
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
|
||||
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
|
||||
const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, schemeTransformer));
|
||||
const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace));
|
||||
const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration));
|
||||
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
|
||||
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
|
||||
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
|
||||
@@ -140,7 +140,7 @@ export function createApiFactory(
|
||||
const extHostLanguages = new ExtHostLanguages(rpcProtocol);
|
||||
|
||||
// Register API-ish commands
|
||||
ExtHostApiCommands.register(extHostCommands, extHostTask);
|
||||
ExtHostApiCommands.register(extHostCommands);
|
||||
|
||||
return function (extension: IExtensionDescription): typeof vscode {
|
||||
|
||||
@@ -396,9 +396,6 @@ export function createApiFactory(
|
||||
showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) {
|
||||
return extHostQuickOpen.showInput(undefined, options, token);
|
||||
},
|
||||
multiStepInput<T>(handler: (input: vscode.QuickInput, token: vscode.CancellationToken) => Thenable<T>, token?: vscode.CancellationToken): Thenable<T> {
|
||||
return extHostQuickOpen.multiStepInput(handler, token);
|
||||
},
|
||||
showOpenDialog(options) {
|
||||
return extHostDialogs.showOpenDialog(options);
|
||||
},
|
||||
@@ -565,9 +562,6 @@ export function createApiFactory(
|
||||
registerFileSystemProvider(scheme, provider, options) {
|
||||
return extHostFileSystem.registerFileSystemProvider(scheme, provider, options);
|
||||
},
|
||||
registerDeprecatedFileSystemProvider: proposedApiFunction(extension, (scheme, provider) => {
|
||||
return extHostFileSystem.registerDeprecatedFileSystemProvider(scheme, provider);
|
||||
}),
|
||||
registerSearchProvider: proposedApiFunction(extension, (scheme, provider) => {
|
||||
return extHostSearch.registerSearchProvider(scheme, provider);
|
||||
}),
|
||||
@@ -576,6 +570,9 @@ export function createApiFactory(
|
||||
}),
|
||||
registerWorkspaceCommentProvider: proposedApiFunction(extension, (provider: vscode.WorkspaceCommentProvider) => {
|
||||
return exthostCommentProviders.registerWorkspaceCommentProvider(provider);
|
||||
}),
|
||||
onDidRenameResource: proposedApiFunction(extension, (listener, thisArg?, disposables?) => {
|
||||
return extHostDocuments.onDidRenameResource(listener, thisArg, disposables);
|
||||
})
|
||||
};
|
||||
|
||||
@@ -633,12 +630,12 @@ export function createApiFactory(
|
||||
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
},
|
||||
fetchTasks: proposedApiFunction(extension, (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
|
||||
fetchTasks: (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
|
||||
return extHostTask.fetchTasks(filter);
|
||||
}),
|
||||
executeTask: proposedApiFunction(extension, (task: vscode.Task): Thenable<vscode.TaskExecution> => {
|
||||
},
|
||||
executeTask: (task: vscode.Task): Thenable<vscode.TaskExecution> => {
|
||||
return extHostTask.executeTask(extension, task);
|
||||
}),
|
||||
},
|
||||
get taskExecutions(): vscode.TaskExecution[] {
|
||||
return extHostTask.taskExecutions;
|
||||
},
|
||||
@@ -677,6 +674,7 @@ export function createApiFactory(
|
||||
Color: extHostTypes.Color,
|
||||
ColorPresentation: extHostTypes.ColorPresentation,
|
||||
ColorInformation: extHostTypes.ColorInformation,
|
||||
CodeActionTrigger: extHostTypes.CodeActionTrigger,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
CompletionItem: extHostTypes.CompletionItem,
|
||||
CompletionItemKind: extHostTypes.CompletionItemKind,
|
||||
@@ -750,8 +748,6 @@ export function createApiFactory(
|
||||
ConfigurationTarget: extHostTypes.ConfigurationTarget,
|
||||
RelativePattern: extHostTypes.RelativePattern,
|
||||
|
||||
DeprecatedFileChangeType: extHostTypes.DeprecatedFileChangeType,
|
||||
DeprecatedFileType: extHostTypes.DeprecatedFileType,
|
||||
FileChangeType: extHostTypes.FileChangeType,
|
||||
FileType: files.FileType,
|
||||
FileSystemError: extHostTypes.FileSystemError,
|
||||
|
||||
@@ -13,7 +13,7 @@ import Severity from 'vs/base/common/severity';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
import { IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -48,7 +48,7 @@ import { CommentRule, CharacterPair, EnterAction } from 'vs/editor/common/modes/
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import { IPatternInfo, IRawSearchQuery, IRawFileMatch2, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { LogLevel } from 'vs/platform/log/common/log';
|
||||
import { TaskExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO } from 'vs/workbench/api/shared/tasks';
|
||||
import { TaskExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO } from 'vs/workbench/api/shared/tasks';
|
||||
|
||||
export interface IEnvironment {
|
||||
isExtensionDevelopmentDebug: boolean;
|
||||
@@ -189,7 +189,7 @@ export interface IApplyEditsOptions extends IUndoStopOptions {
|
||||
}
|
||||
|
||||
export interface ITextDocumentShowOptions {
|
||||
position?: EditorPosition;
|
||||
position?: EditorViewColumn;
|
||||
preserveFocus?: boolean;
|
||||
pinned?: boolean;
|
||||
selection?: IRange;
|
||||
@@ -199,7 +199,7 @@ export interface MainThreadTextEditorsShape extends IDisposable {
|
||||
$tryShowTextDocument(resource: UriComponents, options: ITextDocumentShowOptions): TPromise<string>;
|
||||
$registerTextEditorDecorationType(key: string, options: editorCommon.IDecorationRenderOptions): void;
|
||||
$removeTextEditorDecorationType(key: string): void;
|
||||
$tryShowEditor(id: string, position: EditorPosition): TPromise<void>;
|
||||
$tryShowEditor(id: string, position: EditorViewColumn): TPromise<void>;
|
||||
$tryHideEditor(id: string): TPromise<void>;
|
||||
$trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise<void>;
|
||||
$trySetDecorations(id: string, key: string, ranges: editorCommon.IDecorationOptions[]): TPromise<void>;
|
||||
@@ -364,9 +364,9 @@ export interface MainThreadTelemetryShape extends IDisposable {
|
||||
export type WebviewPanelHandle = string;
|
||||
|
||||
export interface MainThreadWebviewsShape extends IDisposable {
|
||||
$createWebviewPanel(handle: WebviewPanelHandle, viewType: string, title: string, viewOptions: { viewColumn: EditorPosition, preserveFocus: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions, extensionLocation: UriComponents): void;
|
||||
$createWebviewPanel(handle: WebviewPanelHandle, viewType: string, title: string, viewOptions: { viewColumn: EditorViewColumn, preserveFocus: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions, extensionLocation: UriComponents): void;
|
||||
$disposeWebview(handle: WebviewPanelHandle): void;
|
||||
$reveal(handle: WebviewPanelHandle, viewColumn: EditorPosition | null, preserveFocus: boolean): void;
|
||||
$reveal(handle: WebviewPanelHandle, viewColumn: EditorViewColumn | null, preserveFocus: boolean): void;
|
||||
$setTitle(handle: WebviewPanelHandle, value: string): void;
|
||||
$setHtml(handle: WebviewPanelHandle, value: string): void;
|
||||
$postMessage(handle: WebviewPanelHandle, value: any): Thenable<boolean>;
|
||||
@@ -377,9 +377,9 @@ export interface MainThreadWebviewsShape extends IDisposable {
|
||||
|
||||
export interface ExtHostWebviewsShape {
|
||||
$onMessage(handle: WebviewPanelHandle, message: any): void;
|
||||
$onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, active: boolean, position: EditorPosition): void;
|
||||
$onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, active: boolean, position: EditorViewColumn): void;
|
||||
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Thenable<void>;
|
||||
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): Thenable<void>;
|
||||
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: vscode.WebviewOptions): Thenable<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadUrlsShape extends IDisposable {
|
||||
@@ -418,10 +418,11 @@ export interface MainThreadSearchShape extends IDisposable {
|
||||
|
||||
export interface MainThreadTaskShape extends IDisposable {
|
||||
$registerTaskProvider(handle: number): TPromise<void>;
|
||||
$unregisterTaskProvider(handle: number): TPromise<void>;
|
||||
$fetchTasks(filter?: TaskFilterDTO): TPromise<TaskDTO[]>;
|
||||
$executeTask(task: TaskHandleDTO | TaskDTO): TPromise<TaskExecutionDTO>;
|
||||
$terminateTask(id: string): TPromise<void>;
|
||||
$unregisterTaskProvider(handle: number): TPromise<void>;
|
||||
$registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void;
|
||||
}
|
||||
|
||||
export interface MainThreadExtensionServiceShape extends IDisposable {
|
||||
@@ -538,6 +539,7 @@ export interface ExtHostDocumentsShape {
|
||||
$acceptModelSaved(strURL: UriComponents): void;
|
||||
$acceptDirtyStateChanged(strURL: UriComponents, isDirty: boolean): void;
|
||||
$acceptModelChanged(strURL: UriComponents, e: IModelChangedEvent, isDirty: boolean): void;
|
||||
$onDidRename(oldURL: UriComponents, newURL: UriComponents): void;
|
||||
}
|
||||
|
||||
export interface ExtHostDocumentSaveParticipantShape {
|
||||
@@ -550,10 +552,10 @@ export interface ITextEditorAddData {
|
||||
options: IResolvedTextEditorConfiguration;
|
||||
selections: ISelection[];
|
||||
visibleRanges: IRange[];
|
||||
editorPosition: EditorPosition;
|
||||
editorPosition: EditorViewColumn;
|
||||
}
|
||||
export interface ITextEditorPositionData {
|
||||
[id: string]: EditorPosition;
|
||||
[id: string]: EditorViewColumn;
|
||||
}
|
||||
export interface IEditorPropertiesChangeData {
|
||||
options: IResolvedTextEditorConfiguration | null;
|
||||
@@ -790,6 +792,7 @@ export interface ExtHostTaskShape {
|
||||
$onDidStartTaskProcess(value: TaskProcessStartedDTO): void;
|
||||
$onDidEndTaskProcess(value: TaskProcessEndedDTO): void;
|
||||
$OnDidEndTask(execution: TaskExecutionDTO): void;
|
||||
$resolveVariables(workspaceFolder: URI, variables: string[]): TPromise<any>;
|
||||
}
|
||||
|
||||
export interface IBreakpointDto {
|
||||
@@ -836,6 +839,8 @@ export interface ISourceMultiBreakpointDto {
|
||||
export interface ExtHostDebugServiceShape {
|
||||
$substituteVariables(folder: UriComponents | undefined, config: IConfig): TPromise<IConfig>;
|
||||
$runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void>;
|
||||
$isTerminalBusy(processId: number): TPromise<boolean>;
|
||||
$prepareCommandForTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<any>;
|
||||
$startDASession(handle: number, debugType: string, adapterExecutableInfo: IAdapterExecutable | null, debugPort: number): TPromise<void>;
|
||||
$stopDASession(handle: number): TPromise<void>;
|
||||
$sendDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): TPromise<void>;
|
||||
|
||||
@@ -18,22 +18,19 @@ import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
|
||||
import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures';
|
||||
import { ExtHostTask } from './extHostTask';
|
||||
import { ICommandsExecutor, PreviewHTMLAPICommand, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand } from './apiCommands';
|
||||
|
||||
export class ExtHostApiCommands {
|
||||
|
||||
static register(commands: ExtHostCommands, workspace: ExtHostTask) {
|
||||
return new ExtHostApiCommands(commands, workspace).registerCommands();
|
||||
static register(commands: ExtHostCommands) {
|
||||
return new ExtHostApiCommands(commands).registerCommands();
|
||||
}
|
||||
|
||||
private _commands: ExtHostCommands;
|
||||
private _tasks: ExtHostTask;
|
||||
private _disposables: IDisposable[] = [];
|
||||
|
||||
private constructor(commands: ExtHostCommands, task: ExtHostTask) {
|
||||
private constructor(commands: ExtHostCommands) {
|
||||
this._commands = commands;
|
||||
this._tasks = task;
|
||||
}
|
||||
|
||||
registerCommands() {
|
||||
@@ -176,11 +173,6 @@ export class ExtHostApiCommands {
|
||||
],
|
||||
returns: 'A promise that resolves to an array of DocumentLink-instances.'
|
||||
});
|
||||
this._register('vscode.executeTaskProvider', this._executeTaskProvider, {
|
||||
description: 'Execute task provider',
|
||||
args: [],
|
||||
returns: 'An array of task handles'
|
||||
});
|
||||
this._register('vscode.executeDocumentColorProvider', this._executeDocumentColorProvider, {
|
||||
description: 'Execute document color provider.',
|
||||
args: [
|
||||
@@ -494,10 +486,6 @@ export class ExtHostApiCommands {
|
||||
return this._commands.executeCommand<modes.ILink[]>('_executeLinkProvider', resource)
|
||||
.then(tryMapWith(typeConverters.DocumentLink.to));
|
||||
}
|
||||
|
||||
private _executeTaskProvider(): Thenable<vscode.Task[]> {
|
||||
return this._tasks.fetchTasks();
|
||||
}
|
||||
}
|
||||
|
||||
function tryMapWith<T, R>(f: (x: T) => R) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs
|
||||
import { Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { WorkspaceConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
|
||||
declare var Proxy: any; // TODO@TypeScript
|
||||
@@ -191,7 +191,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
}
|
||||
|
||||
private _validateConfigurationAccess(key: string, resource: URI, extensionId: string): void {
|
||||
const scope = this._configurationScopes[key];
|
||||
const scope = OVERRIDE_PROPERTY_PATTERN.test(key) ? ConfigurationScope.RESOURCE : this._configurationScopes[key];
|
||||
const extensionIdText = extensionId ? `[${extensionId}] ` : '';
|
||||
if (ConfigurationScope.RESOURCE === scope) {
|
||||
if (resource === void 0) {
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { IAdapterExecutable, ITerminalSettings, IDebuggerContribution, IConfig, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { getTerminalLauncher } from 'vs/workbench/parts/debug/node/terminals';
|
||||
import { getTerminalLauncher, hasChildprocesses, prepareCommand } from 'vs/workbench/parts/debug/node/terminals';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { VariableResolver } from 'vs/workbench/services/configurationResolver/node/variableResolver';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
@@ -68,7 +68,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
|
||||
|
||||
constructor(mainContext: IMainContext,
|
||||
private _workspace: ExtHostWorkspace,
|
||||
private _workspaceService: ExtHostWorkspace,
|
||||
private _extensionService: ExtHostExtensionService,
|
||||
private _editorsService: ExtHostDocumentsAndEditors,
|
||||
private _configurationService: ExtHostConfiguration
|
||||
@@ -125,12 +125,28 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
public $isTerminalBusy(processId: number): TPromise<boolean> {
|
||||
return asWinJsPromise(token => hasChildprocesses(processId));
|
||||
}
|
||||
|
||||
public $prepareCommandForTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<any> {
|
||||
return asWinJsPromise(token => prepareCommand(args, config));
|
||||
}
|
||||
|
||||
public $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): TPromise<IConfig> {
|
||||
if (!this._variableResolver) {
|
||||
this._variableResolver = new ExtHostVariableResolverService(this._workspace, this._editorsService, this._configurationService);
|
||||
this._variableResolver = new ExtHostVariableResolverService(this._workspaceService, this._editorsService, this._configurationService);
|
||||
}
|
||||
const folder = <IWorkspaceFolder>this.getFolder(folderUri);
|
||||
return asWinJsPromise(token => DebugAdapter.substituteVariables(folder, config, this._variableResolver));
|
||||
const folder = this.getFolder(folderUri);
|
||||
let ws: IWorkspaceFolder = {
|
||||
uri: folder.uri,
|
||||
name: folder.name,
|
||||
index: folder.index,
|
||||
toResource: () => {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
};
|
||||
return asWinJsPromise(token => DebugAdapter.substituteVariables(ws, config, this._variableResolver));
|
||||
}
|
||||
|
||||
public $startDASession(handle: number, debugType: string, adpaterExecutable: IAdapterExecutable | null, debugPort: number): TPromise<void> {
|
||||
@@ -479,14 +495,10 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
this._onDidReceiveDebugSessionCustomEvent.fire(ee);
|
||||
}
|
||||
|
||||
private getFolder(_folderUri: UriComponents | undefined) {
|
||||
private getFolder(_folderUri: UriComponents | undefined): vscode.WorkspaceFolder {
|
||||
if (_folderUri) {
|
||||
const folderUriString = URI.revive(_folderUri).toString();
|
||||
const folders = this._workspace.getWorkspaceFolders();
|
||||
const found = folders.filter(f => f.uri.toString() === folderUriString);
|
||||
if (found && found.length > 0) {
|
||||
return found[0];
|
||||
}
|
||||
const folderURI = URI.revive(_folderUri);
|
||||
return this._workspaceService.resolveWorkspaceFolder(folderURI);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -17,17 +17,17 @@ import { keys } from 'vs/base/common/map';
|
||||
|
||||
export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
private static readonly _maxDiagnosticsPerFile: number = 250;
|
||||
|
||||
private readonly _name: string;
|
||||
private readonly _maxDiagnosticsPerFile: number;
|
||||
private readonly _onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>;
|
||||
|
||||
private _proxy: MainThreadDiagnosticsShape;
|
||||
private _isDisposed = false;
|
||||
private _data = new Map<string, vscode.Diagnostic[]>();
|
||||
|
||||
constructor(name: string, proxy: MainThreadDiagnosticsShape, onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>) {
|
||||
constructor(name: string, maxDiagnosticsPerFile: number, proxy: MainThreadDiagnosticsShape, onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>) {
|
||||
this._name = name;
|
||||
this._maxDiagnosticsPerFile = maxDiagnosticsPerFile;
|
||||
this._proxy = proxy;
|
||||
this._onDidChangeDiagnostics = onDidChangeDiagnostics;
|
||||
}
|
||||
@@ -109,15 +109,15 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
let diagnostics = this._data.get(uri.toString());
|
||||
if (diagnostics) {
|
||||
|
||||
// no more than 250 diagnostics per file
|
||||
if (diagnostics.length > DiagnosticCollection._maxDiagnosticsPerFile) {
|
||||
// no more than N diagnostics per file
|
||||
if (diagnostics.length > this._maxDiagnosticsPerFile) {
|
||||
marker = [];
|
||||
const order = [DiagnosticSeverity.Error, DiagnosticSeverity.Warning, DiagnosticSeverity.Information, DiagnosticSeverity.Hint];
|
||||
orderLoop: for (let i = 0; i < 4; i++) {
|
||||
for (let diagnostic of diagnostics) {
|
||||
if (diagnostic.severity === order[i]) {
|
||||
const len = marker.push(converter.Diagnostic.from(diagnostic));
|
||||
if (len === DiagnosticCollection._maxDiagnosticsPerFile) {
|
||||
if (len === this._maxDiagnosticsPerFile) {
|
||||
break orderLoop;
|
||||
}
|
||||
}
|
||||
@@ -126,8 +126,8 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
// add 'signal' marker for showing omitted errors/warnings
|
||||
marker.push({
|
||||
severity: MarkerSeverity.Error,
|
||||
message: localize({ key: 'limitHit', comment: ['amount of errors/warning skipped due to limits'] }, "Not showing {0} further errors and warnings.", diagnostics.length - DiagnosticCollection._maxDiagnosticsPerFile),
|
||||
severity: MarkerSeverity.Info,
|
||||
message: localize({ key: 'limitHit', comment: ['amount of errors/warning skipped due to limits'] }, "Not showing {0} further errors and warnings.", diagnostics.length - this._maxDiagnosticsPerFile),
|
||||
startLineNumber: marker[marker.length - 1].startLineNumber,
|
||||
startColumn: marker[marker.length - 1].startColumn,
|
||||
endLineNumber: marker[marker.length - 1].endLineNumber,
|
||||
@@ -201,6 +201,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
|
||||
private static _idPool: number = 0;
|
||||
private static readonly _maxDiagnosticsPerFile: number = 1000;
|
||||
|
||||
private readonly _proxy: MainThreadDiagnosticsShape;
|
||||
private readonly _collections: DiagnosticCollection[] = [];
|
||||
@@ -248,7 +249,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
const { _collections, _proxy, _onDidChangeDiagnostics } = this;
|
||||
const result = new class extends DiagnosticCollection {
|
||||
constructor() {
|
||||
super(name, _proxy, _onDidChangeDiagnostics);
|
||||
super(name, ExtHostDiagnostics._maxDiagnosticsPerFile, _proxy, _onDidChangeDiagnostics);
|
||||
_collections.push(this);
|
||||
}
|
||||
dispose() {
|
||||
|
||||
@@ -21,11 +21,13 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
private _onDidRemoveDocument = new Emitter<vscode.TextDocument>();
|
||||
private _onDidChangeDocument = new Emitter<vscode.TextDocumentChangeEvent>();
|
||||
private _onDidSaveDocument = new Emitter<vscode.TextDocument>();
|
||||
private _onDidRenameResource = new Emitter<vscode.ResourceRenamedEvent>();
|
||||
|
||||
readonly onDidAddDocument: Event<vscode.TextDocument> = this._onDidAddDocument.event;
|
||||
readonly onDidRemoveDocument: Event<vscode.TextDocument> = this._onDidRemoveDocument.event;
|
||||
readonly onDidChangeDocument: Event<vscode.TextDocumentChangeEvent> = this._onDidChangeDocument.event;
|
||||
readonly onDidSaveDocument: Event<vscode.TextDocument> = this._onDidSaveDocument.event;
|
||||
readonly onDidRenameResource: Event<vscode.ResourceRenamedEvent> = this._onDidRenameResource.event;
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
private _proxy: MainThreadDocumentsShape;
|
||||
@@ -148,4 +150,11 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
public setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void {
|
||||
setWordDefinitionFor(modeId, wordDefinition);
|
||||
}
|
||||
|
||||
public $onDidRename(oldURL: UriComponents, newURL: UriComponents): void {
|
||||
const oldResource = URI.revive(oldURL);
|
||||
const newResource = URI.revive(newURL);
|
||||
this._onDidRenameResource.fire({ oldResource, newResource });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Event, mapEvent } from 'vs/base/common/event';
|
||||
import { MainContext, IMainContext, ExtHostFileSystemShape, MainThreadFileSystemShape, IFileChangeDto } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import * as files from 'vs/platform/files/common/files';
|
||||
import * as path from 'path';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { Range, DeprecatedFileType, DeprecatedFileChangeType, FileChangeType } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { Range, FileChangeType } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
@@ -34,7 +32,7 @@ class FsLinkProvider implements vscode.DocumentLinkProvider {
|
||||
}
|
||||
}
|
||||
|
||||
provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult<vscode.DocumentLink[]> {
|
||||
provideDocumentLinks(document: vscode.TextDocument): vscode.ProviderResult<vscode.DocumentLink[]> {
|
||||
if (this._schemes.size === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -60,106 +58,6 @@ class FsLinkProvider implements vscode.DocumentLinkProvider {
|
||||
}
|
||||
}
|
||||
|
||||
class FileSystemProviderShim implements vscode.FileSystemProvider {
|
||||
|
||||
onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]>;
|
||||
|
||||
constructor(private readonly _delegate: vscode.DeprecatedFileSystemProvider) {
|
||||
if (!this._delegate.onDidChange) {
|
||||
this.onDidChangeFile = Event.None;
|
||||
} else {
|
||||
this.onDidChangeFile = mapEvent(this._delegate.onDidChange, old => old.map(FileSystemProviderShim._modernizeFileChange));
|
||||
}
|
||||
}
|
||||
|
||||
watch(uri: vscode.Uri, options: {}): vscode.Disposable {
|
||||
// does nothing because in the old API there was no notion of
|
||||
// watch and provider decide what file events to generate...
|
||||
return { dispose() { } };
|
||||
}
|
||||
|
||||
stat(resource: vscode.Uri): Thenable<vscode.FileStat> {
|
||||
return this._delegate.stat(resource).then(stat => FileSystemProviderShim._modernizeFileStat(stat));
|
||||
}
|
||||
rename(oldUri: vscode.Uri, newUri: vscode.Uri): Thenable<void> {
|
||||
return this._delegate.move(oldUri, newUri).then(stat => void 0);
|
||||
}
|
||||
readDirectory(resource: vscode.Uri): Thenable<[string, vscode.FileType][]> {
|
||||
return this._delegate.readdir(resource).then(tuples => {
|
||||
return tuples.map(tuple => <[string, vscode.FileType]>[path.posix.basename(tuple[0].path), FileSystemProviderShim._modernizeFileStat(tuple[1]).type]);
|
||||
});
|
||||
}
|
||||
|
||||
private static _modernizeFileStat(stat: vscode.DeprecatedFileStat): vscode.FileStat {
|
||||
let { mtime, size, type } = stat;
|
||||
let newType: files.FileType;
|
||||
|
||||
// no support for bitmask, effectively no support for symlinks
|
||||
switch (type) {
|
||||
case DeprecatedFileType.Dir:
|
||||
newType = files.FileType.Directory;
|
||||
break;
|
||||
case DeprecatedFileType.File:
|
||||
newType = files.FileType.File;
|
||||
break;
|
||||
case DeprecatedFileType.Symlink:
|
||||
newType = files.FileType.File & files.FileType.SymbolicLink;
|
||||
break;
|
||||
}
|
||||
return { type: newType, ctime: 0, mtime, size };
|
||||
}
|
||||
|
||||
private static _modernizeFileChange(e: vscode.DeprecatedFileChange): vscode.FileChangeEvent {
|
||||
let { resource, type } = e;
|
||||
let newType: vscode.FileChangeType;
|
||||
switch (type) {
|
||||
case DeprecatedFileChangeType.Updated:
|
||||
newType = FileChangeType.Changed;
|
||||
break;
|
||||
case DeprecatedFileChangeType.Added:
|
||||
newType = FileChangeType.Created;
|
||||
break;
|
||||
case DeprecatedFileChangeType.Deleted:
|
||||
newType = FileChangeType.Deleted;
|
||||
break;
|
||||
|
||||
}
|
||||
return { uri: resource, type: newType };
|
||||
}
|
||||
|
||||
// --- delete/create file or folder
|
||||
|
||||
delete(resource: vscode.Uri): Thenable<void> {
|
||||
return this._delegate.stat(resource).then(stat => {
|
||||
if (stat.type === DeprecatedFileType.Dir) {
|
||||
return this._delegate.rmdir(resource);
|
||||
} else {
|
||||
return this._delegate.unlink(resource);
|
||||
}
|
||||
});
|
||||
}
|
||||
createDirectory(resource: vscode.Uri): Thenable<void> {
|
||||
return this._delegate.mkdir(resource).then(stat => void 0);
|
||||
}
|
||||
|
||||
// --- read/write
|
||||
|
||||
readFile(resource: vscode.Uri): Thenable<Uint8Array> {
|
||||
let chunks: Buffer[] = [];
|
||||
return this._delegate.read(resource, 0, -1, {
|
||||
report(data) {
|
||||
chunks.push(Buffer.from(data));
|
||||
}
|
||||
}).then(() => {
|
||||
return Buffer.concat(chunks);
|
||||
});
|
||||
}
|
||||
|
||||
writeFile(resource: vscode.Uri, content: Uint8Array, options: files.FileWriteOptions): Thenable<void> {
|
||||
return this._delegate.write(resource, content);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostFileSystem implements ExtHostFileSystemShape {
|
||||
|
||||
private readonly _proxy: MainThreadFileSystemShape;
|
||||
@@ -185,11 +83,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
|
||||
extHostLanguageFeatures.registerDocumentLinkProvider('*', this._linkProvider);
|
||||
}
|
||||
|
||||
registerDeprecatedFileSystemProvider(scheme: string, provider: vscode.DeprecatedFileSystemProvider) {
|
||||
return this.registerFileSystemProvider(scheme, new FileSystemProviderShim(provider), { isCaseSensitive: false });
|
||||
}
|
||||
|
||||
registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider, options: { isCaseSensitive?: boolean }) {
|
||||
registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider, options: { isCaseSensitive?: boolean } = {}) {
|
||||
|
||||
if (this._usedSchemes.has(scheme)) {
|
||||
throw new Error(`a provider for the scheme '${scheme}' is already registered`);
|
||||
@@ -252,15 +146,15 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
|
||||
}
|
||||
|
||||
$stat(handle: number, resource: UriComponents): TPromise<files.IStat, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat);
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat);
|
||||
}
|
||||
|
||||
$readdir(handle: number, resource: UriComponents): TPromise<[string, files.FileType][], any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).readDirectory(URI.revive(resource)));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).readDirectory(URI.revive(resource)));
|
||||
}
|
||||
|
||||
$readFile(handle: number, resource: UriComponents): TPromise<string> {
|
||||
return asWinJsPromise(token => {
|
||||
return asWinJsPromise(() => {
|
||||
return this._fsProvider.get(handle).readFile(URI.revive(resource));
|
||||
}).then(data => {
|
||||
return Buffer.isBuffer(data) ? data.toString('base64') : Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('base64');
|
||||
@@ -268,33 +162,33 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
|
||||
}
|
||||
|
||||
$writeFile(handle: number, resource: UriComponents, base64Content: string, opts: files.FileWriteOptions): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).writeFile(URI.revive(resource), Buffer.from(base64Content, 'base64'), opts));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).writeFile(URI.revive(resource), Buffer.from(base64Content, 'base64'), opts));
|
||||
}
|
||||
|
||||
$delete(handle: number, resource: UriComponents): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).delete(URI.revive(resource), { recursive: true }));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).delete(URI.revive(resource), { recursive: true }));
|
||||
}
|
||||
|
||||
$rename(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts));
|
||||
}
|
||||
|
||||
$copy(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).copy(URI.revive(oldUri), URI.revive(newUri), opts));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).copy(URI.revive(oldUri), URI.revive(newUri), opts));
|
||||
}
|
||||
|
||||
$mkdir(handle: number, resource: UriComponents): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._fsProvider.get(handle).createDirectory(URI.revive(resource)));
|
||||
return asWinJsPromise(() => this._fsProvider.get(handle).createDirectory(URI.revive(resource)));
|
||||
}
|
||||
|
||||
$watch(handle: number, session: number, resource: UriComponents, opts: files.IWatchOptions): void {
|
||||
asWinJsPromise(token => {
|
||||
asWinJsPromise(() => {
|
||||
let subscription = this._fsProvider.get(handle).watch(URI.revive(resource), opts);
|
||||
this._watches.set(session, subscription);
|
||||
});
|
||||
}
|
||||
|
||||
$unwatch(handle: number, session: number): void {
|
||||
$unwatch(session: number): void {
|
||||
let subscription = this._watches.get(session);
|
||||
if (subscription) {
|
||||
subscription.dispose();
|
||||
|
||||
@@ -65,6 +65,9 @@ class OutlineAdapter {
|
||||
let parentStack: Hierarchy<SymbolInformation2>[] = [];
|
||||
for (let i = 0; i < info.length; i++) {
|
||||
let element = new Hierarchy(new SymbolInformation2(info[i].name, '', info[i].kind, info[i].location.range, info[i].location));
|
||||
element.parent.containerName = info[i].containerName;
|
||||
element.parent.location = info[i].location; // todo@joh make this proper
|
||||
|
||||
while (true) {
|
||||
if (parentStack.length === 0) {
|
||||
parentStack.push(element);
|
||||
@@ -72,7 +75,7 @@ class OutlineAdapter {
|
||||
break;
|
||||
}
|
||||
let parent = parentStack[parentStack.length - 1];
|
||||
if (parent.parent.range.contains(element.parent.range)) {
|
||||
if (parent.parent.range.contains(element.parent.range) && !parent.parent.range.isEqual(element.parent.range)) {
|
||||
parent.children.push(element);
|
||||
parentStack.push(element);
|
||||
break;
|
||||
@@ -88,17 +91,12 @@ class CodeLensAdapter {
|
||||
|
||||
private static _badCmd: vscode.Command = { command: 'missing', title: '<<MISSING COMMAND>>' };
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: CommandsConverter;
|
||||
private _heapService: ExtHostHeapService;
|
||||
private _provider: vscode.CodeLensProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, heapService: ExtHostHeapService, provider: vscode.CodeLensProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._heapService = heapService;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _commands: CommandsConverter,
|
||||
private readonly _heapService: ExtHostHeapService,
|
||||
private readonly _provider: vscode.CodeLensProvider
|
||||
) { }
|
||||
|
||||
provideCodeLenses(resource: URI): TPromise<modes.ICodeLensSymbol[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
@@ -140,13 +138,11 @@ class CodeLensAdapter {
|
||||
}
|
||||
|
||||
class DefinitionAdapter {
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.DefinitionProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.DefinitionProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DefinitionProvider
|
||||
) { }
|
||||
|
||||
provideDefinition(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
@@ -163,13 +159,11 @@ class DefinitionAdapter {
|
||||
}
|
||||
|
||||
class ImplementationAdapter {
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.ImplementationProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.ImplementationProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.ImplementationProvider
|
||||
) { }
|
||||
|
||||
provideImplementation(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
@@ -186,13 +180,11 @@ class ImplementationAdapter {
|
||||
}
|
||||
|
||||
class TypeDefinitionAdapter {
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.TypeDefinitionProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.TypeDefinitionProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.TypeDefinitionProvider
|
||||
) { }
|
||||
|
||||
provideTypeDefinition(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
@@ -208,15 +200,12 @@ class TypeDefinitionAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HoverAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.HoverProvider,
|
||||
) {
|
||||
//
|
||||
}
|
||||
) { }
|
||||
|
||||
public provideHover(resource: URI, position: IPosition): TPromise<modes.Hover> {
|
||||
|
||||
@@ -241,13 +230,10 @@ class HoverAdapter {
|
||||
|
||||
class DocumentHighlightAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.DocumentHighlightProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.DocumentHighlightProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentHighlightProvider
|
||||
) { }
|
||||
|
||||
provideDocumentHighlights(resource: URI, position: IPosition): TPromise<modes.DocumentHighlight[]> {
|
||||
|
||||
@@ -265,13 +251,10 @@ class DocumentHighlightAdapter {
|
||||
|
||||
class ReferenceAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.ReferenceProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.ReferenceProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.ReferenceProvider
|
||||
) { }
|
||||
|
||||
provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
@@ -315,7 +298,8 @@ class CodeActionAdapter {
|
||||
|
||||
const codeActionContext: vscode.CodeActionContext = {
|
||||
diagnostics: allDiagnostics,
|
||||
only: context.only ? new CodeActionKind(context.only) : undefined
|
||||
only: context.only ? new CodeActionKind(context.only) : undefined,
|
||||
triggerKind: context.trigger,
|
||||
};
|
||||
|
||||
return asWinJsPromise(token =>
|
||||
@@ -359,13 +343,10 @@ class CodeActionAdapter {
|
||||
|
||||
class DocumentFormattingAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.DocumentFormattingEditProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.DocumentFormattingEditProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentFormattingEditProvider
|
||||
) { }
|
||||
|
||||
provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions): TPromise<ISingleEditOperation[]> {
|
||||
|
||||
@@ -382,13 +363,10 @@ class DocumentFormattingAdapter {
|
||||
|
||||
class RangeFormattingAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.DocumentRangeFormattingEditProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.DocumentRangeFormattingEditProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentRangeFormattingEditProvider
|
||||
) { }
|
||||
|
||||
provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions): TPromise<ISingleEditOperation[]> {
|
||||
|
||||
@@ -406,13 +384,10 @@ class RangeFormattingAdapter {
|
||||
|
||||
class OnTypeFormattingAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.OnTypeFormattingEditProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.OnTypeFormattingEditProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.OnTypeFormattingEditProvider
|
||||
) { }
|
||||
|
||||
autoFormatTriggerCharacters: string[] = []; // not here
|
||||
|
||||
@@ -498,13 +473,10 @@ class RenameAdapter {
|
||||
return typeof provider.prepareRename === 'function';
|
||||
}
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.RenameProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.RenameProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.RenameProvider
|
||||
) { }
|
||||
|
||||
provideRenameEdits(resource: URI, position: IPosition, newName: string): TPromise<modes.WorkspaceEdit> {
|
||||
|
||||
@@ -733,13 +705,10 @@ class SuggestAdapter {
|
||||
|
||||
class SignatureHelpAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.SignatureHelpProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.SignatureHelpProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.SignatureHelpProvider
|
||||
) { }
|
||||
|
||||
provideSignatureHelp(resource: URI, position: IPosition): TPromise<modes.SignatureHelp> {
|
||||
|
||||
@@ -757,15 +726,11 @@ class SignatureHelpAdapter {
|
||||
|
||||
class LinkProviderAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _heapService: ExtHostHeapService;
|
||||
private _provider: vscode.DocumentLinkProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, heapService: ExtHostHeapService, provider: vscode.DocumentLinkProvider) {
|
||||
this._documents = documents;
|
||||
this._heapService = heapService;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _heapService: ExtHostHeapService,
|
||||
private readonly _provider: vscode.DocumentLinkProvider
|
||||
) { }
|
||||
|
||||
provideLinks(resource: URI): TPromise<modes.ILink[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { wireCancellationToken, asWinJsPromise } from 'vs/base/common/async';
|
||||
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { QuickPickOptions, QuickPickItem, InputBoxOptions, WorkspaceFolderPickOptions, WorkspaceFolder, QuickInput } from 'vscode';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { QuickPickOptions, QuickPickItem, InputBoxOptions, WorkspaceFolderPickOptions, WorkspaceFolder } from 'vscode';
|
||||
import { MainContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems, IMainContext } from './extHost.protocol';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
|
||||
export type Item = string | QuickPickItem;
|
||||
|
||||
@@ -24,8 +23,6 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
private _onDidSelectItem: (handle: number) => void;
|
||||
private _validateInput: (input: string) => string | Thenable<string>;
|
||||
|
||||
private _nextMultiStepHandle = 1;
|
||||
|
||||
constructor(mainContext: IMainContext, workspace: ExtHostWorkspace, commands: ExtHostCommands) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadQuickOpen);
|
||||
this._workspace = workspace;
|
||||
@@ -145,42 +142,4 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
return this._workspace.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0];
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Multi-step input
|
||||
|
||||
multiStepInput<T>(handler: (input: QuickInput, token: CancellationToken) => Thenable<T>, clientToken: CancellationToken = CancellationToken.None): Thenable<T> {
|
||||
const handle = this._nextMultiStepHandle++;
|
||||
const remotePromise = this._proxy.$multiStep(handle);
|
||||
|
||||
const cancellationSource = new CancellationTokenSource();
|
||||
const handlerPromise = TPromise.wrap(handler({
|
||||
showQuickPick: this.showQuickPick.bind(this, handle),
|
||||
showInputBox: this.showInput.bind(this, handle)
|
||||
}, cancellationSource.token));
|
||||
|
||||
clientToken.onCancellationRequested(() => {
|
||||
remotePromise.cancel();
|
||||
cancellationSource.cancel();
|
||||
});
|
||||
|
||||
return TPromise.join<void, T>([
|
||||
remotePromise.then(() => {
|
||||
throw new Error('Unexpectedly fulfilled promise.');
|
||||
}, err => {
|
||||
if (!isPromiseCanceledError(err)) {
|
||||
throw err;
|
||||
}
|
||||
cancellationSource.cancel();
|
||||
}),
|
||||
handlerPromise.then(result => {
|
||||
remotePromise.cancel();
|
||||
return result;
|
||||
}, err => {
|
||||
remotePromise.cancel();
|
||||
throw err;
|
||||
})
|
||||
]).then(([_, result]) => result, ([remoteErr, handlerErr]) => {
|
||||
throw handlerErr || remoteErr;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ import * as strings from 'vs/base/common/strings';
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { PPromise, TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IItemAccessor, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { ICachedSearchStats, IRawFileMatch2, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchQuery, ISearchCompleteStats, IFileMatch } from 'vs/platform/search/common/search';
|
||||
import { ICachedSearchStats, IFileMatch, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchQuery, ISearchCompleteStats, IRawFileMatch2 } from 'vs/platform/search/common/search';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
|
||||
type OneOrMore<T> = T | T[];
|
||||
|
||||
@@ -133,9 +134,11 @@ function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolder
|
||||
class TextSearchResultsCollector {
|
||||
private _batchedCollector: BatchedCollector<IRawFileMatch2>;
|
||||
|
||||
private _currentFolderIdx: number;
|
||||
private _currentRelativePath: string;
|
||||
private _currentFileMatch: IRawFileMatch2;
|
||||
|
||||
constructor(private _onResult: (result: IRawFileMatch2[]) => void) {
|
||||
constructor(private folderQueries: IFolderQuery[], private _onResult: (result: IRawFileMatch2[]) => void) {
|
||||
this._batchedCollector = new BatchedCollector<IRawFileMatch2>(512, items => this.sendItems(items));
|
||||
}
|
||||
|
||||
@@ -143,17 +146,15 @@ class TextSearchResultsCollector {
|
||||
// Collects TextSearchResults into IInternalFileMatches and collates using BatchedCollector.
|
||||
// This is efficient for ripgrep which sends results back one file at a time. It wouldn't be efficient for other search
|
||||
// providers that send results in random order. We could do this step afterwards instead.
|
||||
if (this._currentFileMatch && (this._currentFileMatch.resource.folderIdx !== folderIdx || this._currentFileMatch.resource.relativePath !== data.path)) {
|
||||
if (this._currentFileMatch && (this._currentFolderIdx !== folderIdx || this._currentRelativePath !== data.path)) {
|
||||
this.pushToCollector();
|
||||
this._currentFileMatch = null;
|
||||
}
|
||||
|
||||
if (!this._currentFileMatch) {
|
||||
const resource = joinPath(this.folderQueries[folderIdx].folder, data.path);
|
||||
this._currentFileMatch = {
|
||||
resource: {
|
||||
folderIdx,
|
||||
relativePath: data.path
|
||||
},
|
||||
resource,
|
||||
lineMatches: []
|
||||
};
|
||||
}
|
||||
@@ -271,7 +272,7 @@ class BatchedCollector<T> {
|
||||
}
|
||||
|
||||
interface IDirectoryEntry {
|
||||
base: string;
|
||||
base: URI;
|
||||
relativePath: string;
|
||||
basename: string;
|
||||
}
|
||||
@@ -282,8 +283,8 @@ interface IDirectoryTree {
|
||||
}
|
||||
|
||||
interface IInternalFileMatch {
|
||||
base?: string;
|
||||
relativePath: string; // Not necessarily relative... extraFiles put an absolute path here. Rename.
|
||||
base: URI;
|
||||
relativePath?: string; // Not present for extraFiles or absolute path matches
|
||||
basename: string;
|
||||
size?: number;
|
||||
}
|
||||
@@ -349,7 +350,7 @@ class QueryGlobTester {
|
||||
}
|
||||
|
||||
return this._parsedIncludeExpression ?
|
||||
TPromise.as(this._parsedIncludeExpression(testPath, basename, siblingsFn)).then(result => !result) :
|
||||
TPromise.as(this._parsedIncludeExpression(testPath, basename, siblingsFn)).then(result => !!result) :
|
||||
TPromise.wrap(true);
|
||||
}).then(included => {
|
||||
return included;
|
||||
@@ -393,20 +394,22 @@ class TextSearchEngine {
|
||||
const folderQueries = this.config.folderQueries;
|
||||
|
||||
return new PPromise<{ limitHit: boolean }, IRawFileMatch2[]>((resolve, reject, _onResult) => {
|
||||
this.collector = new TextSearchResultsCollector(_onResult);
|
||||
this.collector = new TextSearchResultsCollector(this.config.folderQueries, _onResult);
|
||||
|
||||
const onResult = (match: vscode.TextSearchResult, folderIdx: number) => {
|
||||
if (this.isCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.resultCount++;
|
||||
this.collector.add(match, folderIdx);
|
||||
|
||||
if (this.resultCount >= this.config.maxResults) {
|
||||
this.isLimitHit = true;
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
if (!this.isLimitHit) {
|
||||
this.resultCount++;
|
||||
this.collector.add(match, folderIdx);
|
||||
}
|
||||
};
|
||||
|
||||
// For each root folder
|
||||
@@ -433,9 +436,9 @@ class TextSearchEngine {
|
||||
const testingPs = [];
|
||||
const progress = {
|
||||
report: (result: vscode.TextSearchResult) => {
|
||||
const siblingFn = () => {
|
||||
const siblingFn = folderQuery.folder.scheme === 'file' && (() => {
|
||||
return this.readdir(path.dirname(path.join(folderQuery.folder.fsPath, result.path)));
|
||||
};
|
||||
});
|
||||
|
||||
testingPs.push(
|
||||
queryTester.includedInQuery(result.path, path.basename(result.path), siblingFn)
|
||||
@@ -491,7 +494,8 @@ class TextSearchEngine {
|
||||
includes,
|
||||
useIgnoreFiles: !this.config.disregardIgnoreFiles,
|
||||
followSymlinks: !this.config.ignoreSymlinks,
|
||||
encoding: this.config.fileEncoding
|
||||
encoding: this.config.fileEncoding,
|
||||
maxFileSize: this.config.maxFileSize
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -558,7 +562,7 @@ class FileSearchEngine {
|
||||
// Report result from file pattern if matching
|
||||
if (exists) {
|
||||
onResult({
|
||||
relativePath: this.filePattern,
|
||||
base: URI.file(this.filePattern),
|
||||
basename: path.basename(this.filePattern),
|
||||
size
|
||||
});
|
||||
@@ -572,15 +576,15 @@ class FileSearchEngine {
|
||||
// For each extra file
|
||||
if (this.config.extraFileResources) {
|
||||
this.config.extraFileResources
|
||||
.map(uri => uri.toString())
|
||||
.forEach(extraFilePath => {
|
||||
const basename = path.basename(extraFilePath);
|
||||
if (this.globalExcludePattern && this.globalExcludePattern(extraFilePath, basename)) {
|
||||
.forEach(extraFile => {
|
||||
const extraFileStr = extraFile.toString(); // ?
|
||||
const basename = path.basename(extraFileStr);
|
||||
if (this.globalExcludePattern && this.globalExcludePattern(extraFileStr, basename)) {
|
||||
return; // excluded
|
||||
}
|
||||
|
||||
// File: Check for match on file pattern and include pattern
|
||||
this.matchFile(onResult, { relativePath: extraFilePath /* no workspace relative path */, basename });
|
||||
this.matchFile(onResult, { base: extraFile, basename });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -588,7 +592,7 @@ class FileSearchEngine {
|
||||
PPromise.join(folderQueries.map(fq => {
|
||||
return this.searchInFolder(fq).then(null, null, onResult);
|
||||
})).then(() => {
|
||||
resolve({ isLimitHit: false });
|
||||
resolve({ isLimitHit: this.isLimitHit });
|
||||
}, (errs: Error[]) => {
|
||||
const errMsg = errs
|
||||
.map(err => toErrorMessage(err))
|
||||
@@ -604,7 +608,6 @@ class FileSearchEngine {
|
||||
let cancellation = new CancellationTokenSource();
|
||||
return new PPromise((resolve, reject, onResult) => {
|
||||
const options = this.getSearchOptionsForFolder(fq);
|
||||
const folderStr = fq.folder.fsPath;
|
||||
let filePatternSeen = false;
|
||||
const tree = this.initDirectoryTree();
|
||||
|
||||
@@ -616,20 +619,19 @@ class FileSearchEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is slow...
|
||||
if (noSiblingsClauses) {
|
||||
if (relativePath === this.filePattern) {
|
||||
filePatternSeen = true;
|
||||
}
|
||||
|
||||
const basename = path.basename(relativePath);
|
||||
this.matchFile(onResult, { base: folderStr, relativePath, basename });
|
||||
this.matchFile(onResult, { base: fq.folder, relativePath, basename });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Optimize siblings clauses with ripgrep here.
|
||||
this.addDirectoryEntries(tree, folderStr, relativePath, onResult);
|
||||
this.addDirectoryEntries(tree, fq.folder, relativePath, onResult);
|
||||
};
|
||||
|
||||
new TPromise(resolve => process.nextTick(resolve))
|
||||
@@ -646,10 +648,10 @@ class FileSearchEngine {
|
||||
if (noSiblingsClauses && this.isLimitHit) {
|
||||
if (!filePatternSeen) {
|
||||
// If the limit was hit, check whether filePattern is an exact relative match because it must be included
|
||||
return this.checkFilePatternRelativeMatch(folderStr).then(({ exists, size }) => {
|
||||
return this.checkFilePatternRelativeMatch(fq.folder).then(({ exists, size }) => {
|
||||
if (exists) {
|
||||
onResult({
|
||||
base: folderStr,
|
||||
base: fq.folder,
|
||||
relativePath: this.filePattern,
|
||||
basename: path.basename(this.filePattern),
|
||||
});
|
||||
@@ -658,7 +660,7 @@ class FileSearchEngine {
|
||||
}
|
||||
}
|
||||
|
||||
this.matchDirectoryTree(tree, folderStr, queryTester, onResult);
|
||||
this.matchDirectoryTree(tree, queryTester, onResult);
|
||||
return null;
|
||||
}).then(
|
||||
() => {
|
||||
@@ -694,7 +696,7 @@ class FileSearchEngine {
|
||||
return tree;
|
||||
}
|
||||
|
||||
private addDirectoryEntries({ pathToEntries }: IDirectoryTree, base: string, relativeFile: string, onResult: (result: IInternalFileMatch) => void) {
|
||||
private addDirectoryEntries({ pathToEntries }: IDirectoryTree, base: URI, relativeFile: string, onResult: (result: IInternalFileMatch) => void) {
|
||||
// Support relative paths to files from a root resource (ignores excludes)
|
||||
if (relativeFile === this.filePattern) {
|
||||
const basename = path.basename(this.filePattern);
|
||||
@@ -719,7 +721,7 @@ class FileSearchEngine {
|
||||
add(relativeFile);
|
||||
}
|
||||
|
||||
private matchDirectoryTree({ rootEntries, pathToEntries }: IDirectoryTree, rootFolder: string, queryTester: QueryGlobTester, onResult: (result: IInternalFileMatch) => void) {
|
||||
private matchDirectoryTree({ rootEntries, pathToEntries }: IDirectoryTree, queryTester: QueryGlobTester, onResult: (result: IInternalFileMatch) => void) {
|
||||
const self = this;
|
||||
const filePattern = this.filePattern;
|
||||
function matchDirectory(entries: IDirectoryEntry[]) {
|
||||
@@ -794,12 +796,12 @@ class FileSearchEngine {
|
||||
});
|
||||
}
|
||||
|
||||
private checkFilePatternRelativeMatch(basePath: string): TPromise<{ exists: boolean, size?: number }> {
|
||||
if (!this.filePattern || path.isAbsolute(this.filePattern)) {
|
||||
private checkFilePatternRelativeMatch(base: URI): TPromise<{ exists: boolean, size?: number }> {
|
||||
if (!this.filePattern || path.isAbsolute(this.filePattern) || base.scheme !== 'file') {
|
||||
return TPromise.wrap({ exists: false });
|
||||
}
|
||||
|
||||
const absolutePath = path.join(basePath, this.filePattern);
|
||||
const absolutePath = path.join(base.fsPath, this.filePattern);
|
||||
return this._pfs.stat(absolutePath).then(stat => {
|
||||
return {
|
||||
exists: !stat.isDirectory(),
|
||||
@@ -894,7 +896,7 @@ class FileSearchManager {
|
||||
|
||||
private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch {
|
||||
return {
|
||||
resource: URI.file(match.base ? path.join(match.base, match.relativePath) : match.relativePath)
|
||||
resource: joinPath(match.base, match.relativePath)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import * as tasks from 'vs/workbench/parts/tasks/common/tasks';
|
||||
|
||||
import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
@@ -21,8 +21,12 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import * as vscode from 'vscode';
|
||||
import {
|
||||
TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO, ProcessExecutionOptionsDTO, ProcessExecutionDTO,
|
||||
ShellExecutionOptionsDTO, ShellExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO
|
||||
ShellExecutionOptionsDTO, ShellExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO
|
||||
} from '../shared/tasks';
|
||||
import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
export { TaskExecutionDTO };
|
||||
|
||||
@@ -197,40 +201,40 @@ namespace ProblemMatcher {
|
||||
*/
|
||||
|
||||
namespace TaskRevealKind {
|
||||
export function from(value: vscode.TaskRevealKind): TaskSystem.RevealKind {
|
||||
export function from(value: vscode.TaskRevealKind): tasks.RevealKind {
|
||||
if (value === void 0 || value === null) {
|
||||
return TaskSystem.RevealKind.Always;
|
||||
return tasks.RevealKind.Always;
|
||||
}
|
||||
switch (value) {
|
||||
case types.TaskRevealKind.Silent:
|
||||
return TaskSystem.RevealKind.Silent;
|
||||
return tasks.RevealKind.Silent;
|
||||
case types.TaskRevealKind.Never:
|
||||
return TaskSystem.RevealKind.Never;
|
||||
return tasks.RevealKind.Never;
|
||||
}
|
||||
return TaskSystem.RevealKind.Always;
|
||||
return tasks.RevealKind.Always;
|
||||
}
|
||||
}
|
||||
|
||||
namespace TaskPanelKind {
|
||||
export function from(value: vscode.TaskPanelKind): TaskSystem.PanelKind {
|
||||
export function from(value: vscode.TaskPanelKind): tasks.PanelKind {
|
||||
if (value === void 0 || value === null) {
|
||||
return TaskSystem.PanelKind.Shared;
|
||||
return tasks.PanelKind.Shared;
|
||||
}
|
||||
switch (value) {
|
||||
case types.TaskPanelKind.Dedicated:
|
||||
return TaskSystem.PanelKind.Dedicated;
|
||||
return tasks.PanelKind.Dedicated;
|
||||
case types.TaskPanelKind.New:
|
||||
return TaskSystem.PanelKind.New;
|
||||
return tasks.PanelKind.New;
|
||||
default:
|
||||
return TaskSystem.PanelKind.Shared;
|
||||
return tasks.PanelKind.Shared;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PresentationOptions {
|
||||
export function from(value: vscode.TaskPresentationOptions): TaskSystem.PresentationOptions {
|
||||
export function from(value: vscode.TaskPresentationOptions): tasks.PresentationOptions {
|
||||
if (value === void 0 || value === null) {
|
||||
return { reveal: TaskSystem.RevealKind.Always, echo: true, focus: false, panel: TaskSystem.PanelKind.Shared };
|
||||
return { reveal: tasks.RevealKind.Always, echo: true, focus: false, panel: tasks.PanelKind.Shared };
|
||||
}
|
||||
return {
|
||||
reveal: TaskRevealKind.from(value.reveal),
|
||||
@@ -259,11 +263,11 @@ namespace CommandOptions {
|
||||
function isShellConfiguration(value: any): value is { executable: string; shellArgs?: string[] } {
|
||||
return value && typeof value.executable === 'string';
|
||||
}
|
||||
export function from(value: vscode.ShellExecutionOptions | vscode.ProcessExecutionOptions): TaskSystem.CommandOptions {
|
||||
export function from(value: vscode.ShellExecutionOptions | vscode.ProcessExecutionOptions): tasks.CommandOptions {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandOptions = {
|
||||
let result: tasks.CommandOptions = {
|
||||
};
|
||||
if (typeof value.cwd === 'string') {
|
||||
result.cwd = value.cwd;
|
||||
@@ -285,7 +289,7 @@ namespace CommandOptions {
|
||||
}
|
||||
|
||||
namespace ShellQuoteOptions {
|
||||
export function from(value: vscode.ShellQuotingOptions): TaskSystem.ShellQuotingOptions {
|
||||
export function from(value: vscode.ShellQuotingOptions): tasks.ShellQuotingOptions {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -298,12 +302,12 @@ namespace ShellQuoteOptions {
|
||||
}
|
||||
|
||||
namespace ShellConfiguration {
|
||||
export function from(value: { executable?: string, shellArgs?: string[], quotes?: vscode.ShellQuotingOptions }): TaskSystem.ShellConfiguration {
|
||||
export function from(value: { executable?: string, shellArgs?: string[], quotes?: vscode.ShellQuotingOptions }): tasks.ShellConfiguration {
|
||||
if (value === void 0 || value === null || !value.executable) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let result: TaskSystem.ShellConfiguration = {
|
||||
let result: tasks.ShellConfiguration = {
|
||||
executable: value.executable,
|
||||
args: Strings.from(value.shellArgs),
|
||||
quoting: ShellQuoteOptions.from(value.quotes)
|
||||
@@ -313,7 +317,7 @@ namespace ShellConfiguration {
|
||||
}
|
||||
|
||||
namespace ShellString {
|
||||
export function from(value: (string | vscode.ShellQuotedString)[]): TaskSystem.CommandString[] {
|
||||
export function from(value: (string | vscode.ShellQuotedString)[]): tasks.CommandString[] {
|
||||
if (value === void 0 || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -323,11 +327,11 @@ namespace ShellString {
|
||||
|
||||
namespace Tasks {
|
||||
|
||||
export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask[] {
|
||||
export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): tasks.ContributedTask[] {
|
||||
if (tasks === void 0 || tasks === null) {
|
||||
return [];
|
||||
}
|
||||
let result: TaskSystem.ContributedTask[] = [];
|
||||
let result: tasks.ContributedTask[] = [];
|
||||
for (let task of tasks) {
|
||||
let converted = fromSingle(task, rootFolder, extension);
|
||||
if (converted) {
|
||||
@@ -337,11 +341,11 @@ namespace Tasks {
|
||||
return result;
|
||||
}
|
||||
|
||||
function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask {
|
||||
function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): tasks.ContributedTask {
|
||||
if (typeof task.name !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let command: TaskSystem.CommandConfiguration;
|
||||
let command: tasks.CommandConfiguration;
|
||||
let execution = task.execution;
|
||||
if (execution instanceof types.ProcessExecution) {
|
||||
command = getProcessCommand(execution);
|
||||
@@ -357,21 +361,21 @@ namespace Tasks {
|
||||
|
||||
let taskScope: types.TaskScope.Global | types.TaskScope.Workspace | vscode.WorkspaceFolder | undefined = task.scope;
|
||||
let workspaceFolder: vscode.WorkspaceFolder | undefined;
|
||||
let scope: TaskSystem.TaskScope;
|
||||
let scope: tasks.TaskScope;
|
||||
// For backwards compatibility
|
||||
if (taskScope === void 0) {
|
||||
scope = TaskSystem.TaskScope.Folder;
|
||||
scope = tasks.TaskScope.Folder;
|
||||
workspaceFolder = rootFolder;
|
||||
} else if (taskScope === types.TaskScope.Global) {
|
||||
scope = TaskSystem.TaskScope.Global;
|
||||
scope = tasks.TaskScope.Global;
|
||||
} else if (taskScope === types.TaskScope.Workspace) {
|
||||
scope = TaskSystem.TaskScope.Workspace;
|
||||
scope = tasks.TaskScope.Workspace;
|
||||
} else {
|
||||
scope = TaskSystem.TaskScope.Folder;
|
||||
scope = tasks.TaskScope.Folder;
|
||||
workspaceFolder = taskScope;
|
||||
}
|
||||
let source: TaskSystem.ExtensionTaskSource = {
|
||||
kind: TaskSystem.TaskSourceKind.Extension,
|
||||
let source: tasks.ExtensionTaskSource = {
|
||||
kind: tasks.TaskSourceKind.Extension,
|
||||
label: typeof task.source === 'string' ? task.source : extension.name,
|
||||
extension: extension.id,
|
||||
scope: scope,
|
||||
@@ -380,17 +384,17 @@ namespace Tasks {
|
||||
// We can't transfer a workspace folder object from the extension host to main since they differ
|
||||
// in shape and we don't have backwards converting function. So transfer the URI and resolve the
|
||||
// workspace folder on the main side.
|
||||
(source as any as TaskSystem.ExtensionTaskSourceTransfer).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined;
|
||||
(source as any as tasks.ExtensionTaskSourceTransfer).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined;
|
||||
let label = nls.localize('task.label', '{0}: {1}', source.label, task.name);
|
||||
let key = (task as types.Task).definitionKey;
|
||||
let kind = (task as types.Task).definition;
|
||||
let id = `${extension.id}.${key}`;
|
||||
let taskKind: TaskSystem.TaskIdentifier = {
|
||||
let taskKind: tasks.TaskIdentifier = {
|
||||
_key: key,
|
||||
type: kind.type
|
||||
};
|
||||
Objects.assign(taskKind, kind);
|
||||
let result: TaskSystem.ContributedTask = {
|
||||
let result: tasks.ContributedTask = {
|
||||
_id: id, // uuidMap.getUUID(identifier),
|
||||
_source: source,
|
||||
_label: label,
|
||||
@@ -407,14 +411,14 @@ namespace Tasks {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getProcessCommand(value: vscode.ProcessExecution): TaskSystem.CommandConfiguration {
|
||||
function getProcessCommand(value: vscode.ProcessExecution): tasks.CommandConfiguration {
|
||||
if (typeof value.process !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandConfiguration = {
|
||||
let result: tasks.CommandConfiguration = {
|
||||
name: value.process,
|
||||
args: Strings.from(value.args),
|
||||
runtime: TaskSystem.RuntimeType.Process,
|
||||
runtime: tasks.RuntimeType.Process,
|
||||
suppressTaskName: true,
|
||||
presentation: undefined
|
||||
};
|
||||
@@ -424,15 +428,15 @@ namespace Tasks {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getShellCommand(value: vscode.ShellExecution): TaskSystem.CommandConfiguration {
|
||||
function getShellCommand(value: vscode.ShellExecution): tasks.CommandConfiguration {
|
||||
if (value.args) {
|
||||
if (typeof value.command !== 'string' && typeof value.command.value !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandConfiguration = {
|
||||
let result: tasks.CommandConfiguration = {
|
||||
name: value.command,
|
||||
args: ShellString.from(value.args),
|
||||
runtime: TaskSystem.RuntimeType.Shell,
|
||||
runtime: tasks.RuntimeType.Shell,
|
||||
presentation: undefined
|
||||
};
|
||||
if (value.options) {
|
||||
@@ -443,9 +447,9 @@ namespace Tasks {
|
||||
if (typeof value.commandLine !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
let result: TaskSystem.CommandConfiguration = {
|
||||
let result: tasks.CommandConfiguration = {
|
||||
name: value.commandLine,
|
||||
runtime: TaskSystem.RuntimeType.Shell,
|
||||
runtime: tasks.RuntimeType.Shell,
|
||||
presentation: undefined
|
||||
};
|
||||
if (value.options) {
|
||||
@@ -728,7 +732,9 @@ interface HandlerData {
|
||||
export class ExtHostTask implements ExtHostTaskShape {
|
||||
|
||||
private _proxy: MainThreadTaskShape;
|
||||
private _extHostWorkspace: ExtHostWorkspace;
|
||||
private _workspaceService: ExtHostWorkspace;
|
||||
private _editorService: ExtHostDocumentsAndEditors;
|
||||
private _configurationService: ExtHostConfiguration;
|
||||
private _handleCounter: number;
|
||||
private _handlers: Map<number, HandlerData>;
|
||||
private _taskExecutions: Map<string, TaskExecutionImpl>;
|
||||
@@ -739,16 +745,18 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
private readonly _onDidTaskProcessStarted: Emitter<vscode.TaskProcessStartEvent> = new Emitter<vscode.TaskProcessStartEvent>();
|
||||
private readonly _onDidTaskProcessEnded: Emitter<vscode.TaskProcessEndEvent> = new Emitter<vscode.TaskProcessEndEvent>();
|
||||
|
||||
constructor(mainContext: IMainContext, extHostWorkspace: ExtHostWorkspace) {
|
||||
constructor(mainContext: IMainContext, workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfiguration) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadTask);
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._workspaceService = workspaceService;
|
||||
this._editorService = editorService;
|
||||
this._configurationService = configurationService;
|
||||
this._handleCounter = 0;
|
||||
this._handlers = new Map<number, HandlerData>();
|
||||
this._taskExecutions = new Map<string, TaskExecutionImpl>();
|
||||
}
|
||||
|
||||
public get extHostWorkspace(): ExtHostWorkspace {
|
||||
return this._extHostWorkspace;
|
||||
return this._workspaceService;
|
||||
}
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
@@ -764,11 +772,15 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void {
|
||||
this._proxy.$registerTaskSystem(scheme, info);
|
||||
}
|
||||
|
||||
public fetchTasks(filter?: vscode.TaskFilter): Thenable<vscode.Task[]> {
|
||||
return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then((values) => {
|
||||
let result: vscode.Task[] = [];
|
||||
for (let value of values) {
|
||||
let task = TaskDTO.to(value, this._extHostWorkspace);
|
||||
let task = TaskDTO.to(value, this._workspaceService);
|
||||
if (task) {
|
||||
result.push(task);
|
||||
}
|
||||
@@ -854,13 +866,13 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
}
|
||||
}
|
||||
|
||||
public $provideTasks(handle: number): TPromise<TaskSystem.TaskSet> {
|
||||
public $provideTasks(handle: number): TPromise<tasks.TaskSet> {
|
||||
let handler = this._handlers.get(handle);
|
||||
if (!handler) {
|
||||
return TPromise.wrapError<TaskSystem.TaskSet>(new Error('no handler found'));
|
||||
return TPromise.wrapError<tasks.TaskSet>(new Error('no handler found'));
|
||||
}
|
||||
return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => {
|
||||
let workspaceFolders = this._extHostWorkspace.getWorkspaceFolders();
|
||||
let workspaceFolders = this._workspaceService.getWorkspaceFolders();
|
||||
return {
|
||||
tasks: Tasks.from(value, workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0] : undefined, handler.extension),
|
||||
extension: handler.extension
|
||||
@@ -868,6 +880,24 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public $resolveVariables(uri: URI, variables: string[]): any {
|
||||
let result = Object.create(null);
|
||||
let workspaceFolder = this._workspaceService.resolveWorkspaceFolder(uri);
|
||||
let resolver = new ExtHostVariableResolverService(this._workspaceService, this._editorService, this._configurationService);
|
||||
let ws: IWorkspaceFolder = {
|
||||
uri: workspaceFolder.uri,
|
||||
name: workspaceFolder.name,
|
||||
index: workspaceFolder.index,
|
||||
toResource: () => {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
};
|
||||
for (let variable of variables) {
|
||||
result.push(variable, resolver.resolve(ws, variable));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private nextHandle(): number {
|
||||
return this._handleCounter++;
|
||||
}
|
||||
@@ -881,7 +911,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._extHostWorkspace));
|
||||
result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._workspaceService));
|
||||
this._taskExecutions.set(execution.id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { TextEditorSelectionChangeKind } from './extHostTypes';
|
||||
import * as TypeConverters from './extHostTypeConverters';
|
||||
import { TextEditorDecorationType, ExtHostTextEditor } from './extHostTextEditor';
|
||||
import { ExtHostDocumentsAndEditors } from './extHostDocumentsAndEditors';
|
||||
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
|
||||
import { MainContext, MainThreadTextEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData, IMainContext, WorkspaceEditDto, IEditorPropertiesChangeData } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
@@ -73,7 +72,6 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
};
|
||||
} else {
|
||||
options = {
|
||||
position: EditorPosition.ONE,
|
||||
preserveFocus: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -116,11 +116,11 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
private _selectedElements: T[] = [];
|
||||
get selectedElements(): T[] { return this._selectedElements; }
|
||||
|
||||
private _onDidExpandElement: Emitter<T> = this._register(new Emitter<T>());
|
||||
readonly onDidExpandElement: Event<T> = this._onDidExpandElement.event;
|
||||
private _onDidExpandElement: Emitter<vscode.TreeViewExpansionEvent<T>> = this._register(new Emitter<vscode.TreeViewExpansionEvent<T>>());
|
||||
readonly onDidExpandElement: Event<vscode.TreeViewExpansionEvent<T>> = this._onDidExpandElement.event;
|
||||
|
||||
private _onDidCollapseElement: Emitter<T> = this._register(new Emitter<T>());
|
||||
readonly onDidCollapseElement: Event<T> = this._onDidCollapseElement.event;
|
||||
private _onDidCollapseElement: Emitter<vscode.TreeViewExpansionEvent<T>> = this._register(new Emitter<vscode.TreeViewExpansionEvent<T>>());
|
||||
readonly onDidCollapseElement: Event<vscode.TreeViewExpansionEvent<T>> = this._onDidCollapseElement.event;
|
||||
|
||||
private refreshPromise: TPromise<void> = TPromise.as(null);
|
||||
|
||||
@@ -174,9 +174,9 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
const element = this.getExtensionElement(treeItemHandle);
|
||||
if (element) {
|
||||
if (expanded) {
|
||||
this._onDidExpandElement.fire(element);
|
||||
this._onDidExpandElement.fire({ element });
|
||||
} else {
|
||||
this._onDidCollapseElement.fire(element);
|
||||
this._onDidCollapseElement.fire({ element });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,7 +362,7 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
return item;
|
||||
}
|
||||
|
||||
private createHandle(element: T, { id, label, resourceUri }: vscode.TreeItem, parent: TreeNode, first?: boolean): TreeItemHandle {
|
||||
private createHandle(element: T, { id, label, resourceUri }: vscode.TreeItem, parent: TreeNode, returnFirst?: boolean): TreeItemHandle {
|
||||
if (id) {
|
||||
return `${ExtHostTreeView.ID_HANDLE_PREFIX}/${id}`;
|
||||
}
|
||||
@@ -373,14 +373,20 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
const existingHandle = this.nodes.has(element) ? this.nodes.get(element).item.handle : void 0;
|
||||
const childrenNodes = (this.getChildrenNodes(parent) || []);
|
||||
|
||||
for (let counter = 0; counter <= childrenNodes.length; counter++) {
|
||||
const handle = `${prefix}/${counter}:${elementId}`;
|
||||
if (first || !this.elements.has(handle) || existingHandle === handle) {
|
||||
return handle;
|
||||
let handle: TreeItemHandle;
|
||||
let counter = 0;
|
||||
do {
|
||||
handle = `${prefix}/${counter}:${elementId}`;
|
||||
if (returnFirst || !this.elements.has(handle) || existingHandle === handle) {
|
||||
// Return first if asked for or
|
||||
// Return if handle does not exist or
|
||||
// Return if handle is being reused
|
||||
break;
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
} while (counter <= childrenNodes.length);
|
||||
|
||||
throw new Error('This should not be reached');
|
||||
return handle;
|
||||
}
|
||||
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
@@ -457,7 +463,7 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
node.children = [];
|
||||
node.children = void 0;
|
||||
} else {
|
||||
this.clearAll();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as types from './extHostTypes';
|
||||
import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { IDecorationOptions } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import * as vscode from 'vscode';
|
||||
@@ -156,29 +157,28 @@ export namespace DiagnosticSeverity {
|
||||
}
|
||||
|
||||
export namespace ViewColumn {
|
||||
export function from(column?: vscode.ViewColumn): EditorPosition {
|
||||
let editorColumn = EditorPosition.ONE;
|
||||
if (typeof column !== 'number') {
|
||||
// stick with ONE
|
||||
export function from(column?: vscode.ViewColumn): EditorViewColumn {
|
||||
let editorColumn: EditorViewColumn;
|
||||
if (column === <number>types.ViewColumn.One) {
|
||||
editorColumn = 0;
|
||||
} else if (column === <number>types.ViewColumn.Two) {
|
||||
editorColumn = EditorPosition.TWO;
|
||||
editorColumn = 1;
|
||||
} else if (column === <number>types.ViewColumn.Three) {
|
||||
editorColumn = EditorPosition.THREE;
|
||||
} else if (column === <number>types.ViewColumn.Active) {
|
||||
editorColumn = 2;
|
||||
} else {
|
||||
// in any other case (no column or ViewColumn.Active), leave the
|
||||
// editorColumn as undefined which signals to use the active column
|
||||
editorColumn = undefined;
|
||||
}
|
||||
return editorColumn;
|
||||
}
|
||||
|
||||
export function to(position?: EditorPosition): vscode.ViewColumn {
|
||||
if (typeof position !== 'number') {
|
||||
return undefined;
|
||||
}
|
||||
if (position === EditorPosition.ONE) {
|
||||
export function to(position?: EditorViewColumn): vscode.ViewColumn {
|
||||
if (position === 0) {
|
||||
return <number>types.ViewColumn.One;
|
||||
} else if (position === EditorPosition.TWO) {
|
||||
} else if (position === 1) {
|
||||
return <number>types.ViewColumn.Two;
|
||||
} else if (position === EditorPosition.THREE) {
|
||||
} else if (position === 2) {
|
||||
return <number>types.ViewColumn.Three;
|
||||
}
|
||||
return undefined;
|
||||
@@ -381,7 +381,8 @@ export namespace HierarchicalSymbolInformation {
|
||||
detail: info.parent.detail,
|
||||
location: location.from(info.parent.location),
|
||||
definingRange: Range.from(info.parent.range),
|
||||
kind: SymbolKind.from(info.parent.kind)
|
||||
kind: SymbolKind.from(info.parent.kind),
|
||||
containerName: info.parent.containerName
|
||||
};
|
||||
if (info.children) {
|
||||
result.children = info.children.map(from);
|
||||
|
||||
@@ -903,6 +903,11 @@ export class Hierarchy<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export enum CodeActionTrigger {
|
||||
Automatic = 1,
|
||||
Manual = 2,
|
||||
}
|
||||
|
||||
export class CodeAction {
|
||||
title: string;
|
||||
|
||||
@@ -1840,12 +1845,6 @@ export enum LogLevel {
|
||||
}
|
||||
|
||||
//#region file api
|
||||
// todo@remote
|
||||
export enum DeprecatedFileChangeType {
|
||||
Updated = 0,
|
||||
Added = 1,
|
||||
Deleted = 2
|
||||
}
|
||||
|
||||
export enum FileChangeType {
|
||||
Changed = 1,
|
||||
@@ -1853,12 +1852,6 @@ export enum FileChangeType {
|
||||
Deleted = 3,
|
||||
}
|
||||
|
||||
export enum DeprecatedFileType {
|
||||
File = 0,
|
||||
Dir = 1,
|
||||
Symlink = 2
|
||||
}
|
||||
|
||||
export class FileSystemError extends Error {
|
||||
|
||||
static FileExists(messageOrUri?: string | URI): FileSystemError {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { MainContext, MainThreadWebviewsShape, IMainContext, ExtHostWebviewsShap
|
||||
import * as vscode from 'vscode';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { Position } from 'vs/platform/editor/common/editor';
|
||||
import { EditorViewColumn } from 'vs/workbench/api/shared/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from './extHostTypes';
|
||||
import URI from 'vs/base/common/uri';
|
||||
@@ -248,7 +248,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
}
|
||||
}
|
||||
|
||||
$onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, visible: boolean, position: Position): void {
|
||||
$onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, visible: boolean, position: EditorViewColumn): void {
|
||||
const panel = this.getWebviewPanel(handle);
|
||||
if (panel) {
|
||||
const viewColumn = typeConverters.ViewColumn.to(position);
|
||||
@@ -274,7 +274,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
viewType: string,
|
||||
title: string,
|
||||
state: any,
|
||||
position: Position,
|
||||
position: EditorViewColumn,
|
||||
options: vscode.WebviewOptions & vscode.WebviewPanelOptions
|
||||
): Thenable<void> {
|
||||
const serializer = this._serializers.get(viewType);
|
||||
|
||||
42
src/vs/workbench/api/shared/editor.ts
Normal file
42
src/vs/workbench/api/shared/editor.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
// TODO@api this was previously a hardcoded list of editor positions (ONE, TWO, THREE)
|
||||
// that with the introduction of grid editor feature is now unbounded. This should be
|
||||
// revisited when the grid functionality is exposed to extensions,
|
||||
|
||||
export type EditorViewColumn = number;
|
||||
|
||||
export function viewColumnToEditorGroup(editorGroupService: IEditorGroupsService, position?: EditorViewColumn): GroupIdentifier {
|
||||
if (typeof position !== 'number') {
|
||||
return ACTIVE_GROUP; // prefer active group when position is undefined
|
||||
}
|
||||
|
||||
const groups = editorGroupService.getGroups(GroupsOrder.CREATION_TIME);
|
||||
|
||||
let candidate = groups[position];
|
||||
if (candidate) {
|
||||
return candidate.id; // found direct match
|
||||
}
|
||||
|
||||
let firstGroup = groups[0];
|
||||
if (groups.length === 1 && firstGroup.count === 0) {
|
||||
return firstGroup.id; // first editor should always open in first group
|
||||
}
|
||||
|
||||
return SIDE_GROUP; // open to the side if group not found
|
||||
}
|
||||
|
||||
export function editorGroupToViewColumn(editorGroupService: IEditorGroupsService, editorGroup: IEditorGroup | GroupIdentifier): EditorViewColumn {
|
||||
const group = typeof editorGroup === 'number' ? editorGroupService.getGroup(editorGroup) : editorGroup;
|
||||
|
||||
return editorGroupService.getGroups(GroupsOrder.CREATION_TIME).indexOf(group);
|
||||
}
|
||||
@@ -102,4 +102,8 @@ export interface TaskProcessEndedDTO {
|
||||
export interface TaskFilterDTO {
|
||||
version?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface TaskSystemInfoDTO {
|
||||
platform: string;
|
||||
}
|
||||
Reference in New Issue
Block a user