mirror of https://github.com/coder/code-server.git
Clean up client API
- Don't use "any" for the API type. - Remove everything from the Coder API that can eventually be done through the VS Code API. - Move the event emission to our own client to minimize patching.
This commit is contained in:
parent
0315b004a7
commit
62719ab544
|
@ -573,34 +573,27 @@ index 5a758eb786..7fcacb5ca7 100644
|
||||||
templateData.actionBar.context = (<TreeViewItemHandleArg>{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle });
|
templateData.actionBar.context = (<TreeViewItemHandleArg>{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle });
|
||||||
templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false });
|
templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false });
|
||||||
diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts
|
diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts
|
||||||
index 1986fb6642..a3e4cbdb56 100644
|
index 1986fb6642..453d3e3e48 100644
|
||||||
--- a/src/vs/workbench/browser/web.main.ts
|
--- a/src/vs/workbench/browser/web.main.ts
|
||||||
+++ b/src/vs/workbench/browser/web.main.ts
|
+++ b/src/vs/workbench/browser/web.main.ts
|
||||||
@@ -35,6 +35,7 @@ import { SignService } from 'vs/platform/sign/browser/signService';
|
@@ -35,6 +35,7 @@ import { SignService } from 'vs/platform/sign/browser/signService';
|
||||||
import { hash } from 'vs/base/common/hash';
|
import { hash } from 'vs/base/common/hash';
|
||||||
import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
|
import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
|
||||||
import { ProductService } from 'vs/platform/product/browser/productService';
|
import { ProductService } from 'vs/platform/product/browser/productService';
|
||||||
+import { coderApi, vscodeApi } from 'vs/server/src/api';
|
+import { initialize } from 'vs/server/src/client';
|
||||||
|
|
||||||
class CodeRendererMain extends Disposable {
|
class CodeRendererMain extends Disposable {
|
||||||
|
|
||||||
@@ -71,6 +72,15 @@ class CodeRendererMain extends Disposable {
|
@@ -71,6 +72,8 @@ class CodeRendererMain extends Disposable {
|
||||||
|
|
||||||
// Startup
|
// Startup
|
||||||
this.workbench.startup();
|
this.workbench.startup();
|
||||||
+
|
+
|
||||||
+ const target = window as any;
|
+ initialize(services.serviceCollection);
|
||||||
+ target.ide = coderApi(services.serviceCollection);
|
|
||||||
+ target.vscode = vscodeApi(services.serviceCollection);
|
|
||||||
+
|
|
||||||
+ const event = new CustomEvent('ide-ready');
|
|
||||||
+ (event as any).ide = target.ide;
|
|
||||||
+ (event as any).vscode = target.vscode;
|
|
||||||
+ window.dispatchEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initServices(): Promise<{ serviceCollection: ServiceCollection, logService: ILogService }> {
|
private async initServices(): Promise<{ serviceCollection: ServiceCollection, logService: ILogService }> {
|
||||||
@@ -114,7 +124,8 @@ class CodeRendererMain extends Disposable {
|
@@ -114,7 +117,8 @@ class CodeRendererMain extends Disposable {
|
||||||
const channel = connection.getChannel<IChannel>(REMOTE_FILE_SYSTEM_CHANNEL_NAME);
|
const channel = connection.getChannel<IChannel>(REMOTE_FILE_SYSTEM_CHANNEL_NAME);
|
||||||
const remoteFileSystemProvider = this._register(new RemoteExtensionsFileSystemProvider(channel, remoteAgentService.getEnvironment()));
|
const remoteFileSystemProvider = this._register(new RemoteExtensionsFileSystemProvider(channel, remoteAgentService.getEnvironment()));
|
||||||
|
|
||||||
|
@ -1422,7 +1415,7 @@ index 306d58f915..58c603ad3d 100644
|
||||||
if (definition.fontCharacter || definition.fontColor) {
|
if (definition.fontCharacter || definition.fontColor) {
|
||||||
let body = '';
|
let body = '';
|
||||||
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
|
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
|
||||||
index c28adc0ad9..3d1adba3d9 100644
|
index c28adc0ad9..4517c308da 100644
|
||||||
--- a/src/vs/workbench/workbench.web.main.ts
|
--- a/src/vs/workbench/workbench.web.main.ts
|
||||||
+++ b/src/vs/workbench/workbench.web.main.ts
|
+++ b/src/vs/workbench/workbench.web.main.ts
|
||||||
@@ -128,7 +128,7 @@ import 'vs/workbench/services/extensions/browser/extensionService';
|
@@ -128,7 +128,7 @@ import 'vs/workbench/services/extensions/browser/extensionService';
|
||||||
|
@ -1447,9 +1440,3 @@ index c28adc0ad9..3d1adba3d9 100644
|
||||||
|
|
||||||
// Output Panel
|
// Output Panel
|
||||||
import 'vs/workbench/contrib/output/browser/output.contribution';
|
import 'vs/workbench/contrib/output/browser/output.contribution';
|
||||||
@@ -356,3 +356,5 @@ import 'vs/workbench/contrib/outline/browser/outline.contribution';
|
|
||||||
// import 'vs/workbench/contrib/issue/electron-browser/issue.contribution';
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
+
|
|
||||||
+import 'vs/server/src/client';
|
|
||||||
|
|
240
src/api.ts
240
src/api.ts
|
@ -1,25 +1,19 @@
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
|
|
||||||
import { localize } from "vs/nls";
|
import { localize } from "vs/nls";
|
||||||
import { Action } from "vs/base/common/actions";
|
import { SyncActionDescriptor } from "vs/platform/actions/common/actions";
|
||||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from "vs/platform/actions/common/actions";
|
|
||||||
import { Registry } from "vs/platform/registry/common/platform";
|
import { Registry } from "vs/platform/registry/common/platform";
|
||||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions} from "vs/workbench/common/actions";
|
import { IWorkbenchActionRegistry, Extensions as ActionExtensions} from "vs/workbench/common/actions";
|
||||||
import { CommandsRegistry, ICommandService } from "vs/platform/commands/common/commands";
|
import { CommandsRegistry, ICommandService } from "vs/platform/commands/common/commands";
|
||||||
import { IStat, IWatchOptions, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions, IFileChange, FileWriteOptions, FileSystemProviderCapabilities, IFileService, FileType, FileOperation, IFileSystemProvider } from "vs/platform/files/common/files";
|
import { IStat, IWatchOptions, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions, IFileChange, FileWriteOptions, FileSystemProviderCapabilities, IFileService, FileType, IFileSystemProvider } from "vs/platform/files/common/files";
|
||||||
import { ITextFileService } from "vs/workbench/services/textfile/common/textfiles";
|
|
||||||
import { IModelService } from "vs/editor/common/services/modelService";
|
|
||||||
import { ITerminalService } from "vs/workbench/contrib/terminal/common/terminal";
|
|
||||||
import { IStorageService } from "vs/platform/storage/common/storage";
|
import { IStorageService } from "vs/platform/storage/common/storage";
|
||||||
import { ServiceCollection } from "vs/platform/instantiation/common/serviceCollection";
|
import { ServiceCollection } from "vs/platform/instantiation/common/serviceCollection";
|
||||||
import { INotificationService } from "vs/platform/notification/common/notification";
|
import { INotificationService } from "vs/platform/notification/common/notification";
|
||||||
import { IStatusbarService, StatusbarAlignment } from "vs/platform/statusbar/common/statusbar";
|
|
||||||
import Severity from "vs/base/common/severity";
|
|
||||||
import { Emitter, Event } from "vs/base/common/event";
|
import { Emitter, Event } from "vs/base/common/event";
|
||||||
import * as extHostTypes from "vs/workbench/api/common/extHostTypes";
|
import * as extHostTypes from "vs/workbench/api/common/extHostTypes";
|
||||||
import { ServiceIdentifier, IInstantiationService } from "vs/platform/instantiation/common/instantiation";
|
import { ServiceIdentifier, IInstantiationService } from "vs/platform/instantiation/common/instantiation";
|
||||||
import { URI } from "vs/base/common/uri";
|
import { URI } from "vs/base/common/uri";
|
||||||
import { ITreeViewDataProvider, IViewsRegistry, ITreeViewDescriptor, Extensions as ViewsExtensions, IViewContainersRegistry } from "vs/workbench/common/views";
|
import { ITreeItem, ITreeViewDataProvider, IViewsRegistry, ITreeViewDescriptor, Extensions as ViewsExtensions, IViewContainersRegistry, TreeItemCollapsibleState } from "vs/workbench/common/views";
|
||||||
import { CustomTreeViewPanel, CustomTreeView } from "vs/workbench/browser/parts/views/customView";
|
import { CustomTreeViewPanel, CustomTreeView } from "vs/workbench/browser/parts/views/customView";
|
||||||
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ShowViewletAction } from "vs/workbench/browser/viewlet";
|
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ShowViewletAction } from "vs/workbench/browser/viewlet";
|
||||||
import { IExtensionService } from "vs/workbench/services/extensions/common/extensions";
|
import { IExtensionService } from "vs/workbench/services/extensions/common/extensions";
|
||||||
|
@ -35,6 +29,7 @@ import { IViewletService } from "vs/workbench/services/viewlet/browser/viewlet";
|
||||||
import { IEditorGroupsService } from "vs/workbench/services/editor/common/editorGroupsService";
|
import { IEditorGroupsService } from "vs/workbench/services/editor/common/editorGroupsService";
|
||||||
import { createCSSRule } from "vs/base/browser/dom";
|
import { createCSSRule } from "vs/base/browser/dom";
|
||||||
import { IDisposable } from "vs/base/common/lifecycle";
|
import { IDisposable } from "vs/base/common/lifecycle";
|
||||||
|
import { generateUuid } from "vs/base/common/uuid";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client-side implementation of VS Code's API.
|
* Client-side implementation of VS Code's API.
|
||||||
|
@ -42,7 +37,7 @@ import { IDisposable } from "vs/base/common/lifecycle";
|
||||||
* TODO: Implement menu items for views (for item actions).
|
* TODO: Implement menu items for views (for item actions).
|
||||||
* TODO: File system provider doesn't work.
|
* TODO: File system provider doesn't work.
|
||||||
*/
|
*/
|
||||||
export const vscodeApi = (serviceCollection: ServiceCollection): typeof vscode => {
|
export const vscodeApi = (serviceCollection: ServiceCollection): Partial<typeof vscode> => {
|
||||||
const getService = <T>(id: ServiceIdentifier<T>): T => serviceCollection.get<T>(id) as T;
|
const getService = <T>(id: ServiceIdentifier<T>): T => serviceCollection.get<T>(id) as T;
|
||||||
const commandService = getService(ICommandService);
|
const commandService = getService(ICommandService);
|
||||||
const notificationService = getService(INotificationService);
|
const notificationService = getService(INotificationService);
|
||||||
|
@ -61,149 +56,84 @@ export const vscodeApi = (serviceCollection: ServiceCollection): typeof vscode =
|
||||||
FileType: FileType,
|
FileType: FileType,
|
||||||
Uri: URI,
|
Uri: URI,
|
||||||
commands: {
|
commands: {
|
||||||
executeCommand: (commandId: string, ...args: any[]): any => {
|
executeCommand: <T = any>(commandId: string, ...args: any[]): Promise<T | undefined> => {
|
||||||
return commandService.executeCommand(commandId, ...args);
|
return commandService.executeCommand(commandId, ...args);
|
||||||
},
|
},
|
||||||
registerCommand: (id: string, command: () => void): any => {
|
registerCommand: (id: string, command: (...args: any[]) => any): IDisposable => {
|
||||||
return CommandsRegistry.registerCommand(id, command);
|
return CommandsRegistry.registerCommand(id, command);
|
||||||
},
|
},
|
||||||
},
|
} as Partial<typeof vscode.commands>,
|
||||||
window: {
|
window: {
|
||||||
registerTreeDataProvider: (id: string, dataProvider: ITreeViewDataProvider): void => {
|
registerTreeDataProvider: <T>(id: string, dataProvider: vscode.TreeDataProvider<T>): IDisposable => {
|
||||||
|
const tree = new TreeViewDataProvider(dataProvider);
|
||||||
const view = viewsRegistry.getView(id);
|
const view = viewsRegistry.getView(id);
|
||||||
if (view) {
|
(view as ITreeViewDescriptor).treeView.dataProvider = tree;
|
||||||
(view as ITreeViewDescriptor).treeView.dataProvider = dataProvider;
|
return {
|
||||||
}
|
dispose: () => tree.dispose(),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
showErrorMessage: (message: string): void => {
|
showErrorMessage: async (message: string): Promise<string | undefined> => {
|
||||||
notificationService.error(message);
|
notificationService.error(message);
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
},
|
} as Partial<typeof vscode.window>,
|
||||||
workspace: {
|
workspace: {
|
||||||
registerFileSystemProvider: (scheme: string, provider: vscode.FileSystemProvider): IDisposable => {
|
registerFileSystemProvider: (scheme: string, provider: vscode.FileSystemProvider): IDisposable => {
|
||||||
return fileService.registerProvider(scheme, new FileSystemProvider(provider));
|
return fileService.registerProvider(scheme, new FileSystemProvider(provider));
|
||||||
},
|
},
|
||||||
},
|
} as Partial<typeof vscode.workspace>,
|
||||||
} as any;
|
} as Partial<typeof vscode>; // Without this it complains that the type isn't `| undefined`.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coder API.
|
* Coder API. This should only provide functionality that can't be made
|
||||||
|
* available through the VS Code API.
|
||||||
*/
|
*/
|
||||||
export const coderApi = (serviceCollection: ServiceCollection): typeof coder => {
|
export const coderApi = (serviceCollection: ServiceCollection): typeof coder => {
|
||||||
const getService = <T>(id: ServiceIdentifier<T>): T => serviceCollection.get<T>(id) as T;
|
const getService = <T>(id: ServiceIdentifier<T>): T => serviceCollection.get<T>(id) as T;
|
||||||
return {
|
return {
|
||||||
workbench: {
|
registerView: (viewId, viewName, containerId, containerName, icon): void => {
|
||||||
action: Action,
|
const cssClass = `extensionViewlet-${containerId}`;
|
||||||
syncActionDescriptor: SyncActionDescriptor,
|
const id = `workbench.view.extension.${containerId}`;
|
||||||
commandRegistry: CommandsRegistry,
|
class CustomViewlet extends ViewContainerViewlet {
|
||||||
actionsRegistry: Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions),
|
public constructor(
|
||||||
registerView: (viewId, viewName, containerId, containerName, icon): void => {
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
const cssClass = `extensionViewlet-${containerId}`;
|
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||||
const id = `workbench.view.extension.${containerId}`;
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
class CustomViewlet extends ViewContainerViewlet {
|
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||||
public constructor(
|
@IStorageService storageService: IStorageService,
|
||||||
@IConfigurationService configurationService: IConfigurationService,
|
@IEditorService _editorService: IEditorService,
|
||||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
@IInstantiationService instantiationService: IInstantiationService,
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@IThemeService themeService: IThemeService,
|
||||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
@IContextMenuService contextMenuService: IContextMenuService,
|
||||||
@IStorageService storageService: IStorageService,
|
@IExtensionService extensionService: IExtensionService,
|
||||||
@IEditorService _editorService: IEditorService,
|
) {
|
||||||
@IInstantiationService instantiationService: IInstantiationService,
|
super(id, `${id}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||||
@IThemeService themeService: IThemeService,
|
|
||||||
@IContextMenuService contextMenuService: IContextMenuService,
|
|
||||||
@IExtensionService extensionService: IExtensionService,
|
|
||||||
) {
|
|
||||||
super(id, `${id}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(
|
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(
|
||||||
new ViewletDescriptor(CustomViewlet as any, id, containerName, cssClass, undefined, URI.parse(icon)),
|
new ViewletDescriptor(CustomViewlet as any, id, containerName, cssClass, undefined, URI.parse(icon)),
|
||||||
);
|
);
|
||||||
|
|
||||||
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions).registerWorkbenchAction(
|
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions).registerWorkbenchAction(
|
||||||
new SyncActionDescriptor(OpenCustomViewletAction as any, id, localize("showViewlet", "Show {0}", containerName)),
|
new SyncActionDescriptor(OpenCustomViewletAction as any, id, localize("showViewlet", "Show {0}", containerName)),
|
||||||
"View: Show {0}",
|
"View: Show {0}",
|
||||||
localize("view", "View"),
|
localize("view", "View"),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate CSS to show the icon in the activity bar.
|
// Generate CSS to show the icon in the activity bar.
|
||||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`;
|
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`;
|
||||||
createCSSRule(iconClass, `-webkit-mask: url('${icon}') no-repeat 50% 50%`);
|
createCSSRule(iconClass, `-webkit-mask: url('${icon}') no-repeat 50% 50%`);
|
||||||
|
|
||||||
const container = Registry.as<IViewContainersRegistry>(ViewsExtensions.ViewContainersRegistry).registerViewContainer(containerId);
|
const container = Registry.as<IViewContainersRegistry>(ViewsExtensions.ViewContainersRegistry).registerViewContainer(containerId);
|
||||||
Registry.as<IViewsRegistry>(ViewsExtensions.ViewsRegistry).registerViews([{
|
Registry.as<IViewsRegistry>(ViewsExtensions.ViewsRegistry).registerViews([{
|
||||||
id: viewId,
|
id: viewId,
|
||||||
name: viewName,
|
name: viewName,
|
||||||
ctorDescriptor: { ctor: CustomTreeViewPanel },
|
ctorDescriptor: { ctor: CustomTreeViewPanel },
|
||||||
treeView: getService(IInstantiationService).createInstance(CustomTreeView as any, viewId, container),
|
treeView: getService(IInstantiationService).createInstance(CustomTreeView as any, viewId, container),
|
||||||
}] as ITreeViewDescriptor[], container);
|
}] as ITreeViewDescriptor[], container);
|
||||||
},
|
|
||||||
menuRegistry: MenuRegistry as any,
|
|
||||||
statusbarService: getService(IStatusbarService) as any,
|
|
||||||
notificationService: getService(INotificationService),
|
|
||||||
terminalService: getService(ITerminalService),
|
|
||||||
onFileCreate: (cb): void => {
|
|
||||||
getService<IFileService>(IFileService).onAfterOperation((e) => {
|
|
||||||
if (e.operation === FileOperation.CREATE) {
|
|
||||||
cb(e.resource.path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFileMove: (cb): void => {
|
|
||||||
getService<IFileService>(IFileService).onAfterOperation((e) => {
|
|
||||||
if (e.operation === FileOperation.MOVE) {
|
|
||||||
cb(e.resource.path, e.target ? e.target.resource.path : undefined!);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFileDelete: (cb): void => {
|
|
||||||
getService<IFileService>(IFileService).onAfterOperation((e) => {
|
|
||||||
if (e.operation === FileOperation.DELETE) {
|
|
||||||
cb(e.resource.path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFileSaved: (cb): void => {
|
|
||||||
getService<ITextFileService>(ITextFileService).models.onModelSaved((e) => {
|
|
||||||
cb(e.resource.path);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFileCopy: (cb): void => {
|
|
||||||
getService<IFileService>(IFileService).onAfterOperation((e) => {
|
|
||||||
if (e.operation === FileOperation.COPY) {
|
|
||||||
cb(e.resource.path, e.target ? e.target.resource.path : undefined!);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onModelAdded: (cb): void => {
|
|
||||||
getService<IModelService>(IModelService).onModelAdded((e) => {
|
|
||||||
cb(e.uri.path, e.getLanguageIdentifier().language);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onModelRemoved: (cb): void => {
|
|
||||||
getService<IModelService>(IModelService).onModelRemoved((e) => {
|
|
||||||
cb(e.uri.path, e.getLanguageIdentifier().language);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onModelLanguageChange: (cb): void => {
|
|
||||||
getService<IModelService>(IModelService).onModelModeChanged((e) => {
|
|
||||||
cb(e.model.uri.path, e.model.getLanguageIdentifier().language, e.oldModeId);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onTerminalAdded: (cb): void => {
|
|
||||||
getService<ITerminalService>(ITerminalService).onInstanceCreated(() => cb());
|
|
||||||
},
|
|
||||||
onTerminalRemoved: (cb): void => {
|
|
||||||
getService<ITerminalService>(ITerminalService).onInstanceDisposed(() => cb());
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// @ts-ignore
|
|
||||||
MenuId: MenuId,
|
|
||||||
Severity: Severity,
|
|
||||||
// @ts-ignore
|
|
||||||
StatusbarAlignment: StatusbarAlignment,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,3 +212,59 @@ class FileSystemProvider implements IFileSystemProvider {
|
||||||
throw new Error("not implemented");
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TreeViewDataProvider<T> implements ITreeViewDataProvider {
|
||||||
|
private readonly root = Symbol("root");
|
||||||
|
private readonly values = new Map<string, T>();
|
||||||
|
private readonly children = new Map<T | Symbol, ITreeItem[]>();
|
||||||
|
|
||||||
|
public constructor(private readonly provider: vscode.TreeDataProvider<T>) {}
|
||||||
|
|
||||||
|
public async getChildren(item?: ITreeItem): Promise<ITreeItem[]> {
|
||||||
|
const value = item && this.itemToValue(item);
|
||||||
|
const children = await Promise.all(
|
||||||
|
(await this.provider.getChildren(value) || [])
|
||||||
|
.map(async (childValue) => {
|
||||||
|
const treeItem = await this.provider.getTreeItem(childValue);
|
||||||
|
const handle = this.createHandle(treeItem);
|
||||||
|
this.values.set(handle, childValue);
|
||||||
|
return {
|
||||||
|
handle,
|
||||||
|
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.clear(value || this.root, item);
|
||||||
|
this.children.set(value || this.root, children);
|
||||||
|
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
private itemToValue(item: ITreeItem): T {
|
||||||
|
if (!this.values.has(item.handle)) {
|
||||||
|
throw new Error(`No element found with handle ${item.handle}`);
|
||||||
|
}
|
||||||
|
return this.values.get(item.handle)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private clear(value: T | Symbol, item?: ITreeItem): void {
|
||||||
|
if (this.children.has(value)) {
|
||||||
|
this.children.get(value)!.map((c) => this.clear(this.itemToValue(c), c));
|
||||||
|
this.children.delete(value);
|
||||||
|
}
|
||||||
|
if (item) {
|
||||||
|
this.values.delete(item.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createHandle(item: vscode.TreeItem): string {
|
||||||
|
return item.id
|
||||||
|
? `coder-tree-item-id/${item.id}`
|
||||||
|
: `coder-tree-item-uuid/${generateUuid()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1,18 @@
|
||||||
import 'vs/css!./media/firefox';
|
import { coderApi, vscodeApi } from "vs/server/src/api";
|
||||||
|
import "vs/css!./media/firefox";
|
||||||
|
import { ServiceCollection } from "vs/platform/instantiation/common/serviceCollection";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called by vs/workbench/browser/web.main.ts after the workbench has
|
||||||
|
* been initialized so we can initialize our own client-side code.
|
||||||
|
*/
|
||||||
|
export const initialize = (services: ServiceCollection): void => {
|
||||||
|
const target = window as any;
|
||||||
|
target.ide = coderApi(services);
|
||||||
|
target.vscode = vscodeApi(services);
|
||||||
|
|
||||||
|
const event = new CustomEvent('ide-ready');
|
||||||
|
(event as any).ide = target.ide;
|
||||||
|
(event as any).vscode = target.vscode;
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
};
|
||||||
|
|
|
@ -1,210 +1,3 @@
|
||||||
declare namespace coder {
|
declare namespace coder {
|
||||||
export interface IDisposable {
|
export const registerView: (viewId: string, viewName: string, containerId: string, containerName: string, icon: string) => void;
|
||||||
dispose(): void;
|
|
||||||
}
|
|
||||||
export interface Disposer extends IDisposable {
|
|
||||||
onDidDispose: (cb: () => void) => void;
|
|
||||||
}
|
|
||||||
export interface Event<T> {
|
|
||||||
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStatusbarEntry {
|
|
||||||
readonly text: string;
|
|
||||||
readonly tooltip?: string;
|
|
||||||
readonly color?: string;
|
|
||||||
readonly command?: string;
|
|
||||||
readonly arguments?: any[];
|
|
||||||
readonly showBeak?: boolean;
|
|
||||||
}
|
|
||||||
export interface IStatusbarService {
|
|
||||||
addEntry(entry: IStatusbarEntry, alignment: StatusbarAlignment, priority?: number): IDisposable;
|
|
||||||
setStatusMessage(message: string, autoDisposeAfter?: number, delayBy?: number): IDisposable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAction extends IDisposable {
|
|
||||||
id: string;
|
|
||||||
label: string;
|
|
||||||
tooltip: string;
|
|
||||||
class: string | undefined;
|
|
||||||
enabled: boolean;
|
|
||||||
checked: boolean;
|
|
||||||
radio: boolean;
|
|
||||||
run(event?: any): Promise<any>;
|
|
||||||
}
|
|
||||||
export type NotificationMessage = string | Error;
|
|
||||||
export interface INotificationProperties {
|
|
||||||
sticky?: boolean;
|
|
||||||
silent?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotificationActions {
|
|
||||||
primary?: IAction[];
|
|
||||||
secondary?: IAction[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotificationProgress {
|
|
||||||
infinite(): void;
|
|
||||||
total(value: number): void;
|
|
||||||
worked(value: number): void;
|
|
||||||
done(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPromptChoice {
|
|
||||||
label: string;
|
|
||||||
isSecondary?: boolean;
|
|
||||||
keepOpen?: boolean;
|
|
||||||
run: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPromptOptions extends INotificationProperties {
|
|
||||||
onCancel?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISerializableCommandAction extends IBaseCommandAction {
|
|
||||||
// iconLocation?: { dark: UriComponents; light?: UriComponents; };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMenuItem {
|
|
||||||
command: ICommandAction;
|
|
||||||
alt?: ICommandAction;
|
|
||||||
// when?: ContextKeyExpr;
|
|
||||||
group?: "navigation" | string;
|
|
||||||
order?: number;
|
|
||||||
}
|
|
||||||
export interface IMenuRegistry {
|
|
||||||
appendMenuItem(menu: MenuId, item: IMenuItem): IDisposable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBaseCommandAction {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
category?: string;
|
|
||||||
}
|
|
||||||
export interface ICommandAction extends IBaseCommandAction {
|
|
||||||
// iconLocation?: { dark: URI; light?: URI; };
|
|
||||||
// precondition?: ContextKeyExpr;
|
|
||||||
// toggled?: ContextKeyExpr;
|
|
||||||
}
|
|
||||||
export interface ICommandHandler {
|
|
||||||
(accessor: any, ...args: any[]): void;
|
|
||||||
}
|
|
||||||
export interface ICommand {
|
|
||||||
id: string;
|
|
||||||
handler: ICommandHandler;
|
|
||||||
description?: ICommandHandlerDescription | null;
|
|
||||||
}
|
|
||||||
export interface ICommandHandlerDescription {
|
|
||||||
description: string;
|
|
||||||
args: { name: string; description?: string; }[];
|
|
||||||
returns?: string;
|
|
||||||
}
|
|
||||||
export interface ICommandRegistry {
|
|
||||||
registerCommand(command: ICommand): IDisposable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotification extends INotificationProperties {
|
|
||||||
severity: Severity;
|
|
||||||
message: NotificationMessage;
|
|
||||||
source?: string;
|
|
||||||
actions?: INotificationActions;
|
|
||||||
}
|
|
||||||
export interface INotificationHandle {
|
|
||||||
readonly onDidClose: Event<void>;
|
|
||||||
readonly progress: INotificationProgress;
|
|
||||||
updateSeverity(severity: Severity): void;
|
|
||||||
updateMessage(message: NotificationMessage): void;
|
|
||||||
updateActions(actions?: INotificationActions): void;
|
|
||||||
close(): void;
|
|
||||||
}
|
|
||||||
export interface INotificationService {
|
|
||||||
notify(notification: INotification): INotificationHandle;
|
|
||||||
info(message: NotificationMessage | NotificationMessage[]): void;
|
|
||||||
warn(message: NotificationMessage | NotificationMessage[]): void;
|
|
||||||
error(message: NotificationMessage | NotificationMessage[]): void;
|
|
||||||
prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace client {}
|
|
||||||
|
|
||||||
export namespace workbench {
|
|
||||||
// TODO: these types won't actually be included in the package if we try to
|
|
||||||
// import them. We'll need to recreate them.
|
|
||||||
export const action: any; // import { Action } from "vs/base/common/actions";
|
|
||||||
export const syncActionDescriptor: any; // import { SyncActionDescriptor } from "vs/platform/actions/common/actions";
|
|
||||||
export const statusbarService: IStatusbarService;
|
|
||||||
export const actionsRegistry: any; // import { IWorkbenchActionRegistry } from "vs/workbench/common/actions";
|
|
||||||
export const notificationService: INotificationService;
|
|
||||||
export const menuRegistry: IMenuRegistry;
|
|
||||||
export const commandRegistry: ICommandRegistry;
|
|
||||||
export const terminalService: any; // import { ITerminalService } from "vs/workbench/contrib/terminal/common/terminal";
|
|
||||||
|
|
||||||
export const registerView: (viewId: string, viewName: string, containerId: string, containerName: string, icon: string) => void;
|
|
||||||
|
|
||||||
export const onFileCreate: (cb: (path: string) => void) => void;
|
|
||||||
export const onFileMove: (cb: (path: string, target: string) => void) => void;
|
|
||||||
export const onFileDelete: (cb: (path: string) => void) => void;
|
|
||||||
export const onFileSaved: (cb: (path: string) => void) => void;
|
|
||||||
export const onFileCopy: (cb: (path: string, target: string) => void) => void;
|
|
||||||
|
|
||||||
export const onModelAdded: (cb: (path: string, languageId: string) => void) => void;
|
|
||||||
export const onModelRemoved: (cb: (path: string, languageId: string) => void) => void;
|
|
||||||
export const onModelLanguageChange: (cb: (path: string, languageId: string, oldLanguageId: string) => void) => void;
|
|
||||||
|
|
||||||
export const onTerminalAdded: (cb: () => void) => void;
|
|
||||||
export const onTerminalRemoved: (cb: () => void) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Severity {
|
|
||||||
Ignore = 0,
|
|
||||||
Info = 1,
|
|
||||||
Warning = 2,
|
|
||||||
Error = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum StatusbarAlignment {
|
|
||||||
LEFT, RIGHT,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum MenuId {
|
|
||||||
CommandPalette,
|
|
||||||
DebugBreakpointsContext,
|
|
||||||
DebugCallStackContext,
|
|
||||||
DebugConsoleContext,
|
|
||||||
DebugVariablesContext,
|
|
||||||
DebugWatchContext,
|
|
||||||
DebugToolBar,
|
|
||||||
EditorContext,
|
|
||||||
EditorTitle,
|
|
||||||
EditorTitleContext,
|
|
||||||
EmptyEditorGroupContext,
|
|
||||||
ExplorerContext,
|
|
||||||
MenubarAppearanceMenu,
|
|
||||||
MenubarDebugMenu,
|
|
||||||
MenubarEditMenu,
|
|
||||||
MenubarFileMenu,
|
|
||||||
MenubarGoMenu,
|
|
||||||
MenubarHelpMenu,
|
|
||||||
MenubarLayoutMenu,
|
|
||||||
MenubarNewBreakpointMenu,
|
|
||||||
MenubarPreferencesMenu,
|
|
||||||
MenubarRecentMenu,
|
|
||||||
MenubarSelectionMenu,
|
|
||||||
MenubarSwitchEditorMenu,
|
|
||||||
MenubarSwitchGroupMenu,
|
|
||||||
MenubarTerminalMenu,
|
|
||||||
MenubarViewMenu,
|
|
||||||
OpenEditorsContext,
|
|
||||||
ProblemsPanelContext,
|
|
||||||
SCMChangeContext,
|
|
||||||
SCMResourceContext,
|
|
||||||
SCMResourceGroupContext,
|
|
||||||
SCMSourceControl,
|
|
||||||
SCMTitle,
|
|
||||||
SearchContext,
|
|
||||||
StatusBarWindowIndicatorMenu,
|
|
||||||
TouchBarContext,
|
|
||||||
ViewItemContext,
|
|
||||||
ViewTitle,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue