mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 03:54:24 +01:00
Merge remote-tracking branch 'origin/master' into 46192_terminal_renderer
This commit is contained in:
@@ -17,12 +17,11 @@ 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 { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IExtensionService, IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ViewLocation } from 'vs/workbench/common/views';
|
||||
import { PersistentViewsViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { Extensions as ViewContainerExtensions, IViewContainersRegistry, TEST_VIEW_CONTAINER_ID } from 'vs/workbench/common/views';
|
||||
import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
@@ -84,7 +83,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
const cssClass = `extensionViewlet-test`;
|
||||
const icon = require.toUrl('./media/test.svg');
|
||||
|
||||
this.registerCustomViewlet({ id: ViewLocation.TEST.id, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass);
|
||||
this.registerCustomViewlet({ id: TEST_VIEW_CONTAINER_ID, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass);
|
||||
}
|
||||
|
||||
private handleAndRegisterCustomViewContainers() {
|
||||
@@ -143,15 +142,16 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
|
||||
private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor, order: number, cssClass: string): void {
|
||||
const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
const viewletRegistry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets);
|
||||
const id = descriptor.id;
|
||||
|
||||
if (!viewletRegistry.getViewlet(id)) {
|
||||
|
||||
const location: ViewLocation = ViewLocation.register(id);
|
||||
viewContainersRegistry.registerViewContainer(id);
|
||||
|
||||
// Register as viewlet
|
||||
class CustomViewlet extends PersistentViewsViewlet {
|
||||
class CustomViewlet extends ViewContainerViewlet {
|
||||
constructor(
|
||||
@IPartService partService: IPartService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@@ -159,12 +159,11 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IExtensionService extensionService: IExtensionService
|
||||
) {
|
||||
super(id, location, `${id}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService);
|
||||
super(id, `${id}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
}
|
||||
}
|
||||
const viewletDescriptor = new ViewletDescriptor(
|
||||
|
||||
@@ -7,22 +7,144 @@
|
||||
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 { ViewLocation, ViewsRegistry, ICustomViewDescriptor } from 'vs/workbench/common/views';
|
||||
import { CustomTreeViewPanel } from 'vs/workbench/browser/parts/views/customViewPanel';
|
||||
import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { ViewContainer, ViewsRegistry, ICustomViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views';
|
||||
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 { VIEWLET_ID as EXPLORER } from 'vs/workbench/parts/files/common/files';
|
||||
import { VIEWLET_ID as SCM } from 'vs/workbench/parts/scm/common/scm';
|
||||
import { VIEWLET_ID as DEBUG } from 'vs/workbench/parts/debug/common/debug';
|
||||
|
||||
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 {
|
||||
|
||||
private viewContainersRegistry: IViewContainersRegistry;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
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 container = this.getViewContainer(entry.key);
|
||||
if (!container) {
|
||||
collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key));
|
||||
container = this.viewContainersRegistry.get(EXPLORER);
|
||||
}
|
||||
const registeredViews = ViewsRegistry.getViews(container);
|
||||
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 view container `{1}`", item.id, container.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 view container `{1}`", item.id, container.id));
|
||||
return null;
|
||||
}
|
||||
|
||||
const viewDescriptor = <ICustomViewDescriptor>{
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
ctor: CustomTreeViewPanel,
|
||||
container,
|
||||
when: ContextKeyExpr.deserialize(item.when),
|
||||
canToggleVisibility: true,
|
||||
collapsed: this.showCollapsed(container),
|
||||
treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, container)
|
||||
};
|
||||
|
||||
viewIds.push(viewDescriptor.id);
|
||||
return viewDescriptor;
|
||||
}));
|
||||
ViewsRegistry.registerViews(viewDescriptors);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private isValidViewDescriptors(viewDescriptors: IUserFriendlyViewDescriptor[], collector: ExtensionMessageCollector): boolean {
|
||||
if (!Array.isArray(viewDescriptors)) {
|
||||
collector.error(localize('requirearray', "views must be an array"));
|
||||
return false;
|
||||
@@ -46,124 +168,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 getViewContainer(value: string): ViewContainer {
|
||||
switch (value) {
|
||||
case 'explorer': return this.viewContainersRegistry.get(EXPLORER);
|
||||
case 'debug': return this.viewContainersRegistry.get(DEBUG);
|
||||
case 'scm': return this.viewContainersRegistry.get(SCM);
|
||||
default: return this.viewContainersRegistry.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(container: ViewContainer): boolean {
|
||||
switch (container.id) {
|
||||
case EXPLORER:
|
||||
case SCM:
|
||||
case DEBUG:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function 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: showCollapsed(location),
|
||||
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);
|
||||
@@ -50,6 +50,7 @@ import './mainThreadTerminalService';
|
||||
import './mainThreadTreeViews';
|
||||
import './mainThreadLogService';
|
||||
import './mainThreadWebview';
|
||||
import './mainThreadComments';
|
||||
import './mainThreadUrls';
|
||||
import './mainThreadWindow';
|
||||
import './mainThreadWorkspace';
|
||||
|
||||
137
src/vs/workbench/api/electron-browser/mainThreadComments.ts
Normal file
137
src/vs/workbench/api/electron-browser/mainThreadComments.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { keys } from '../../../base/common/map';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape } from '../node/extHost.protocol';
|
||||
|
||||
import { ICommentService } from 'vs/workbench/parts/comments/electron-browser/commentService';
|
||||
import { COMMENTS_PANEL_ID } from 'vs/workbench/parts/comments/electron-browser/commentsPanel';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { ReviewController } from 'vs/workbench/parts/comments/electron-browser/commentsEditorContribution';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadComments)
|
||||
export class MainThreadComments extends Disposable implements MainThreadCommentsShape {
|
||||
private _disposables: IDisposable[];
|
||||
private _proxy: ExtHostCommentsShape;
|
||||
private _documentProviders = new Map<number, IDisposable>();
|
||||
private _workspaceProviders = new Map<number, IDisposable>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@ICommentService private _commentService: ICommentService,
|
||||
@IPanelService private _panelService: IPanelService,
|
||||
@ICodeEditorService private _codeEditorService: ICodeEditorService
|
||||
) {
|
||||
super();
|
||||
this._disposables = [];
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostComments);
|
||||
this._disposables.push(this._editorService.onDidActiveEditorChange(e => {
|
||||
const outerEditor = this.getFocusedEditor();
|
||||
if (!outerEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const controller = ReviewController.get(outerEditor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!outerEditor.getModel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const outerEditorURI = outerEditor.getModel().uri;
|
||||
this.provideDocumentComments(outerEditorURI).then(commentInfos => {
|
||||
this._commentService.setDocumentComments(outerEditorURI, commentInfos.filter(info => info !== null));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
$registerDocumentCommentProvider(handle: number): void {
|
||||
this._documentProviders.set(handle, undefined);
|
||||
|
||||
this._commentService.registerDataProvider(
|
||||
handle,
|
||||
{
|
||||
provideDocumentComments: async (uri, token) => {
|
||||
return this._proxy.$provideDocumentComments(handle, uri);
|
||||
},
|
||||
onDidChangeCommentThreads: null,
|
||||
createNewCommentThread: async (uri, range, text, token) => {
|
||||
return this._proxy.$createNewCommentThread(handle, uri, range, text);
|
||||
},
|
||||
replyToCommentThread: async (uri, range, thread, text, token) => {
|
||||
return this._proxy.$replyToCommentThread(handle, uri, range, thread, text);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$registerWorkspaceCommentProvider(handle: number): void {
|
||||
this._workspaceProviders.set(handle, undefined);
|
||||
this._panelService.setPanelEnablement(COMMENTS_PANEL_ID, true);
|
||||
this._panelService.openPanel(COMMENTS_PANEL_ID);
|
||||
this._proxy.$provideWorkspaceComments(handle).then(commentThreads => {
|
||||
if (commentThreads) {
|
||||
this._commentService.setWorkspaceComments(handle, commentThreads);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$unregisterDocumentCommentProvider(handle: number): void {
|
||||
this._documentProviders.delete(handle);
|
||||
this._commentService.unregisterDataProvider(handle);
|
||||
}
|
||||
|
||||
$unregisterWorkspaceCommentProvider(handle: number): void {
|
||||
this._workspaceProviders.delete(handle);
|
||||
if (this._workspaceProviders.size === 0) {
|
||||
this._panelService.setPanelEnablement(COMMENTS_PANEL_ID, false);
|
||||
}
|
||||
this._commentService.removeWorkspaceComments(handle);
|
||||
}
|
||||
|
||||
$onDidCommentThreadsChange(handle: number, event: modes.CommentThreadChangedEvent) {
|
||||
// notify comment service
|
||||
this._commentService.updateComments(event);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables = dispose(this._disposables);
|
||||
this._workspaceProviders.forEach(value => dispose(value));
|
||||
this._workspaceProviders.clear();
|
||||
this._documentProviders.forEach(value => dispose(value));
|
||||
this._documentProviders.clear();
|
||||
}
|
||||
|
||||
getFocusedEditor(): ICodeEditor {
|
||||
return this._codeEditorService.getFocusedCodeEditor() || getCodeEditor(this._editorService.activeControl);
|
||||
}
|
||||
|
||||
async provideWorkspaceComments(): Promise<modes.CommentThread[]> {
|
||||
const result: modes.CommentThread[] = [];
|
||||
for (const handle of keys(this._workspaceProviders)) {
|
||||
result.push(...await this._proxy.$provideWorkspaceComments(handle));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async provideDocumentComments(resource: URI): Promise<modes.CommentInfo[]> {
|
||||
const result: modes.CommentInfo[] = [];
|
||||
for (const handle of keys(this._documentProviders)) {
|
||||
result.push(await this._proxy.$provideDocumentComments(handle, resource));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -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, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable, ITerminalSettings, IDebugAdapter, IDebugAdapterProvider } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import {
|
||||
ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext,
|
||||
@@ -18,8 +18,6 @@ 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)
|
||||
@@ -30,13 +28,11 @@ 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,
|
||||
@ITerminalService private terminalService: ITerminalService,
|
||||
@IDebugService private debugService: IDebugService
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDebugService);
|
||||
this._toDispose = [];
|
||||
@@ -77,10 +73,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
}
|
||||
|
||||
runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
|
||||
if (!this._terminalLauncher) {
|
||||
this._terminalLauncher = new ExtensionTerminalLauncher(this.terminalService, this._proxy);
|
||||
}
|
||||
return this._terminalLauncher.runInTerminal(args, config);
|
||||
return this._proxy.$runInTerminal(args, config);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -94,7 +87,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
|
||||
// set up a handler to send more
|
||||
this._toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(e => {
|
||||
if (e) {
|
||||
// Ignore session only breakpoint events since they should only reflect in the UI
|
||||
if (e && !e.sessionOnly) {
|
||||
const delta: IBreakpointsDeltaDto = {};
|
||||
if (e.added) {
|
||||
delta.added = this.convertToDto(e.added);
|
||||
@@ -302,25 +296,3 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG
|
||||
import { ExtHostContext, ExtHostEditorsShape, IExtHostContext, ITextDocumentShowOptions, ITextEditorPositionData, MainThreadTextEditorsShape } from '../node/extHost.protocol';
|
||||
import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors';
|
||||
import { MainThreadTextEditor } from './mainThreadEditor';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
|
||||
export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
|
||||
@@ -250,12 +251,25 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
CommandsRegistry.registerCommand('_workbench.open', function (accessor: ServicesAccessor, args: [URI, IEditorOptions, EditorViewColumn]) {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
const openerService = accessor.get(IOpenerService);
|
||||
|
||||
const [resource, options, position] = args;
|
||||
|
||||
return editorService.openEditor({ resource, options }, viewColumnToEditorGroup(editorGroupService, position)).then(() => void 0);
|
||||
if (options || typeof position === 'number') {
|
||||
// use editor options or editor view column as a hint to use the editor service for opening
|
||||
return editorService.openEditor({ resource, options }, viewColumnToEditorGroup(editorGroupService, position)).then(_ => void 0);
|
||||
}
|
||||
|
||||
if (resource && resource.scheme === 'command') {
|
||||
// do not allow to execute commands from here
|
||||
return TPromise.as(void 0);
|
||||
}
|
||||
|
||||
// finally, delegate to opener service
|
||||
return openerService.open(resource).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);
|
||||
@@ -273,4 +287,4 @@ CommandsRegistry.registerCommand('_workbench.diff', function (accessor: Services
|
||||
}
|
||||
|
||||
return editorService.openEditor({ leftResource, rightResource, label, description, options }, viewColumnToEditorGroup(editorGroupService, position)).then(() => void 0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,12 +9,12 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { ITextModel, ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { WorkspaceSymbolProviderRegistry, IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
|
||||
import * as search from 'vs/workbench/parts/search/common/search';
|
||||
import { wireCancellationToken } from 'vs/base/common/async';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, SymbolInformationDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter } from '../node/extHost.protocol';
|
||||
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter } from '../node/extHost.protocol';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { LanguageConfiguration, IndentationRule, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration';
|
||||
import { IHeapService } from './mainThreadHeapService';
|
||||
@@ -72,20 +72,17 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
}
|
||||
}
|
||||
|
||||
private static _reviveSymbolInformationDto(data: SymbolInformationDto): modes.SymbolInformation;
|
||||
private static _reviveSymbolInformationDto(data: SymbolInformationDto[]): modes.SymbolInformation[];
|
||||
private static _reviveSymbolInformationDto(data: SymbolInformationDto | SymbolInformationDto[]): modes.SymbolInformation | modes.SymbolInformation[] {
|
||||
private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto): search.IWorkspaceSymbol;
|
||||
private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto[]): search.IWorkspaceSymbol[];
|
||||
private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto | WorkspaceSymbolDto[]): search.IWorkspaceSymbol | search.IWorkspaceSymbol[] {
|
||||
if (!data) {
|
||||
return <modes.SymbolInformation>data;
|
||||
return <search.IWorkspaceSymbol>data;
|
||||
} else if (Array.isArray(data)) {
|
||||
data.forEach(MainThreadLanguageFeatures._reviveSymbolInformationDto);
|
||||
return <modes.SymbolInformation[]>data;
|
||||
data.forEach(MainThreadLanguageFeatures._reviveWorkspaceSymbolDto);
|
||||
return <search.IWorkspaceSymbol[]>data;
|
||||
} else {
|
||||
data.location = MainThreadLanguageFeatures._reviveLocationDto(data.location);
|
||||
if (data.children) {
|
||||
data.children.forEach(MainThreadLanguageFeatures._reviveSymbolInformationDto);
|
||||
}
|
||||
return <modes.SymbolInformation>data;
|
||||
return <search.IWorkspaceSymbol>data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,8 +100,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
$registerOutlineSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: string): void {
|
||||
this._registrations[handle] = modes.DocumentSymbolProviderRegistry.register(typeConverters.LanguageSelector.from(selector), <modes.DocumentSymbolProvider>{
|
||||
extensionId,
|
||||
provideDocumentSymbols: (model: ITextModel, token: CancellationToken): Thenable<modes.SymbolInformation[]> => {
|
||||
return wireCancellationToken(token, this._proxy.$provideDocumentSymbols(handle, model.uri)).then(MainThreadLanguageFeatures._reviveSymbolInformationDto);
|
||||
provideDocumentSymbols: (model: ITextModel, token: CancellationToken): Thenable<modes.DocumentSymbol[]> => {
|
||||
return wireCancellationToken(token, this._proxy.$provideDocumentSymbols(handle, model.uri));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -238,18 +235,18 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
|
||||
$registerNavigateTypeSupport(handle: number): void {
|
||||
let lastResultId: number;
|
||||
this._registrations[handle] = WorkspaceSymbolProviderRegistry.register(<IWorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols: (search: string): TPromise<modes.SymbolInformation[]> => {
|
||||
this._registrations[handle] = search.WorkspaceSymbolProviderRegistry.register(<search.IWorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols: (search: string): TPromise<search.IWorkspaceSymbol[]> => {
|
||||
return this._proxy.$provideWorkspaceSymbols(handle, search).then(result => {
|
||||
if (lastResultId !== undefined) {
|
||||
this._proxy.$releaseWorkspaceSymbols(handle, lastResultId);
|
||||
}
|
||||
lastResultId = result._id;
|
||||
return MainThreadLanguageFeatures._reviveSymbolInformationDto(result.symbols);
|
||||
return MainThreadLanguageFeatures._reviveWorkspaceSymbolDto(result.symbols);
|
||||
});
|
||||
},
|
||||
resolveWorkspaceSymbol: (item: modes.SymbolInformation): TPromise<modes.SymbolInformation> => {
|
||||
return this._proxy.$resolveWorkspaceSymbol(handle, item).then(i => MainThreadLanguageFeatures._reviveSymbolInformationDto(i));
|
||||
resolveWorkspaceSymbol: (item: search.IWorkspaceSymbol): TPromise<search.IWorkspaceSymbol> => {
|
||||
return this._proxy.$resolveWorkspaceSymbol(handle, item).then(i => MainThreadLanguageFeatures._reviveWorkspaceSymbolDto(i));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IProgressService2, IProgress, IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress';
|
||||
import { IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { MainThreadProgressShape, MainContext, IExtHostContext, ExtHostProgressShape, ExtHostContext } from '../node/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { IProgressService2, IProgressStep, IProgressOptions } from 'vs/workbench/services/progress/common/progress';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadProgress)
|
||||
export class MainThreadProgress implements MainThreadProgressShape {
|
||||
|
||||
@@ -7,26 +7,20 @@
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { IPickOptions, IInputOptions, IQuickInputService, IQuickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { InputBoxOptions, CancellationToken } from 'vscode';
|
||||
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems, MainContext, IExtHostContext } from '../node/extHost.protocol';
|
||||
import { InputBoxOptions } from 'vscode';
|
||||
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, TransferQuickPickItems, MainContext, IExtHostContext, TransferQuickInput, TransferQuickInputButton } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
|
||||
interface MultiStepSession {
|
||||
handle: number;
|
||||
input: IQuickInput;
|
||||
token: CancellationToken;
|
||||
}
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadQuickOpen)
|
||||
export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
|
||||
private _proxy: ExtHostQuickOpenShape;
|
||||
private _quickInputService: IQuickInputService;
|
||||
private _doSetItems: (items: MyQuickPickItems[]) => any;
|
||||
private _doSetItems: (items: TransferQuickPickItems[]) => any;
|
||||
private _doSetError: (error: Error) => any;
|
||||
private _contents: TPromise<MyQuickPickItems[]>;
|
||||
private _contents: TPromise<TransferQuickPickItems[]>;
|
||||
private _token: number = 0;
|
||||
private _multiStep: MultiStepSession;
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@@ -39,17 +33,10 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
public dispose(): void {
|
||||
}
|
||||
|
||||
$show(multiStepHandle: number | undefined, options: IPickOptions): TPromise<number | number[]> {
|
||||
|
||||
const multiStep = typeof multiStepHandle === 'number';
|
||||
if (multiStep && !(this._multiStep && multiStepHandle === this._multiStep.handle && !this._multiStep.token.isCancellationRequested)) {
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
const input: IQuickInput = multiStep ? this._multiStep.input : this._quickInputService;
|
||||
|
||||
$show(options: IPickOptions): TPromise<number | number[]> {
|
||||
const myToken = ++this._token;
|
||||
|
||||
this._contents = new TPromise<MyQuickPickItems[]>((c, e) => {
|
||||
this._contents = new TPromise<TransferQuickPickItems[]>((c, e) => {
|
||||
this._doSetItems = (items) => {
|
||||
if (myToken === this._token) {
|
||||
c(items);
|
||||
@@ -64,31 +51,31 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
});
|
||||
|
||||
if (options.canPickMany) {
|
||||
return asWinJsPromise(token => input.pick(this._contents, options as { canPickMany: true }, token)).then(items => {
|
||||
return asWinJsPromise(token => this._quickInputService.pick(this._contents, options as { canPickMany: true }, token)).then(items => {
|
||||
if (items) {
|
||||
return items.map(item => item.handle);
|
||||
}
|
||||
return undefined;
|
||||
}, undefined, progress => {
|
||||
if (progress) {
|
||||
this._proxy.$onItemSelected((<MyQuickPickItems>progress).handle);
|
||||
this._proxy.$onItemSelected((<TransferQuickPickItems>progress).handle);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return asWinJsPromise(token => input.pick(this._contents, options, token)).then(item => {
|
||||
return asWinJsPromise(token => this._quickInputService.pick(this._contents, options, token)).then(item => {
|
||||
if (item) {
|
||||
return item.handle;
|
||||
}
|
||||
return undefined;
|
||||
}, undefined, progress => {
|
||||
if (progress) {
|
||||
this._proxy.$onItemSelected((<MyQuickPickItems>progress).handle);
|
||||
this._proxy.$onItemSelected((<TransferQuickPickItems>progress).handle);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$setItems(items: MyQuickPickItems[]): TPromise<any> {
|
||||
$setItems(items: TransferQuickPickItems[]): TPromise<any> {
|
||||
if (this._doSetItems) {
|
||||
this._doSetItems(items);
|
||||
}
|
||||
@@ -104,14 +91,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
|
||||
// ---- input
|
||||
|
||||
$input(multiStepHandle: number | undefined, options: InputBoxOptions, validateInput: boolean): TPromise<string> {
|
||||
|
||||
const multiStep = typeof multiStepHandle === 'number';
|
||||
if (multiStep && !(this._multiStep && multiStepHandle === this._multiStep.handle && !this._multiStep.token.isCancellationRequested)) {
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
const input: IQuickInput = multiStep ? this._multiStep.input : this._quickInputService;
|
||||
|
||||
$input(options: InputBoxOptions, validateInput: boolean): TPromise<string> {
|
||||
const inputOptions: IInputOptions = Object.create(null);
|
||||
|
||||
if (options) {
|
||||
@@ -129,27 +109,73 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
};
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => input.input(inputOptions, token));
|
||||
return asWinJsPromise(token => this._quickInputService.input(inputOptions, token));
|
||||
}
|
||||
|
||||
// ---- Multi-step input
|
||||
// ---- QuickInput
|
||||
|
||||
$multiStep(handle: number): TPromise<never> {
|
||||
let outerReject: (err: any) => void;
|
||||
let innerResolve: (value: void) => void;
|
||||
const promise = new TPromise<never>((_, rej) => outerReject = rej, () => innerResolve(undefined));
|
||||
this._quickInputService.multiStepInput((input, token) => {
|
||||
this._multiStep = { handle, input, token };
|
||||
const promise = new TPromise<void>(res => innerResolve = res);
|
||||
token.onCancellationRequested(() => innerResolve(undefined));
|
||||
return promise;
|
||||
})
|
||||
.then(() => promise.cancel(), err => outerReject(err))
|
||||
.then(() => {
|
||||
if (this._multiStep && this._multiStep.handle === handle) {
|
||||
this._multiStep = null;
|
||||
private sessions = new Map<number, IQuickInput>();
|
||||
|
||||
$createOrUpdate(params: TransferQuickInput): TPromise<void> {
|
||||
const sessionId = params.id;
|
||||
let session = this.sessions.get(sessionId);
|
||||
if (!session) {
|
||||
if (params.type === 'quickPick') {
|
||||
const input = this._quickInputService.createQuickPick();
|
||||
input.onDidAccept(() => {
|
||||
this._proxy.$onDidAccept(sessionId);
|
||||
});
|
||||
input.onDidChangeActive(items => {
|
||||
this._proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
|
||||
});
|
||||
input.onDidChangeSelection(items => {
|
||||
this._proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
|
||||
});
|
||||
input.onDidTriggerButton(button => {
|
||||
this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle);
|
||||
});
|
||||
session = input;
|
||||
} else {
|
||||
const input = this._quickInputService.createInputBox();
|
||||
input.onDidAccept(() => {
|
||||
this._proxy.$onDidAccept(sessionId);
|
||||
});
|
||||
session = input;
|
||||
}
|
||||
this.sessions.set(sessionId, session);
|
||||
}
|
||||
for (const param in params) {
|
||||
if (param === 'id' || param === 'type') {
|
||||
continue;
|
||||
}
|
||||
if (param === 'visible') {
|
||||
if (params.visible) {
|
||||
session.show();
|
||||
} else {
|
||||
session.hide();
|
||||
}
|
||||
});
|
||||
return promise;
|
||||
} else if (param === 'buttons') {
|
||||
params.buttons.forEach(button => {
|
||||
const iconPath = button.iconPath;
|
||||
iconPath.dark = URI.revive(iconPath.dark);
|
||||
if (iconPath.light) {
|
||||
iconPath.light = URI.revive(iconPath.light);
|
||||
}
|
||||
});
|
||||
session[param] = params[param];
|
||||
} else {
|
||||
session[param] = params[param];
|
||||
}
|
||||
}
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
$dispose(sessionId: number): TPromise<void> {
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (session) {
|
||||
session.dispose();
|
||||
this.sessions.delete(sessionId);
|
||||
}
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { IProgressService2, ProgressLocation } from 'vs/workbench/services/progress/common/progress';
|
||||
import { localize } from 'vs/nls';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
@@ -17,9 +15,12 @@ import * as Platform from 'vs/base/common/platform';
|
||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
import {
|
||||
ContributedTask, ExtensionTaskSourceTransfer, TaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind,
|
||||
ContributedTask, ExtensionTaskSourceTransfer, KeyedTaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind,
|
||||
PresentationOptions, CommandOptions, CommandConfiguration, RuntimeType, CustomTask, TaskScope, TaskSource, TaskSourceKind, ExtensionTaskSource, RevealKind, PanelKind
|
||||
} from 'vs/workbench/parts/tasks/common/tasks';
|
||||
|
||||
import { TaskDefinition } from 'vs/workbench/parts/tasks/node/tasks';
|
||||
|
||||
import { ITaskService, TaskFilter } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
@@ -29,8 +30,6 @@ import {
|
||||
ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO
|
||||
} from 'vs/workbench/api/shared/tasks';
|
||||
|
||||
export { TaskDTO, TaskHandleDTO, TaskExecutionDTO, TaskFilterDTO };
|
||||
|
||||
namespace TaskExecutionDTO {
|
||||
export function from(value: TaskExecution): TaskExecutionDTO {
|
||||
return {
|
||||
@@ -65,17 +64,13 @@ namespace TaskProcessEndedDTO {
|
||||
}
|
||||
|
||||
namespace TaskDefinitionDTO {
|
||||
export function from(value: TaskIdentifier): TaskDefinitionDTO {
|
||||
export function from(value: KeyedTaskIdentifier): TaskDefinitionDTO {
|
||||
let result = Objects.assign(Object.create(null), value);
|
||||
delete result._key;
|
||||
return result;
|
||||
}
|
||||
export function to(value: TaskDefinitionDTO): TaskIdentifier {
|
||||
const hash = crypto.createHash('md5');
|
||||
hash.update(JSON.stringify(value));
|
||||
let result = Objects.assign(Object.create(null), value);
|
||||
result._key = hash.digest('hex');
|
||||
return result;
|
||||
export function to(value: TaskDefinitionDTO): KeyedTaskIdentifier {
|
||||
return TaskDefinition.createTaskIdentifier(value, console);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,15 +388,24 @@ export class MainThreadTask implements MainThreadTaskShape {
|
||||
this._taskService.registerTaskProvider(handle, {
|
||||
provideTasks: () => {
|
||||
return this._proxy.$provideTasks(handle).then((value) => {
|
||||
let tasks: Task[] = [];
|
||||
for (let task of value.tasks) {
|
||||
if (ContributedTask.is(task)) {
|
||||
let uri = (task._source as any as ExtensionTaskSourceTransfer).__workspaceFolder;
|
||||
if (uri) {
|
||||
delete (task._source as any as ExtensionTaskSourceTransfer).__workspaceFolder;
|
||||
(task._source as any).workspaceFolder = this._workspaceContextServer.getWorkspaceFolder(URI.revive(uri));
|
||||
let taskTransfer = task._source as any as ExtensionTaskSourceTransfer;
|
||||
if (taskTransfer.__workspaceFolder !== void 0 && taskTransfer.__definition !== void 0) {
|
||||
(task._source as any).workspaceFolder = this._workspaceContextServer.getWorkspaceFolder(URI.revive(taskTransfer.__workspaceFolder));
|
||||
delete taskTransfer.__workspaceFolder;
|
||||
let taskIdentifier = TaskDefinition.createTaskIdentifier(taskTransfer.__definition, console);
|
||||
delete taskTransfer.__definition;
|
||||
if (taskIdentifier !== void 0) {
|
||||
(task as ContributedTask).defines = taskIdentifier;
|
||||
task._id = `${task._id}.${taskIdentifier._key}`;
|
||||
tasks.push(task);
|
||||
}
|
||||
} else {
|
||||
console.warn(`Dropping task ${task.name}. Missing workspace folder and task definition`);
|
||||
}
|
||||
}
|
||||
value.tasks = tasks;
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,10 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
mainThreadShowOptions.group = viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn);
|
||||
}
|
||||
|
||||
const webview = this._webviewService.createWebview(MainThreadWebviews.viewType, title, mainThreadShowOptions, options, URI.revive(extensionLocation), this.createWebviewEventDelegate(handle));
|
||||
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
|
||||
@@ -273,4 +276,4 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
||||
<body>${localize('errorMessage', "An error occurred while restoring view:{0}", viewType)}</body>
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import * as vscode from 'vscode';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import * as files from 'vs/platform/files/common/files';
|
||||
import { MainContext, ExtHostContext, IInitData, IExtHostContext } from './extHost.protocol';
|
||||
import { MainContext, ExtHostContext, IInitData, IMainContext } from './extHost.protocol';
|
||||
import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
|
||||
@@ -58,6 +58,7 @@ import { ExtensionActivatedByAPI } from 'vs/workbench/api/node/extHostExtensionA
|
||||
import { OverviewRulerLane } from 'vs/editor/common/model';
|
||||
import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
|
||||
import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview';
|
||||
import { ExtHostComments } from './extHostComments';
|
||||
import { ExtHostSearch } from './extHostSearch';
|
||||
import { ExtHostUrls } from './extHostUrls';
|
||||
|
||||
@@ -79,7 +80,7 @@ function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
|
||||
if (extension.enableProposedApi) {
|
||||
return fn;
|
||||
} else {
|
||||
return <any>throwProposedApiError;
|
||||
return throwProposedApiError.bind(null, extension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
|
||||
*/
|
||||
export function createApiFactory(
|
||||
initData: IInitData,
|
||||
rpcProtocol: IExtHostContext,
|
||||
rpcProtocol: IMainContext,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
extensionService: ExtHostExtensionService,
|
||||
@@ -111,7 +112,6 @@ export function createApiFactory(
|
||||
const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostHeapService, extHostLogService));
|
||||
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands));
|
||||
rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
|
||||
const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration));
|
||||
rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
|
||||
const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol));
|
||||
const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics));
|
||||
@@ -119,12 +119,14 @@ export function createApiFactory(
|
||||
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService());
|
||||
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
|
||||
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
|
||||
const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService));
|
||||
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, 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)));
|
||||
const exthostCommentProviders = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands.converter, extHostDocuments));
|
||||
|
||||
// Check that no named customers are missing
|
||||
const expected: ProxyIdentifier<any>[] = Object.keys(ExtHostContext).map((key) => (<any>ExtHostContext)[key]);
|
||||
@@ -386,13 +388,13 @@ export function createApiFactory(
|
||||
return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest);
|
||||
},
|
||||
showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
|
||||
return extHostQuickOpen.showQuickPick(undefined, items, options, token);
|
||||
return extHostQuickOpen.showQuickPick(items, options, token);
|
||||
},
|
||||
showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
|
||||
return extHostQuickOpen.showWorkspaceFolderPick(options);
|
||||
},
|
||||
showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) {
|
||||
return extHostQuickOpen.showInput(undefined, options, token);
|
||||
return extHostQuickOpen.showInput(options, token);
|
||||
},
|
||||
showOpenDialog(options) {
|
||||
return extHostDialogs.showOpenDialog(options);
|
||||
@@ -446,7 +448,13 @@ export function createApiFactory(
|
||||
}),
|
||||
registerProtocolHandler: proposedApiFunction(extension, (handler: vscode.ProtocolHandler) => {
|
||||
return extHostUrls.registerProtocolHandler(extension.id, handler);
|
||||
})
|
||||
}),
|
||||
createQuickPick: proposedApiFunction(extension, (): vscode.QuickPick => {
|
||||
return extHostQuickOpen.createQuickPick(extension.id);
|
||||
}),
|
||||
createInputBox: proposedApiFunction(extension, (): vscode.InputBox => {
|
||||
return extHostQuickOpen.createInputBox(extension.id);
|
||||
}),
|
||||
};
|
||||
|
||||
// namespace: workspace
|
||||
@@ -545,33 +553,21 @@ export function createApiFactory(
|
||||
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
},
|
||||
fetchTasks: proposedApiFunction(extension, (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
|
||||
return extHostTask.fetchTasks(filter);
|
||||
}),
|
||||
executeTask: proposedApiFunction(extension, (task: vscode.Task): Thenable<vscode.TaskExecution> => {
|
||||
return extHostTask.executeTask(extension, task);
|
||||
}),
|
||||
get taskExecutions(): vscode.TaskExecution[] {
|
||||
return extHostTask.taskExecutions;
|
||||
},
|
||||
onDidStartTask: (listeners, thisArgs?, disposables?) => {
|
||||
return extHostTask.onDidStartTask(listeners, thisArgs, disposables);
|
||||
},
|
||||
onDidEndTask: (listeners, thisArgs?, disposables?) => {
|
||||
return extHostTask.onDidEndTask(listeners, thisArgs, disposables);
|
||||
},
|
||||
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);
|
||||
}),
|
||||
registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => {
|
||||
return exthostCommentProviders.registerDocumentCommentProvider(provider);
|
||||
}),
|
||||
registerWorkspaceCommentProvider: proposedApiFunction(extension, (provider: vscode.WorkspaceCommentProvider) => {
|
||||
return exthostCommentProviders.registerWorkspaceCommentProvider(provider);
|
||||
}),
|
||||
onDidRenameResource: proposedApiFunction(extension, (listener, thisArg?, disposables?) => {
|
||||
return extHostDocuments.onDidRenameResource(listener, thisArg, disposables);
|
||||
}),
|
||||
})
|
||||
};
|
||||
|
||||
// namespace: scm
|
||||
@@ -705,18 +701,7 @@ export function createApiFactory(
|
||||
SourceBreakpoint: extHostTypes.SourceBreakpoint,
|
||||
StatusBarAlignment: extHostTypes.StatusBarAlignment,
|
||||
SymbolInformation: extHostTypes.SymbolInformation,
|
||||
SymbolInformation2: class extends extHostTypes.SymbolInformation2 {
|
||||
constructor(name, detail, kind, range, location) {
|
||||
checkProposedApiEnabled(extension);
|
||||
super(name, detail, kind, range, location);
|
||||
}
|
||||
},
|
||||
Hierarchy: class <T> extends extHostTypes.Hierarchy<T> {
|
||||
constructor(parent: T) {
|
||||
checkProposedApiEnabled(extension);
|
||||
super(parent);
|
||||
}
|
||||
},
|
||||
DocumentSymbol: extHostTypes.DocumentSymbol,
|
||||
SymbolKind: extHostTypes.SymbolKind,
|
||||
SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
|
||||
TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason,
|
||||
@@ -746,17 +731,29 @@ export function createApiFactory(
|
||||
ConfigurationTarget: extHostTypes.ConfigurationTarget,
|
||||
RelativePattern: extHostTypes.RelativePattern,
|
||||
|
||||
DeprecatedFileChangeType: extHostTypes.DeprecatedFileChangeType,
|
||||
DeprecatedFileType: extHostTypes.DeprecatedFileType,
|
||||
FileChangeType: extHostTypes.FileChangeType,
|
||||
FileType: files.FileType,
|
||||
FileSystemError: extHostTypes.FileSystemError,
|
||||
FoldingRange: extHostTypes.FoldingRange,
|
||||
FoldingRangeKind: extHostTypes.FoldingRangeKind
|
||||
FoldingRangeKind: extHostTypes.FoldingRangeKind,
|
||||
|
||||
CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original fs path (using the original casing for the drive letter)
|
||||
*/
|
||||
export function originalFSPath(uri: URI): string {
|
||||
const result = uri.fsPath;
|
||||
if (/^[a-zA-Z]:/.test(result) && uri.path.charAt(1).toLowerCase() === result.charAt(0)) {
|
||||
// Restore original drive letter casing
|
||||
return uri.path.charAt(1) + result.substr(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
class Extension<T> implements vscode.Extension<T> {
|
||||
|
||||
private _extensionService: ExtHostExtensionService;
|
||||
@@ -768,7 +765,7 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) {
|
||||
this._extensionService = extensionService;
|
||||
this.id = description.id;
|
||||
this.extensionPath = paths.normalize(description.extensionLocation.fsPath, true);
|
||||
this.extensionPath = paths.normalize(originalFSPath(description.extensionLocation), true);
|
||||
this.packageJSON = description;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e
|
||||
import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress';
|
||||
import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress';
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
@@ -26,7 +26,7 @@ import * as modes from 'vs/editor/common/modes';
|
||||
import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfig, IAdapterExecutable, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug';
|
||||
|
||||
import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IQuickPickItem, IPickOptions, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { EndOfLine, TextEditorLineNumbersStyle } from 'vs/workbench/api/node/extHostTypes';
|
||||
@@ -102,6 +102,14 @@ export interface MainThreadCommandsShape extends IDisposable {
|
||||
$getCommands(): Thenable<string[]>;
|
||||
}
|
||||
|
||||
export interface MainThreadCommentsShape extends IDisposable {
|
||||
$registerDocumentCommentProvider(handle: number): void;
|
||||
$unregisterDocumentCommentProvider(handle: number): void;
|
||||
$registerWorkspaceCommentProvider(handle: number): void;
|
||||
$unregisterWorkspaceCommentProvider(handle: number): void;
|
||||
$onDidCommentThreadsChange(handle: number, event: modes.CommentThreadChangedEvent): void;
|
||||
}
|
||||
|
||||
export interface MainThreadConfigurationShape extends IDisposable {
|
||||
$updateConfigurationOption(target: ConfigurationTarget, key: string, value: any, resource: UriComponents): TPromise<void>;
|
||||
$removeConfigurationOption(target: ConfigurationTarget, key: string, resource: UriComponents): TPromise<void>;
|
||||
@@ -330,15 +338,74 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
|
||||
$sendProcessExit(terminalId: number, exitCode: number): void;
|
||||
}
|
||||
|
||||
export interface MyQuickPickItems extends IPickOpenEntry {
|
||||
export interface TransferQuickPickItems extends IQuickPickItem {
|
||||
handle: number;
|
||||
}
|
||||
|
||||
export interface TransferQuickInputButton extends IQuickInputButton {
|
||||
handle: number;
|
||||
}
|
||||
|
||||
export type TransferQuickInput = TransferQuickPick | TransferInputBox;
|
||||
|
||||
export interface BaseTransferQuickInput {
|
||||
|
||||
id: number;
|
||||
|
||||
type?: 'quickPick' | 'inputBox';
|
||||
|
||||
enabled?: boolean;
|
||||
|
||||
busy?: boolean;
|
||||
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
export interface TransferQuickPick extends BaseTransferQuickInput {
|
||||
|
||||
type?: 'quickPick';
|
||||
|
||||
value?: string;
|
||||
|
||||
placeholder?: string;
|
||||
|
||||
buttons?: TransferQuickInputButton[];
|
||||
|
||||
items?: TransferQuickPickItems[];
|
||||
|
||||
canSelectMany?: boolean;
|
||||
|
||||
ignoreFocusOut?: boolean;
|
||||
|
||||
matchOnDescription?: boolean;
|
||||
|
||||
matchOnDetail?: boolean;
|
||||
}
|
||||
|
||||
export interface TransferInputBox extends BaseTransferQuickInput {
|
||||
|
||||
type?: 'inputBox';
|
||||
|
||||
value?: string;
|
||||
|
||||
placeholder?: string;
|
||||
|
||||
password?: boolean;
|
||||
|
||||
buttons?: TransferQuickInputButton[];
|
||||
|
||||
prompt?: string;
|
||||
|
||||
validationMessage?: string;
|
||||
}
|
||||
|
||||
export interface MainThreadQuickOpenShape extends IDisposable {
|
||||
$show(multiStepHandle: number | undefined, options: IPickOptions): TPromise<number | number[]>;
|
||||
$setItems(items: MyQuickPickItems[]): TPromise<any>;
|
||||
$show(options: IPickOptions): TPromise<number | number[]>;
|
||||
$setItems(items: TransferQuickPickItems[]): TPromise<any>;
|
||||
$setError(error: Error): TPromise<any>;
|
||||
$input(multiStepHandle: number | undefined, options: vscode.InputBoxOptions, validateInput: boolean): TPromise<string>;
|
||||
$multiStep(handle: number): TPromise<never>;
|
||||
$input(options: vscode.InputBoxOptions, validateInput: boolean): TPromise<string>;
|
||||
$createOrUpdate(params: TransferQuickInput): TPromise<void>;
|
||||
$dispose(id: number): TPromise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadStatusBarShape extends IDisposable {
|
||||
@@ -666,17 +733,15 @@ export interface LocationDto {
|
||||
range: IRange;
|
||||
}
|
||||
|
||||
export interface SymbolInformationDto extends IdObject {
|
||||
export interface WorkspaceSymbolDto extends IdObject {
|
||||
name: string;
|
||||
containerName?: string;
|
||||
kind: modes.SymbolKind;
|
||||
location: LocationDto;
|
||||
definingRange: IRange;
|
||||
children?: SymbolInformationDto[];
|
||||
}
|
||||
|
||||
export interface WorkspaceSymbolsDto extends IdObject {
|
||||
symbols: SymbolInformationDto[];
|
||||
symbols: WorkspaceSymbolDto[];
|
||||
}
|
||||
|
||||
export interface ResourceFileEditDto {
|
||||
@@ -720,7 +785,7 @@ export interface CodeActionDto {
|
||||
}
|
||||
|
||||
export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents): TPromise<SymbolInformationDto[]>;
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents): TPromise<modes.DocumentSymbol[]>;
|
||||
$provideCodeLenses(handle: number, resource: UriComponents): TPromise<modes.ICodeLensSymbol[]>;
|
||||
$resolveCodeLens(handle: number, resource: UriComponents, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol>;
|
||||
$provideDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise<LocationDto | LocationDto[]>;
|
||||
@@ -734,7 +799,7 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions): TPromise<ISingleEditOperation[]>;
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions): TPromise<ISingleEditOperation[]>;
|
||||
$provideWorkspaceSymbols(handle: number, search: string): TPromise<WorkspaceSymbolsDto>;
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: SymbolInformationDto): TPromise<SymbolInformationDto>;
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto): TPromise<WorkspaceSymbolDto>;
|
||||
$releaseWorkspaceSymbols(handle: number, id: number): void;
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string): TPromise<WorkspaceEditDto>;
|
||||
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.RenameLocation>;
|
||||
@@ -752,6 +817,10 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
export interface ExtHostQuickOpenShape {
|
||||
$onItemSelected(handle: number): void;
|
||||
$validateInput(input: string): TPromise<string>;
|
||||
$onDidChangeActive(sessionId: number, handles: number[]): void;
|
||||
$onDidChangeSelection(sessionId: number, handles: number[]): void;
|
||||
$onDidAccept(sessionId: number): void;
|
||||
$onDidTriggerButton(sessionId: number, handle: number): void;
|
||||
}
|
||||
|
||||
export interface ShellLaunchConfigDto {
|
||||
@@ -833,8 +902,6 @@ 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>;
|
||||
@@ -874,10 +941,18 @@ export interface ExtHostProgressShape {
|
||||
$acceptProgressCanceled(handle: number): void;
|
||||
}
|
||||
|
||||
export interface ExtHostCommentsShape {
|
||||
$provideDocumentComments(handle: number, document: UriComponents): TPromise<modes.CommentInfo>;
|
||||
$createNewCommentThread?(handle: number, document: UriComponents, range: IRange, text: string): TPromise<modes.CommentThread>;
|
||||
$replyToCommentThread?(handle: number, document: UriComponents, range: IRange, commentThread: modes.CommentThread, text: string): TPromise<modes.CommentThread>;
|
||||
$provideWorkspaceComments(handle: number): TPromise<modes.CommentThread[]>;
|
||||
}
|
||||
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
MainThreadCommands: <ProxyIdentifier<MainThreadCommandsShape>>createMainId<MainThreadCommandsShape>('MainThreadCommands'),
|
||||
MainThreadComments: createMainId<MainThreadCommentsShape>('MainThreadComments'),
|
||||
MainThreadConfiguration: createMainId<MainThreadConfigurationShape>('MainThreadConfiguration'),
|
||||
MainThreadDebugService: createMainId<MainThreadDebugServiceShape>('MainThreadDebugService'),
|
||||
MainThreadDecorations: createMainId<MainThreadDecorationsShape>('MainThreadDecorations'),
|
||||
@@ -935,6 +1010,7 @@ export const ExtHostContext = {
|
||||
ExtHostWorkspace: createExtId<ExtHostWorkspaceShape>('ExtHostWorkspace'),
|
||||
ExtHostWindow: createExtId<ExtHostWindowShape>('ExtHostWindow'),
|
||||
ExtHostWebviews: createExtId<ExtHostWebviewsShape>('ExtHostWebviews'),
|
||||
ExtHostUrls: createExtId<ExtHostUrlsShape>('ExtHostUrls'),
|
||||
ExtHostProgress: createMainId<ExtHostProgressShape>('ExtHostProgress')
|
||||
ExtHostProgress: createMainId<ExtHostProgressShape>('ExtHostProgress'),
|
||||
ExtHostComments: createMainId<ExtHostCommentsShape>('ExtHostComments'),
|
||||
ExtHostUrls: createExtId<ExtHostUrlsShape>('ExtHostUrls')
|
||||
};
|
||||
|
||||
@@ -11,12 +11,11 @@ import * as vscode from 'vscode';
|
||||
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { IRawColorInfo } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as search from 'vs/workbench/parts/search/common/search';
|
||||
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 { ICommandsExecutor, PreviewHTMLAPICommand, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand } from './apiCommands';
|
||||
|
||||
@@ -266,11 +265,11 @@ export class ExtHostApiCommands {
|
||||
* @return A promise that resolves to an array of symbol information.
|
||||
*/
|
||||
private _executeWorkspaceSymbolProvider(query: string): Thenable<types.SymbolInformation[]> {
|
||||
return this._commands.executeCommand<[IWorkspaceSymbolProvider, modes.SymbolInformation[]][]>('_executeWorkspaceSymbolProvider', { query }).then(value => {
|
||||
return this._commands.executeCommand<[search.IWorkspaceSymbolProvider, search.IWorkspaceSymbol[]][]>('_executeWorkspaceSymbolProvider', { query }).then(value => {
|
||||
const result: types.SymbolInformation[] = [];
|
||||
if (Array.isArray(value)) {
|
||||
for (let tuple of value) {
|
||||
result.push(...tuple[1].map(typeConverters.SymbolInformation.to));
|
||||
result.push(...tuple[1].map(typeConverters.WorkspaceSymbol.to));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -404,13 +403,13 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
}
|
||||
|
||||
private _executeDocumentSymbolProvider(resource: URI): Thenable<types.SymbolInformation[]> {
|
||||
private _executeDocumentSymbolProvider(resource: URI): Thenable<vscode.DocumentSymbol[]> {
|
||||
const args = {
|
||||
resource
|
||||
};
|
||||
return this._commands.executeCommand<modes.IOutline>('_executeDocumentSymbolProvider', args).then(value => {
|
||||
if (value && Array.isArray(value.entries)) {
|
||||
return value.entries.map(typeConverters.SymbolInformation.to);
|
||||
return this._commands.executeCommand<modes.DocumentSymbol[]>('_executeDocumentSymbolProvider', args).then(value => {
|
||||
if (value && Array.isArray(value)) {
|
||||
return value.map(typeConverters.DocumentSymbol.to);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
@@ -131,6 +131,8 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
$executeContributedCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
this._logService.trace('ExtHostCommands#$executeContributedCommand', id);
|
||||
|
||||
if (!this._commands.has(id)) {
|
||||
return Promise.reject(new Error(`Contributed command '${id}' does not exist.`));
|
||||
} else {
|
||||
|
||||
179
src/vs/workbench/api/node/extHostComments.ts
Normal file
179
src/vs/workbench/api/node/extHostComments.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { asWinJsPromise } from 'vs/base/common/async';
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import * as extHostTypeConverter from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostCommentsShape, IMainContext, MainContext, MainThreadCommentsShape } from './extHost.protocol';
|
||||
import { CommandsConverter } from './extHostCommands';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
|
||||
export class ExtHostComments implements ExtHostCommentsShape {
|
||||
private static handlePool = 0;
|
||||
|
||||
private _proxy: MainThreadCommentsShape;
|
||||
|
||||
private _documentProviders = new Map<number, vscode.DocumentCommentProvider>();
|
||||
private _workspaceProviders = new Map<number, vscode.WorkspaceCommentProvider>();
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
private readonly _commandsConverter: CommandsConverter,
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadComments);
|
||||
}
|
||||
|
||||
registerWorkspaceCommentProvider(
|
||||
provider: vscode.WorkspaceCommentProvider
|
||||
): vscode.Disposable {
|
||||
const handle = ExtHostComments.handlePool++;
|
||||
this._workspaceProviders.set(handle, provider);
|
||||
this._proxy.$registerWorkspaceCommentProvider(handle);
|
||||
this.registerListeners(handle, provider);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this._proxy.$unregisterWorkspaceCommentProvider(handle);
|
||||
this._workspaceProviders.delete(handle);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
registerDocumentCommentProvider(
|
||||
provider: vscode.DocumentCommentProvider
|
||||
): vscode.Disposable {
|
||||
const handle = ExtHostComments.handlePool++;
|
||||
this._documentProviders.set(handle, provider);
|
||||
this._proxy.$registerDocumentCommentProvider(handle);
|
||||
this.registerListeners(handle, provider);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this._proxy.$unregisterDocumentCommentProvider(handle);
|
||||
this._documentProviders.delete(handle);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$createNewCommentThread(handle: number, uri: UriComponents, range: IRange, text: string): TPromise<modes.CommentThread> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
const ran = <vscode.Range>extHostTypeConverter.Range.to(range);
|
||||
|
||||
if (!data || !data.document) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => {
|
||||
let provider = this._documentProviders.get(handle);
|
||||
return provider.createNewCommentThread(data.document, ran, text, token);
|
||||
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
|
||||
}
|
||||
|
||||
$replyToCommentThread(handle: number, uri: UriComponents, range: IRange, thread: modes.CommentThread, text: string): TPromise<modes.CommentThread> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
const ran = <vscode.Range>extHostTypeConverter.Range.to(range);
|
||||
|
||||
if (!data || !data.document) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => {
|
||||
let provider = this._documentProviders.get(handle);
|
||||
return provider.replyToCommentThread(data.document, ran, convertFromCommentThread(thread), text, token);
|
||||
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
|
||||
}
|
||||
|
||||
$provideDocumentComments(handle: number, uri: UriComponents): TPromise<modes.CommentInfo> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
if (!data || !data.document) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => {
|
||||
let provider = this._documentProviders.get(handle);
|
||||
return provider.provideDocumentComments(data.document, token);
|
||||
})
|
||||
.then(commentInfo => commentInfo ? convertCommentInfo(handle, commentInfo, this._commandsConverter) : null);
|
||||
}
|
||||
|
||||
$provideWorkspaceComments(handle: number): TPromise<modes.CommentThread[]> {
|
||||
const provider = this._workspaceProviders.get(handle);
|
||||
if (!provider) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => {
|
||||
return provider.provideWorkspaceComments(token);
|
||||
}).then(comments =>
|
||||
comments.map(x => convertToCommentThread(x, this._commandsConverter)
|
||||
));
|
||||
}
|
||||
|
||||
private registerListeners(handle: number, provider: vscode.DocumentCommentProvider | vscode.WorkspaceCommentProvider) {
|
||||
provider.onDidChangeCommentThreads(event => {
|
||||
|
||||
this._proxy.$onDidCommentThreadsChange(handle, {
|
||||
owner: handle,
|
||||
changed: event.changed.map(x => convertToCommentThread(x, this._commandsConverter)),
|
||||
added: event.added.map(x => convertToCommentThread(x, this._commandsConverter)),
|
||||
removed: event.removed.map(x => convertToCommentThread(x, this._commandsConverter))
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function convertCommentInfo(owner: number, vscodeCommentInfo: vscode.CommentInfo, commandsConverter: CommandsConverter): modes.CommentInfo {
|
||||
return {
|
||||
owner: owner,
|
||||
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(x, commandsConverter)),
|
||||
commentingRanges: vscodeCommentInfo.commentingRanges ? vscodeCommentInfo.commentingRanges.map(range => extHostTypeConverter.Range.from(range)) : []
|
||||
};
|
||||
}
|
||||
|
||||
function convertToCommentThread(vscodeCommentThread: vscode.CommentThread, commandsConverter: CommandsConverter): modes.CommentThread {
|
||||
return {
|
||||
threadId: vscodeCommentThread.threadId,
|
||||
resource: vscodeCommentThread.resource.toString(),
|
||||
range: extHostTypeConverter.Range.from(vscodeCommentThread.range),
|
||||
comments: vscodeCommentThread.comments.map(comment => convertToComment(comment, commandsConverter)),
|
||||
collapsibleState: vscodeCommentThread.collapsibleState
|
||||
};
|
||||
}
|
||||
|
||||
function convertFromCommentThread(commentThread: modes.CommentThread): vscode.CommentThread {
|
||||
return {
|
||||
threadId: commentThread.threadId,
|
||||
resource: URI.parse(commentThread.resource),
|
||||
range: extHostTypeConverter.Range.to(commentThread.range),
|
||||
comments: commentThread.comments.map(convertFromComment),
|
||||
collapsibleState: commentThread.collapsibleState
|
||||
};
|
||||
}
|
||||
|
||||
function convertFromComment(comment: modes.Comment): vscode.Comment {
|
||||
return {
|
||||
commentId: comment.commentId,
|
||||
body: extHostTypeConverter.MarkdownString.to(comment.body),
|
||||
userName: comment.userName,
|
||||
gravatar: comment.gravatar
|
||||
};
|
||||
}
|
||||
|
||||
function convertToComment(vscodeComment: vscode.Comment, commandsConverter: CommandsConverter): modes.Comment {
|
||||
return {
|
||||
commentId: vscodeComment.commentId,
|
||||
body: extHostTypeConverter.MarkdownString.from(vscodeComment.body),
|
||||
userName: vscodeComment.userName,
|
||||
gravatar: vscodeComment.gravatar,
|
||||
command: vscodeComment.command ? commandsConverter.toInternal(vscodeComment.command) : null
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import * as nls from 'vs/nls';
|
||||
import {
|
||||
MainContext, MainThreadDebugServiceShape, ExtHostDebugServiceShape, DebugSessionUUID,
|
||||
IMainContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto
|
||||
@@ -24,10 +25,11 @@ import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumen
|
||||
import { IAdapterExecutable, ITerminalSettings, IDebuggerContribution, IConfig, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug';
|
||||
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';
|
||||
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/node/variableResolver';
|
||||
import { ExtHostConfiguration } from './extHostConfiguration';
|
||||
import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/common/debugUtils';
|
||||
import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
|
||||
|
||||
@@ -66,12 +68,16 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
|
||||
private _variableResolver: IConfigurationResolverService;
|
||||
|
||||
private _integratedTerminalInstance: vscode.Terminal;
|
||||
private _terminalDisposedListener: IDisposable;
|
||||
|
||||
|
||||
constructor(mainContext: IMainContext,
|
||||
private _workspaceService: ExtHostWorkspace,
|
||||
private _extensionService: ExtHostExtensionService,
|
||||
private _editorsService: ExtHostDocumentsAndEditors,
|
||||
private _configurationService: ExtHostConfiguration
|
||||
private _configurationService: ExtHostConfiguration,
|
||||
private _terminalService: ExtHostTerminalService
|
||||
) {
|
||||
|
||||
this._handleCounter = 0;
|
||||
@@ -117,22 +123,45 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
}
|
||||
}
|
||||
|
||||
public $runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
|
||||
const terminalLauncher = getTerminalLauncher();
|
||||
if (terminalLauncher) {
|
||||
return terminalLauncher.runInTerminal(args, config);
|
||||
public async $runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
|
||||
|
||||
if (args.kind === 'integrated') {
|
||||
|
||||
if (!this._terminalDisposedListener) {
|
||||
// React on terminal disposed and check if that is the debug terminal #12956
|
||||
this._terminalDisposedListener = this._terminalService.onDidCloseTerminal(terminal => {
|
||||
if (this._integratedTerminalInstance && this._integratedTerminalInstance === terminal) {
|
||||
this._integratedTerminalInstance = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let t = this._integratedTerminalInstance;
|
||||
|
||||
if ((t && hasChildprocesses(await t.processId)) || !t) {
|
||||
t = this._terminalService.createTerminal(args.title || nls.localize('debug.terminal.title', "debuggee"));
|
||||
this._integratedTerminalInstance = t;
|
||||
}
|
||||
t.show();
|
||||
|
||||
return new TPromise((resolve, error) => {
|
||||
setTimeout(_ => {
|
||||
const command = prepareCommand(args, config);
|
||||
t.sendText(command, true);
|
||||
resolve(void 0);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
} else if (args.kind === 'external') {
|
||||
|
||||
const terminalLauncher = getTerminalLauncher();
|
||||
if (terminalLauncher) {
|
||||
return terminalLauncher.runInTerminal(args, config);
|
||||
}
|
||||
}
|
||||
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._workspaceService, this._editorsService, this._configurationService);
|
||||
@@ -146,7 +175,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
};
|
||||
return asWinJsPromise(token => DebugAdapter.substituteVariables(ws, config, this._variableResolver));
|
||||
return asWinJsPromise(token => this._variableResolver.resolveAny(ws, config));
|
||||
}
|
||||
|
||||
public $startDASession(handle: number, debugType: string, adpaterExecutable: IAdapterExecutable | null, debugPort: number): TPromise<void> {
|
||||
@@ -558,15 +587,12 @@ export class ExtHostDebugConsole implements vscode.DebugConsole {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostVariableResolverService implements IConfigurationResolverService {
|
||||
export class ExtHostVariableResolverService extends AbstractVariableResolverService {
|
||||
|
||||
_serviceBrand: any;
|
||||
_variableResolver: VariableResolver;
|
||||
|
||||
constructor(workspace: ExtHostWorkspace, editors: ExtHostDocumentsAndEditors, configuration: ExtHostConfiguration) {
|
||||
this._variableResolver = new VariableResolver({
|
||||
constructor(workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfiguration) {
|
||||
super({
|
||||
getFolderUri: (folderName: string): URI => {
|
||||
const folders = workspace.getWorkspaceFolders();
|
||||
const folders = workspaceService.getWorkspaceFolders();
|
||||
const found = folders.filter(f => f.name === folderName);
|
||||
if (found && found.length > 0) {
|
||||
return found[0].uri;
|
||||
@@ -574,16 +600,16 @@ export class ExtHostVariableResolverService implements IConfigurationResolverSer
|
||||
return undefined;
|
||||
},
|
||||
getWorkspaceFolderCount: (): number => {
|
||||
return workspace.getWorkspaceFolders().length;
|
||||
return workspaceService.getWorkspaceFolders().length;
|
||||
},
|
||||
getConfigurationValue: (folderUri: URI, section: string) => {
|
||||
return configuration.getConfiguration(undefined, folderUri).get<string>(section);
|
||||
return configurationService.getConfiguration(undefined, folderUri).get<string>(section);
|
||||
},
|
||||
getExecPath: (): string | undefined => {
|
||||
return undefined; // does not exist in EH
|
||||
},
|
||||
getFilePath: (): string | undefined => {
|
||||
const activeEditor = editors.activeEditor();
|
||||
const activeEditor = editorService.activeEditor();
|
||||
if (activeEditor) {
|
||||
const resource = activeEditor.document.uri;
|
||||
if (resource.scheme === Schemas.file) {
|
||||
@@ -593,34 +619,19 @@ export class ExtHostVariableResolverService implements IConfigurationResolverSer
|
||||
return undefined;
|
||||
},
|
||||
getSelectedText: (): string | undefined => {
|
||||
const activeEditor = editors.activeEditor();
|
||||
const activeEditor = editorService.activeEditor();
|
||||
if (activeEditor && !activeEditor.selection.isEmpty) {
|
||||
return activeEditor.document.getText(activeEditor.selection);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getLineNumber: (): string => {
|
||||
const activeEditor = editors.activeEditor();
|
||||
const activeEditor = editorService.activeEditor();
|
||||
if (activeEditor) {
|
||||
return String(activeEditor.selection.end.line + 1);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}, process.env);
|
||||
}
|
||||
|
||||
public resolve(root: IWorkspaceFolder, value: string): string;
|
||||
public resolve(root: IWorkspaceFolder, value: string[]): string[];
|
||||
public resolve(root: IWorkspaceFolder, value: IStringDictionary<string>): IStringDictionary<string>;
|
||||
public resolve(root: IWorkspaceFolder, value: any): any {
|
||||
return this._variableResolver.resolveAny(root ? root.uri : undefined, value);
|
||||
}
|
||||
|
||||
public resolveAny<T>(root: IWorkspaceFolder, value: T, commandMapping?: IStringDictionary<string>): T {
|
||||
return this._variableResolver.resolveAny(root ? root.uri : undefined, value, commandMapping);
|
||||
}
|
||||
|
||||
public executeCommandVariables(configuration: any, variables: IStringDictionary<string>): TPromise<IStringDictionary<string>> {
|
||||
throw new Error('findAndExecuteCommandVariables not implemented.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -78,32 +78,32 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
return this._deliverEventAsync(listener, thisArg, stubEvent).then(() => {
|
||||
return this._deliverEventAsync(extension, listener, thisArg, stubEvent).then(() => {
|
||||
// don't send result across the wire
|
||||
return true;
|
||||
|
||||
}, err => {
|
||||
|
||||
this._logService.error('[onWillSaveTextDocument]', extension.id);
|
||||
this._logService.error(`onWillSaveTextDocument-listener from extension '${extension.id}' threw ERROR`);
|
||||
this._logService.error(err);
|
||||
|
||||
if (!(err instanceof Error) || (<Error>err).message !== 'concurrent_edits') {
|
||||
const errors = this._badListeners.get(listener);
|
||||
this._badListeners.set(listener, !errors ? 1 : errors + 1);
|
||||
|
||||
// todo@joh signal to the listener?
|
||||
// if (errors === this._thresholds.errors) {
|
||||
// console.warn('BAD onWillSaveTextDocumentEvent-listener is from now on being ignored');
|
||||
// }
|
||||
if (errors > this._thresholds.errors) {
|
||||
this._logService.info(`onWillSaveTextDocument-listener from extension '${extension.id}' will now be IGNORED because of timeouts and/or errors`);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private _deliverEventAsync(listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
|
||||
private _deliverEventAsync(extension: IExtensionDescription, listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
|
||||
|
||||
const promises: Promise<vscode.TextEdit[]>[] = [];
|
||||
|
||||
const t1 = Date.now();
|
||||
const { document, reason } = stubEvent;
|
||||
const { version } = document;
|
||||
|
||||
@@ -133,6 +133,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
const handle = setTimeout(() => reject(new Error('timeout')), this._thresholds.timeout);
|
||||
|
||||
return Promise.all(promises).then(edits => {
|
||||
this._logService.debug(`onWillSaveTextDocument-listener from extension '${extension.id}' finished after ${(Date.now() - t1)}ms`);
|
||||
clearTimeout(handle);
|
||||
resolve(edits);
|
||||
}).catch(err => {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/n
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage';
|
||||
import { createApiFactory, initializeExtensionApi, checkProposedApiEnabled } from 'vs/workbench/api/node/extHost.api.impl';
|
||||
import { MainContext, MainThreadExtensionServiceShape, IWorkspaceData, IEnvironment, IInitData, ExtHostExtensionServiceShape, MainThreadTelemetryShape, IExtHostContext } from './extHost.protocol';
|
||||
import { MainContext, MainThreadExtensionServiceShape, IWorkspaceData, IEnvironment, IInitData, ExtHostExtensionServiceShape, MainThreadTelemetryShape, IMainContext } from './extHost.protocol';
|
||||
import { IExtensionMemento, ExtensionsActivator, ActivatedExtension, IExtensionAPI, IExtensionContext, EmptyExtension, IExtensionModule, ExtensionActivationTimesBuilder, ExtensionActivationTimes, ExtensionActivationReason, ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
@@ -136,7 +136,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
* This class is constructed manually because it is a service, so it doesn't use any ctor injection
|
||||
*/
|
||||
constructor(initData: IInitData,
|
||||
extHostContext: IExtHostContext,
|
||||
extHostContext: IMainContext,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
extHostLogService: ExtHostLogService
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import * as vscode from 'vscode';
|
||||
import * as typeConvert from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, Hierarchy, SymbolInformation2 } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
@@ -17,10 +17,10 @@ import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, SymbolInformationDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto, ISerializedDocumentFilter } from './extHost.protocol';
|
||||
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto, ISerializedDocumentFilter } from './extHost.protocol';
|
||||
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
import { ISelection, Selection } from 'vs/editor/common/core/selection';
|
||||
@@ -37,21 +37,21 @@ class OutlineAdapter {
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideDocumentSymbols(resource: URI): TPromise<SymbolInformationDto[]> {
|
||||
provideDocumentSymbols(resource: URI): TPromise<modes.DocumentSymbol[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
return asWinJsPromise(token => this._provider.provideDocumentSymbols(doc, token)).then(value => {
|
||||
if (isFalsyOrEmpty(value)) {
|
||||
return undefined;
|
||||
}
|
||||
let [probe] = value;
|
||||
if (!(probe instanceof Hierarchy)) {
|
||||
value = OutlineAdapter._asSymbolHierarchy(<SymbolInformation[]>value);
|
||||
if (value[0] instanceof DocumentSymbol) {
|
||||
return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
|
||||
} else {
|
||||
return OutlineAdapter._asDocumentSymbolTree(resource, <SymbolInformation[]>value);
|
||||
}
|
||||
return (<Hierarchy<SymbolInformation2>[]>value).map(typeConvert.HierarchicalSymbolInformation.from);
|
||||
});
|
||||
}
|
||||
|
||||
private static _asSymbolHierarchy(info: SymbolInformation[]): vscode.Hierarchy<SymbolInformation2>[] {
|
||||
private static _asDocumentSymbolTree(resource: URI, info: SymbolInformation[]): modes.DocumentSymbol[] {
|
||||
// first sort by start (and end) and then loop over all elements
|
||||
// and build a tree based on containment.
|
||||
info = info.slice(0).sort((a, b) => {
|
||||
@@ -61,12 +61,17 @@ class OutlineAdapter {
|
||||
}
|
||||
return res;
|
||||
});
|
||||
let res: Hierarchy<SymbolInformation2>[] = [];
|
||||
let parentStack: Hierarchy<SymbolInformation2>[] = [];
|
||||
let res: modes.DocumentSymbol[] = [];
|
||||
let parentStack: modes.DocumentSymbol[] = [];
|
||||
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
|
||||
let element = <modes.DocumentSymbol>{
|
||||
name: info[i].name,
|
||||
kind: typeConvert.SymbolKind.from(info[i].kind),
|
||||
containerName: info[i].containerName,
|
||||
fullRange: typeConvert.Range.from(info[i].location.range),
|
||||
identifierRange: typeConvert.Range.from(info[i].location.range),
|
||||
children: []
|
||||
};
|
||||
|
||||
while (true) {
|
||||
if (parentStack.length === 0) {
|
||||
@@ -75,7 +80,7 @@ class OutlineAdapter {
|
||||
break;
|
||||
}
|
||||
let parent = parentStack[parentStack.length - 1];
|
||||
if (parent.parent.range.contains(element.parent.range) && !parent.parent.range.isEqual(element.parent.range)) {
|
||||
if (EditorRange.containsRange(parent.fullRange, element.fullRange) && !EditorRange.equalsRange(parent.fullRange, element.fullRange)) {
|
||||
parent.children.push(element);
|
||||
parentStack.push(element);
|
||||
break;
|
||||
@@ -428,7 +433,7 @@ class NavigateTypeAdapter {
|
||||
console.warn('INVALID SymbolInformation, lacks name', item);
|
||||
continue;
|
||||
}
|
||||
const symbol = IdObject.mixin(typeConvert.SymbolInformation.from(item));
|
||||
const symbol = IdObject.mixin(typeConvert.WorkspaceSymbol.from(item));
|
||||
this._symbolCache[symbol._id] = item;
|
||||
result.symbols.push(symbol);
|
||||
}
|
||||
@@ -441,7 +446,7 @@ class NavigateTypeAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
resolveWorkspaceSymbol(symbol: SymbolInformationDto): TPromise<SymbolInformationDto> {
|
||||
resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto): TPromise<WorkspaceSymbolDto> {
|
||||
|
||||
if (typeof this._provider.resolveWorkspaceSymbol !== 'function') {
|
||||
return TPromise.as(symbol);
|
||||
@@ -450,7 +455,7 @@ class NavigateTypeAdapter {
|
||||
const item = this._symbolCache[symbol._id];
|
||||
if (item) {
|
||||
return asWinJsPromise(token => this._provider.resolveWorkspaceSymbol(item, token)).then(value => {
|
||||
return value && mixin(symbol, typeConvert.SymbolInformation.from(value), true);
|
||||
return value && mixin(symbol, typeConvert.WorkspaceSymbol.from(value), true);
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
@@ -930,7 +935,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents): TPromise<SymbolInformationDto[]> {
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents): TPromise<modes.DocumentSymbol[]> {
|
||||
return this._withAdapter(handle, OutlineAdapter, adapter => adapter.provideDocumentSymbols(URI.revive(resource)));
|
||||
}
|
||||
|
||||
@@ -1085,7 +1090,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search));
|
||||
}
|
||||
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: SymbolInformationDto): TPromise<SymbolInformationDto> {
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto): TPromise<WorkspaceSymbolDto> {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@ import { ProgressOptions } from 'vscode';
|
||||
import { MainThreadProgressShape, ExtHostProgressShape } from './extHost.protocol';
|
||||
import { ProgressLocation } from './extHostTypeConverters';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IProgressStep, Progress } from 'vs/platform/progress/common/progress';
|
||||
import { Progress } from 'vs/platform/progress/common/progress';
|
||||
import { localize } from 'vs/nls';
|
||||
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { debounce } from 'vs/base/common/decorators';
|
||||
import { IProgressStep } from 'vs/workbench/services/progress/common/progress';
|
||||
|
||||
export class ExtHostProgress implements ExtHostProgressShape {
|
||||
|
||||
|
||||
@@ -4,13 +4,18 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { wireCancellationToken, asWinJsPromise } from 'vs/base/common/async';
|
||||
import { asWinJsPromise, wireCancellationToken } from 'vs/base/common/async';
|
||||
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 { Emitter } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
|
||||
import { ExtHostQuickOpenShape, IMainContext, MainContext, MainThreadQuickOpenShape, TransferQuickPickItems, TransferQuickInput, TransferQuickInputButton } from './extHost.protocol';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { ThemeIcon } from 'vs/workbench/api/node/extHostTypes';
|
||||
|
||||
export type Item = string | QuickPickItem;
|
||||
|
||||
@@ -23,23 +28,25 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
private _onDidSelectItem: (handle: number) => void;
|
||||
private _validateInput: (input: string) => string | Thenable<string>;
|
||||
|
||||
private _sessions = new Map<number, ExtHostQuickInput>();
|
||||
|
||||
constructor(mainContext: IMainContext, workspace: ExtHostWorkspace, commands: ExtHostCommands) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadQuickOpen);
|
||||
this._workspace = workspace;
|
||||
this._commands = commands;
|
||||
}
|
||||
|
||||
showQuickPick(multiStepHandle: number | undefined, itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Thenable<QuickPickItem[] | undefined>;
|
||||
showQuickPick(multiStepHandle: number | undefined, itemsOrItemsPromise: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string | undefined>;
|
||||
showQuickPick(multiStepHandle: number | undefined, itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<QuickPickItem | undefined>;
|
||||
showQuickPick(multiStepHandle: number | undefined, itemsOrItemsPromise: Item[] | Thenable<Item[]>, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Thenable<Item | Item[] | undefined> {
|
||||
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Thenable<QuickPickItem[] | undefined>;
|
||||
showQuickPick(itemsOrItemsPromise: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string | undefined>;
|
||||
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<QuickPickItem | undefined>;
|
||||
showQuickPick(itemsOrItemsPromise: Item[] | Thenable<Item[]>, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Thenable<Item | Item[] | undefined> {
|
||||
|
||||
// clear state from last invocation
|
||||
this._onDidSelectItem = undefined;
|
||||
|
||||
const itemsPromise = <TPromise<Item[]>>TPromise.wrap(itemsOrItemsPromise);
|
||||
|
||||
const quickPickWidget = this._proxy.$show(multiStepHandle, {
|
||||
const quickPickWidget = this._proxy.$show({
|
||||
placeHolder: options && options.placeHolder,
|
||||
matchOnDescription: options && options.matchOnDescription,
|
||||
matchOnDetail: options && options.matchOnDetail,
|
||||
@@ -54,7 +61,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
|
||||
return itemsPromise.then(items => {
|
||||
|
||||
let pickItems: MyQuickPickItems[] = [];
|
||||
let pickItems: TransferQuickPickItems[] = [];
|
||||
for (let handle = 0; handle < items.length; handle++) {
|
||||
|
||||
let item = items[handle];
|
||||
@@ -115,12 +122,12 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
|
||||
// ---- input
|
||||
|
||||
showInput(multiStepHandle: number | undefined, options?: InputBoxOptions, token: CancellationToken = CancellationToken.None): Thenable<string> {
|
||||
showInput(options?: InputBoxOptions, token: CancellationToken = CancellationToken.None): Thenable<string> {
|
||||
|
||||
// global validate fn used in callback below
|
||||
this._validateInput = options && options.validateInput;
|
||||
|
||||
const promise = this._proxy.$input(multiStepHandle, options, typeof this._validateInput === 'function');
|
||||
const promise = this._proxy.$input(options, typeof this._validateInput === 'function');
|
||||
return wireCancellationToken(token, promise, true);
|
||||
}
|
||||
|
||||
@@ -142,4 +149,406 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
return this._workspace.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0];
|
||||
});
|
||||
}
|
||||
|
||||
// ---- QuickInput
|
||||
|
||||
createQuickPick(extensionId: string): QuickPick {
|
||||
const session = new ExtHostQuickPick(this._proxy, extensionId, () => this._sessions.delete(session._id));
|
||||
this._sessions.set(session._id, session);
|
||||
return session;
|
||||
}
|
||||
|
||||
createInputBox(extensionId: string): InputBox {
|
||||
const session = new ExtHostInputBox(this._proxy, extensionId, () => this._sessions.delete(session._id));
|
||||
this._sessions.set(session._id, session);
|
||||
return session;
|
||||
}
|
||||
|
||||
$onDidAccept(sessionId: number): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session instanceof ExtHostQuickPick) {
|
||||
session._fireDidAccept();
|
||||
}
|
||||
}
|
||||
|
||||
$onDidChangeActive(sessionId: number, handles: number[]): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session instanceof ExtHostQuickPick) {
|
||||
session._fireDidChangeFocus(handles);
|
||||
}
|
||||
}
|
||||
|
||||
$onDidChangeSelection(sessionId: number, handles: number[]): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session instanceof ExtHostQuickPick) {
|
||||
session._fireDidChangeSelection(handles);
|
||||
}
|
||||
}
|
||||
|
||||
$onDidTriggerButton(sessionId: number, handle: number): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session) {
|
||||
session._fireDidTriggerButton(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExtHostQuickInput implements QuickInput {
|
||||
|
||||
private static _nextId = 1;
|
||||
_id = ExtHostQuickPick._nextId++;
|
||||
|
||||
private _visible = false;
|
||||
private _enabled = true;
|
||||
private _busy = false;
|
||||
private _ignoreFocusOut = true;
|
||||
private _buttons: QuickInputButton[] = [];
|
||||
private _handlesToButtons = new Map<number, QuickInputButton>();
|
||||
private _onDidTriggerButtonEmitter = new Emitter<QuickInputButton>();
|
||||
private _onDidHideEmitter = new Emitter<void>();
|
||||
private _updateTimeout: number;
|
||||
private _pendingUpdate: TransferQuickInput = { id: this._id };
|
||||
|
||||
private _disposed = false;
|
||||
protected _disposables: IDisposable[] = [
|
||||
this._onDidTriggerButtonEmitter,
|
||||
this._onDidHideEmitter,
|
||||
];
|
||||
|
||||
constructor(protected _proxy: MainThreadQuickOpenShape, protected _extensionId: string, private _onDidDispose: () => void) {
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
set enabled(enabled: boolean) {
|
||||
this._enabled = enabled;
|
||||
this.update({ enabled });
|
||||
}
|
||||
|
||||
get busy() {
|
||||
return this._busy;
|
||||
}
|
||||
|
||||
set busy(busy: boolean) {
|
||||
this._busy = busy;
|
||||
this.update({ busy });
|
||||
}
|
||||
|
||||
get ignoreFocusOut() {
|
||||
return this._ignoreFocusOut;
|
||||
}
|
||||
|
||||
set ignoreFocusOut(ignoreFocusOut: boolean) {
|
||||
this._ignoreFocusOut = ignoreFocusOut;
|
||||
this.update({ ignoreFocusOut });
|
||||
}
|
||||
|
||||
get buttons() {
|
||||
return this._buttons;
|
||||
}
|
||||
|
||||
set buttons(buttons: QuickInputButton[]) {
|
||||
this._buttons = buttons;
|
||||
this._handlesToButtons.clear();
|
||||
buttons.forEach((button, i) => {
|
||||
this._handlesToButtons.set(i, button);
|
||||
});
|
||||
this.update({
|
||||
buttons: buttons.map<TransferQuickInputButton>((button, i) => ({
|
||||
iconPath: getIconUris(button.iconPath),
|
||||
toolTip: button.tooltip,
|
||||
handle: i,
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
onDidTriggerButton = this._onDidTriggerButtonEmitter.event;
|
||||
|
||||
show(): void {
|
||||
this._visible = true;
|
||||
this.update({ visible: true });
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
this._visible = false;
|
||||
this.update({ visible: false });
|
||||
}
|
||||
|
||||
onDidHide = this._onDidHideEmitter.event;
|
||||
|
||||
_fireDidTriggerButton(handle: number) {
|
||||
const button = this._handlesToButtons.get(handle);
|
||||
this._onDidTriggerButtonEmitter.fire(button);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
this._disposed = true;
|
||||
this._disposables = dispose(this._disposables);
|
||||
if (this._updateTimeout) {
|
||||
clearTimeout(this._updateTimeout);
|
||||
this._updateTimeout = undefined;
|
||||
}
|
||||
this._proxy.$dispose(this._id);
|
||||
this._onDidDispose();
|
||||
}
|
||||
|
||||
protected update(properties: Record<string, any>): void {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
assign(this._pendingUpdate, properties);
|
||||
|
||||
if (!this._visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties.visible) {
|
||||
if (this._updateTimeout) {
|
||||
clearTimeout(this._updateTimeout);
|
||||
this._updateTimeout = undefined;
|
||||
}
|
||||
this.dispatchUpdate();
|
||||
} else if (!this._updateTimeout) {
|
||||
// Defer the update so that multiple changes to setters dont cause a redraw each
|
||||
this._updateTimeout = setTimeout(() => {
|
||||
this._updateTimeout = undefined;
|
||||
this.dispatchUpdate();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private dispatchUpdate() {
|
||||
this._proxy.$createOrUpdate(this._pendingUpdate);
|
||||
this._pendingUpdate = { id: this._id };
|
||||
}
|
||||
}
|
||||
|
||||
function getIconUris(iconPath: QuickInputButton['iconPath']) {
|
||||
const light = getLightIconUri(iconPath);
|
||||
return { dark: getDarkIconUri(iconPath) || light, light };
|
||||
}
|
||||
|
||||
function getLightIconUri(iconPath: QuickInputButton['iconPath']) {
|
||||
if (iconPath && !(iconPath instanceof ThemeIcon)) {
|
||||
if (typeof iconPath === 'string'
|
||||
|| iconPath instanceof URI) {
|
||||
return getIconUri(iconPath);
|
||||
}
|
||||
return getIconUri(iconPath['light']);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getDarkIconUri(iconPath: QuickInputButton['iconPath']) {
|
||||
if (iconPath && !(iconPath instanceof ThemeIcon) && iconPath['dark']) {
|
||||
return getIconUri(iconPath['dark']);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getIconUri(iconPath: string | URI) {
|
||||
if (iconPath instanceof URI) {
|
||||
return iconPath;
|
||||
}
|
||||
return URI.file(iconPath);
|
||||
}
|
||||
|
||||
class ExtHostQuickPick extends ExtHostQuickInput implements QuickPick {
|
||||
|
||||
private _value = '';
|
||||
private _placeholder: string;
|
||||
private _onDidChangeValueEmitter = new Emitter<string>();
|
||||
private _onDidAcceptEmitter = new Emitter<void>();
|
||||
private _items: QuickPickItem[] = [];
|
||||
private _handlesToItems = new Map<number, QuickPickItem>();
|
||||
private _canSelectMany = false;
|
||||
private _matchOnDescription = true;
|
||||
private _matchOnDetail = true;
|
||||
private _focusedItems: QuickPickItem[] = [];
|
||||
private _onDidChangeActiveEmitter = new Emitter<QuickPickItem[]>();
|
||||
private _selectedItems: QuickPickItem[] = [];
|
||||
private _onDidChangeSelectionEmitter = new Emitter<QuickPickItem[]>();
|
||||
|
||||
constructor(proxy: MainThreadQuickOpenShape, extensionId: string, onDispose: () => void) {
|
||||
super(proxy, extensionId, onDispose);
|
||||
this._disposables.push(
|
||||
this._onDidChangeValueEmitter,
|
||||
this._onDidAcceptEmitter,
|
||||
this._onDidChangeActiveEmitter,
|
||||
this._onDidChangeSelectionEmitter,
|
||||
);
|
||||
this.update({ type: 'quickPick' });
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value: string) {
|
||||
this._value = value;
|
||||
this.update({ value });
|
||||
}
|
||||
|
||||
get placeholder() {
|
||||
return this._placeholder;
|
||||
}
|
||||
|
||||
set placeholder(placeholder: string) {
|
||||
this._placeholder = placeholder;
|
||||
this.update({ placeholder });
|
||||
}
|
||||
|
||||
onDidChangeValue = this._onDidChangeValueEmitter.event;
|
||||
|
||||
onDidAccept = this._onDidAcceptEmitter.event;
|
||||
|
||||
get items() {
|
||||
return this._items;
|
||||
}
|
||||
|
||||
set items(items: QuickPickItem[]) {
|
||||
this._items = items;
|
||||
this._handlesToItems.clear();
|
||||
items.forEach((item, i) => {
|
||||
this._handlesToItems.set(i, item);
|
||||
});
|
||||
this.update({
|
||||
items: items.map((item, i) => ({
|
||||
label: item.label,
|
||||
description: item.description,
|
||||
handle: i,
|
||||
detail: item.detail,
|
||||
picked: item.picked
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
get canSelectMany() {
|
||||
return this._canSelectMany;
|
||||
}
|
||||
|
||||
set canSelectMany(canSelectMany: boolean) {
|
||||
this._canSelectMany = canSelectMany;
|
||||
this.update({ canSelectMany });
|
||||
}
|
||||
|
||||
get matchOnDescription() {
|
||||
return this._matchOnDescription;
|
||||
}
|
||||
|
||||
set matchOnDescription(matchOnDescription: boolean) {
|
||||
this._matchOnDescription = matchOnDescription;
|
||||
this.update({ matchOnDescription });
|
||||
}
|
||||
|
||||
get matchOnDetail() {
|
||||
return this._matchOnDetail;
|
||||
}
|
||||
|
||||
set matchOnDetail(matchOnDetail: boolean) {
|
||||
this._matchOnDetail = matchOnDetail;
|
||||
this.update({ matchOnDetail });
|
||||
}
|
||||
|
||||
get activeItems() {
|
||||
return this._focusedItems;
|
||||
}
|
||||
|
||||
onDidChangeActive = this._onDidChangeActiveEmitter.event;
|
||||
|
||||
get selectedItems() {
|
||||
return this._selectedItems;
|
||||
}
|
||||
|
||||
onDidChangeSelection = this._onDidChangeSelectionEmitter.event;
|
||||
|
||||
_fireDidAccept() {
|
||||
this._onDidAcceptEmitter.fire();
|
||||
}
|
||||
|
||||
_fireDidChangeFocus(handles: number[]) {
|
||||
const items = handles.map(handle => this._handlesToItems.get(handle));
|
||||
this._focusedItems = items;
|
||||
this._onDidChangeActiveEmitter.fire(items);
|
||||
}
|
||||
|
||||
_fireDidChangeSelection(handles: number[]) {
|
||||
const items = handles.map(handle => this._handlesToItems.get(handle));
|
||||
this._selectedItems = items;
|
||||
this._onDidChangeSelectionEmitter.fire(items);
|
||||
}
|
||||
}
|
||||
|
||||
class ExtHostInputBox extends ExtHostQuickInput implements InputBox {
|
||||
|
||||
private _value = '';
|
||||
private _placeholder: string;
|
||||
private _password: boolean;
|
||||
private _prompt: string;
|
||||
private _validationMessage: string;
|
||||
private _onDidChangeValueEmitter = new Emitter<string>();
|
||||
private _onDidAcceptEmitter = new Emitter<string>();
|
||||
|
||||
constructor(proxy: MainThreadQuickOpenShape, extensionId: string, onDispose: () => void) {
|
||||
super(proxy, extensionId, onDispose);
|
||||
this._disposables.push(
|
||||
this._onDidChangeValueEmitter,
|
||||
this._onDidAcceptEmitter,
|
||||
);
|
||||
this.update({ type: 'inputBox' });
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value: string) {
|
||||
this._value = value;
|
||||
this.update({ value });
|
||||
}
|
||||
|
||||
get placeholder() {
|
||||
return this._placeholder;
|
||||
}
|
||||
|
||||
set placeholder(placeholder: string) {
|
||||
this._placeholder = placeholder;
|
||||
this.update({ placeholder });
|
||||
}
|
||||
|
||||
get password() {
|
||||
return this._password;
|
||||
}
|
||||
|
||||
set password(password: boolean) {
|
||||
this._password = password;
|
||||
this.update({ password });
|
||||
}
|
||||
|
||||
get prompt() {
|
||||
return this._prompt;
|
||||
}
|
||||
|
||||
set prompt(prompt: string) {
|
||||
this._prompt = prompt;
|
||||
this.update({ prompt });
|
||||
}
|
||||
|
||||
get validationMessage() {
|
||||
return this._validationMessage;
|
||||
}
|
||||
|
||||
set validationMessage(validationMessage: string) {
|
||||
this._validationMessage = validationMessage;
|
||||
this.update({ validationMessage });
|
||||
}
|
||||
|
||||
onDidChangeValue = this._onDidChangeValueEmitter.event;
|
||||
|
||||
onDidAccept = this._onDidAcceptEmitter.event;
|
||||
}
|
||||
@@ -454,7 +454,7 @@ class TextSearchEngine {
|
||||
new TPromise(resolve => process.nextTick(resolve))
|
||||
.then(() => {
|
||||
this.activeCancellationTokens.add(cancellation);
|
||||
return this.provider.provideTextSearchResults(this.pattern, searchOptions, progress, cancellation.token);
|
||||
return this.provider.provideTextSearchResults(patternInfoToQuery(this.pattern), searchOptions, progress, cancellation.token);
|
||||
})
|
||||
.then(() => {
|
||||
this.activeCancellationTokens.delete(cancellation);
|
||||
@@ -500,6 +500,15 @@ class TextSearchEngine {
|
||||
}
|
||||
}
|
||||
|
||||
function patternInfoToQuery(patternInfo: IPatternInfo): vscode.TextSearchQuery {
|
||||
return <vscode.TextSearchQuery>{
|
||||
isCaseSensitive: patternInfo.isCaseSensitive || false,
|
||||
isRegExp: patternInfo.isRegExp || false,
|
||||
isWordMatch: patternInfo.isWordMatch || false,
|
||||
pattern: patternInfo.pattern
|
||||
};
|
||||
}
|
||||
|
||||
class FileSearchEngine {
|
||||
private filePattern: string;
|
||||
private normalizedFilePatternLowercase: string;
|
||||
|
||||
@@ -28,8 +28,6 @@ import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumen
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
export { TaskExecutionDTO };
|
||||
|
||||
/*
|
||||
namespace ProblemPattern {
|
||||
export function from(value: vscode.ProblemPattern | vscode.MultiLineProblemPattern): Problems.ProblemPattern | Problems.MultiLineProblemPattern {
|
||||
@@ -234,13 +232,14 @@ namespace TaskPanelKind {
|
||||
namespace PresentationOptions {
|
||||
export function from(value: vscode.TaskPresentationOptions): tasks.PresentationOptions {
|
||||
if (value === void 0 || value === null) {
|
||||
return { reveal: tasks.RevealKind.Always, echo: true, focus: false, panel: tasks.PanelKind.Shared };
|
||||
return { reveal: tasks.RevealKind.Always, echo: true, focus: false, panel: tasks.PanelKind.Shared, showReuseMessage: true };
|
||||
}
|
||||
return {
|
||||
reveal: TaskRevealKind.from(value.reveal),
|
||||
echo: value.echo === void 0 ? true : !!value.echo,
|
||||
focus: !!value.focus,
|
||||
panel: TaskPanelKind.from(value.panel)
|
||||
panel: TaskPanelKind.from(value.panel),
|
||||
showReuseMessage: value.showReuseMessage === void 0 ? true : !!value.showReuseMessage
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -385,21 +384,16 @@ namespace Tasks {
|
||||
// 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 tasks.ExtensionTaskSourceTransfer).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined;
|
||||
(source as any as tasks.ExtensionTaskSourceTransfer).__definition = task.definition;
|
||||
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: tasks.TaskIdentifier = {
|
||||
_key: key,
|
||||
type: kind.type
|
||||
};
|
||||
Objects.assign(taskKind, kind);
|
||||
// The definition id will be prefix on the main side since we compute it there.
|
||||
let id = `${extension.id}`;
|
||||
let result: tasks.ContributedTask = {
|
||||
_id: id, // uuidMap.getUUID(identifier),
|
||||
_id: id,
|
||||
_source: source,
|
||||
_label: label,
|
||||
type: kind.type,
|
||||
defines: taskKind,
|
||||
type: task.definition.type,
|
||||
defines: undefined,
|
||||
name: task.name,
|
||||
identifier: label,
|
||||
group: task.group ? (task.group as types.TaskGroup).id : undefined,
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as types from './extHostTypes';
|
||||
import * as search from 'vs/workbench/parts/search/common/search';
|
||||
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';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { ProgressLocation as MainProgressLocation } from 'vs/workbench/services/progress/common/progress';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
@@ -355,16 +356,16 @@ export namespace SymbolKind {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace SymbolInformation {
|
||||
export function from(info: vscode.SymbolInformation): modes.SymbolInformation {
|
||||
return <modes.SymbolInformation>{
|
||||
export namespace WorkspaceSymbol {
|
||||
export function from(info: vscode.SymbolInformation): search.IWorkspaceSymbol {
|
||||
return <search.IWorkspaceSymbol>{
|
||||
name: info.name,
|
||||
kind: SymbolKind.from(info.kind),
|
||||
containerName: info.containerName,
|
||||
location: location.from(info.location)
|
||||
};
|
||||
}
|
||||
export function to(info: modes.SymbolInformation): types.SymbolInformation {
|
||||
export function to(info: search.IWorkspaceSymbol): types.SymbolInformation {
|
||||
return new types.SymbolInformation(
|
||||
info.name,
|
||||
SymbolKind.to(info.kind),
|
||||
@@ -374,31 +375,30 @@ export namespace SymbolInformation {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace HierarchicalSymbolInformation {
|
||||
export function from(info: vscode.Hierarchy<vscode.SymbolInformation2>): modes.SymbolInformation {
|
||||
let result: modes.SymbolInformation = {
|
||||
name: info.parent.name,
|
||||
detail: info.parent.detail,
|
||||
location: location.from(info.parent.location),
|
||||
definingRange: Range.from(info.parent.range),
|
||||
kind: SymbolKind.from(info.parent.kind),
|
||||
containerName: info.parent.containerName
|
||||
export namespace DocumentSymbol {
|
||||
export function from(info: vscode.DocumentSymbol): modes.DocumentSymbol {
|
||||
let result: modes.DocumentSymbol = {
|
||||
name: info.name,
|
||||
detail: info.detail,
|
||||
fullRange: Range.from(info.fullRange),
|
||||
identifierRange: Range.from(info.gotoRange),
|
||||
kind: SymbolKind.from(info.kind)
|
||||
};
|
||||
if (info.children) {
|
||||
result.children = info.children.map(from);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export function to(info: modes.SymbolInformation): types.Hierarchy<vscode.SymbolInformation2> {
|
||||
let result = new types.Hierarchy<vscode.SymbolInformation2>(new types.SymbolInformation2(
|
||||
export function to(info: modes.DocumentSymbol): vscode.DocumentSymbol {
|
||||
let result = new types.DocumentSymbol(
|
||||
info.name,
|
||||
info.detail,
|
||||
SymbolKind.to(info.kind),
|
||||
Range.to(info.definingRange),
|
||||
location.to(info.location),
|
||||
));
|
||||
Range.to(info.fullRange),
|
||||
Range.to(info.identifierRange),
|
||||
);
|
||||
if (info.children) {
|
||||
result.children = info.children.map(to);
|
||||
result.children = info.children.map(to) as any;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -881,28 +881,29 @@ export class SymbolInformation {
|
||||
}
|
||||
}
|
||||
|
||||
export class SymbolInformation2 extends SymbolInformation {
|
||||
|
||||
export class DocumentSymbol {
|
||||
name: string;
|
||||
detail: string;
|
||||
range: Range;
|
||||
kind: SymbolKind;
|
||||
fullRange: Range;
|
||||
gotoRange: Range;
|
||||
children: DocumentSymbol[];
|
||||
|
||||
constructor(name: string, detail: string, kind: SymbolKind, range: Range, location: Location) {
|
||||
super(name, kind, undefined, location);
|
||||
constructor(name: string, detail: string, kind: SymbolKind, fullRange: Range, gotoRange: Range) {
|
||||
this.name = name;
|
||||
this.detail = detail;
|
||||
this.range = range;
|
||||
}
|
||||
}
|
||||
|
||||
export class Hierarchy<T> {
|
||||
parent: T;
|
||||
children: Hierarchy<T>[];
|
||||
|
||||
constructor(parent: T) {
|
||||
this.parent = parent;
|
||||
this.kind = kind;
|
||||
this.fullRange = fullRange;
|
||||
this.gotoRange = gotoRange;
|
||||
this.children = [];
|
||||
|
||||
if (!this.fullRange.contains(this.gotoRange)) {
|
||||
throw new Error('gotoRange must be contained in fullRange');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export enum CodeActionTrigger {
|
||||
Automatic = 1,
|
||||
Manual = 2,
|
||||
@@ -1494,7 +1495,6 @@ export class Task implements vscode.Task {
|
||||
private __id: string;
|
||||
|
||||
private _definition: vscode.TaskDefinition;
|
||||
private _definitionKey: string;
|
||||
private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder;
|
||||
private _name: string;
|
||||
private _execution: ProcessExecution | ShellExecution;
|
||||
@@ -1555,7 +1555,6 @@ export class Task implements vscode.Task {
|
||||
}
|
||||
this.__id = undefined;
|
||||
this._scope = undefined;
|
||||
this._definitionKey = undefined;
|
||||
this._definition = undefined;
|
||||
if (this._execution instanceof ProcessExecution) {
|
||||
this._definition = {
|
||||
@@ -1579,19 +1578,9 @@ export class Task implements vscode.Task {
|
||||
throw illegalArgument('Kind can\'t be undefined or null');
|
||||
}
|
||||
this.clear();
|
||||
this._definitionKey = undefined;
|
||||
this._definition = value;
|
||||
}
|
||||
|
||||
get definitionKey(): string {
|
||||
if (!this._definitionKey) {
|
||||
const hash = crypto.createHash('md5');
|
||||
hash.update(JSON.stringify(this._definition));
|
||||
this._definitionKey = hash.digest('hex');
|
||||
}
|
||||
return this._definitionKey;
|
||||
}
|
||||
|
||||
get scope(): vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder {
|
||||
return this._scope;
|
||||
}
|
||||
@@ -1845,12 +1834,6 @@ export enum LogLevel {
|
||||
}
|
||||
|
||||
//#region file api
|
||||
// todo@remote
|
||||
export enum DeprecatedFileChangeType {
|
||||
Updated = 0,
|
||||
Added = 1,
|
||||
Deleted = 2
|
||||
}
|
||||
|
||||
export enum FileChangeType {
|
||||
Changed = 1,
|
||||
@@ -1858,12 +1841,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 {
|
||||
@@ -1928,3 +1905,15 @@ export enum FoldingRangeKind {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
export enum CommentThreadCollapsibleState {
|
||||
/**
|
||||
* Determines an item is collapsed
|
||||
*/
|
||||
Collapsed = 0,
|
||||
/**
|
||||
* Determines an item is expanded
|
||||
*/
|
||||
Expanded = 1
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface TaskPresentationOptionsDTO {
|
||||
echo?: boolean;
|
||||
focus?: boolean;
|
||||
panel?: number;
|
||||
showReuseMessage?: boolean;
|
||||
}
|
||||
|
||||
export interface ExecutionOptionsDTO {
|
||||
|
||||
Reference in New Issue
Block a user