Set platform based on server (#32)
* Set platform based on server Had to refactor a bit to ensure our values get set before VS Code tries to use them. * Pave the way for mnemonics on all platforms * Fix context menus on Mac * Fix a bunch of things on Mac including menu bar * Set keybindings based on client's OS
This commit is contained in:
204
packages/vscode/src/workbench.ts
Normal file
204
packages/vscode/src/workbench.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
import * as os from "os";
|
||||
import { IProgress, INotificationHandle } from "@coder/ide";
|
||||
import { client } from "./client";
|
||||
|
||||
import "./fill/platform";
|
||||
import "./fill/dom";
|
||||
import "./fill/codeEditor";
|
||||
import "./fill/environmentService";
|
||||
import "./fill/labels";
|
||||
import "./fill/menuRegistry";
|
||||
import "./fill/mouseEvent";
|
||||
import "./fill/storageDatabase";
|
||||
import "./fill/vscodeTextmate";
|
||||
import "./fill/windowsService";
|
||||
import "./fill/workbenchRegistry";
|
||||
import "./fill/workspacesService";
|
||||
import * as paths from "./fill/paths";
|
||||
import { PasteAction } from "./fill/paste";
|
||||
|
||||
import { ExplorerItem, ExplorerModel } from "vs/workbench/parts/files/common/explorerModel";
|
||||
import { IEditorGroup } from "vs/workbench/services/group/common/editorGroupsService";
|
||||
import { IEditorService, IResourceEditor } from "vs/workbench/services/editor/common/editorService";
|
||||
import { INotificationService } from "vs/platform/notification/common/notification";
|
||||
import { IProgressService2, ProgressLocation } from "vs/platform/progress/common/progress";
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
|
||||
import { IWindowsService, IWindowConfiguration } from "vs/platform/windows/common/windows";
|
||||
import { LogLevel } from "vs/platform/log/common/log";
|
||||
import { RawContextKey, IContextKeyService } from "vs/platform/contextkey/common/contextkey";
|
||||
import { ServiceCollection } from "vs/platform/instantiation/common/serviceCollection";
|
||||
import { URI } from "vs/base/common/uri";
|
||||
|
||||
import "vs/loader";
|
||||
|
||||
export class Workbench {
|
||||
private readonly windowId = parseInt(new Date().toISOString().replace(/[-:.TZ]/g, ""), 10);
|
||||
private _serviceCollection: ServiceCollection | undefined;
|
||||
private _clipboardContextKey: RawContextKey<boolean> | undefined;
|
||||
|
||||
public async handleExternalDrop(target: ExplorerItem | ExplorerModel, originalEvent: DragEvent): Promise<void> {
|
||||
await client.upload.uploadDropped(
|
||||
originalEvent,
|
||||
(target instanceof ExplorerItem ? target : target.roots[0]).resource,
|
||||
);
|
||||
}
|
||||
|
||||
public handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup, afterDrop: (targetGroup: IEditorGroup) => void, targetIndex?: number): void {
|
||||
client.upload.uploadDropped(event, URI.file(paths.getWorkingDirectory())).then((paths) => {
|
||||
const uris = paths.map((p) => URI.file(p));
|
||||
if (uris.length) {
|
||||
(this.serviceCollection.get(IWindowsService) as IWindowsService).addRecentlyOpened(uris);
|
||||
}
|
||||
|
||||
const editors: IResourceEditor[] = uris.map(uri => ({
|
||||
resource: uri,
|
||||
options: {
|
||||
pinned: true,
|
||||
index: targetIndex,
|
||||
},
|
||||
}));
|
||||
|
||||
const targetGroup = resolveTargetGroup();
|
||||
|
||||
(this.serviceCollection.get(IEditorService) as IEditorService).openEditors(editors, targetGroup).then(() => {
|
||||
afterDrop(targetGroup);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to toggle the paste option inside editors based on the native clipboard.
|
||||
*/
|
||||
public get clipboardContextKey(): RawContextKey<boolean> {
|
||||
if (!this._clipboardContextKey) {
|
||||
throw new Error("Trying to access clipboard context key before it has been set");
|
||||
}
|
||||
|
||||
return this._clipboardContextKey;
|
||||
}
|
||||
|
||||
public get clipboardText(): Promise<string> {
|
||||
return client.clipboard.readText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a paste action for use in text inputs.
|
||||
*/
|
||||
public get pasteAction(): PasteAction {
|
||||
return new PasteAction();
|
||||
}
|
||||
|
||||
public set workspace(ws: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined) {
|
||||
if (typeof ws === "undefined") {
|
||||
window.localStorage.removeItem("workspace");
|
||||
} else {
|
||||
window.localStorage.setItem("workspace", JSON.stringify(ws));
|
||||
}
|
||||
|
||||
location.reload();
|
||||
}
|
||||
|
||||
public get workspace(): undefined | IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier {
|
||||
const ws = window.localStorage.getItem("workspace");
|
||||
try {
|
||||
return JSON.parse(ws!);
|
||||
} catch (ex) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public get serviceCollection(): ServiceCollection {
|
||||
if (!this._serviceCollection) {
|
||||
throw new Error("Trying to access service collection before it has been set");
|
||||
}
|
||||
|
||||
return this._serviceCollection;
|
||||
}
|
||||
|
||||
public set serviceCollection(collection: ServiceCollection) {
|
||||
this._serviceCollection = collection;
|
||||
client.progressService = {
|
||||
start: <T>(title: string, task: (progress: IProgress) => Promise<T>, onCancel: () => void): Promise<T> => {
|
||||
let lastProgress = 0;
|
||||
|
||||
return (this.serviceCollection.get(IProgressService2) as IProgressService2).withProgress({
|
||||
location: ProgressLocation.Notification,
|
||||
title,
|
||||
cancellable: true,
|
||||
}, (progress) => {
|
||||
return task({
|
||||
report: (p): void => {
|
||||
progress.report({ increment: p - lastProgress });
|
||||
lastProgress = p;
|
||||
},
|
||||
});
|
||||
}, () => {
|
||||
onCancel();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
client.notificationService = {
|
||||
error: (error: Error): void => (this.serviceCollection.get(INotificationService) as INotificationService).error(error),
|
||||
prompt: (severity, message, buttons, onCancel): INotificationHandle => {
|
||||
const handle = (this.serviceCollection.get(INotificationService) as INotificationService).prompt(
|
||||
severity, message, buttons, { onCancel },
|
||||
);
|
||||
|
||||
return {
|
||||
close: (): void => handle.close(),
|
||||
updateMessage: (message): void => handle.updateMessage(message),
|
||||
updateButtons: (buttons): void => handle.updateActions({
|
||||
primary: buttons.map((button) => ({
|
||||
id: "",
|
||||
label: button.label,
|
||||
tooltip: "",
|
||||
class: undefined,
|
||||
enabled: true,
|
||||
checked: false,
|
||||
radio: false,
|
||||
dispose: (): void => undefined,
|
||||
run: (): Promise<void> => Promise.resolve(button.run()),
|
||||
})),
|
||||
}),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
this._clipboardContextKey = new RawContextKey("nativeClipboard", client.clipboard.isEnabled);
|
||||
|
||||
const workspace = this.workspace || URI.file(paths.getWorkingDirectory());
|
||||
// If we try to import this above, workbench will be undefined due to
|
||||
// circular imports.
|
||||
require("vs/workbench/workbench.main");
|
||||
const { startup } = require("vs/workbench/electron-browser/main");
|
||||
const config: IWindowConfiguration = {
|
||||
machineId: "1",
|
||||
windowId: this.windowId,
|
||||
logLevel: LogLevel.Info,
|
||||
mainPid: 1,
|
||||
appRoot: paths.getDefaultUserDataPath(),
|
||||
execPath: os.tmpdir(),
|
||||
userEnv: {},
|
||||
nodeCachedDataDir: os.tmpdir(),
|
||||
perfEntries: [],
|
||||
_: [],
|
||||
};
|
||||
if ((workspace as IWorkspaceIdentifier).configPath) {
|
||||
config.workspace = workspace as IWorkspaceIdentifier;
|
||||
} else {
|
||||
config.folderUri = workspace as URI;
|
||||
}
|
||||
await startup(config);
|
||||
const contextKeys = this.serviceCollection.get(IContextKeyService) as IContextKeyService;
|
||||
const bounded = this.clipboardContextKey.bindTo(contextKeys);
|
||||
client.clipboard.onPermissionChange((enabled) => {
|
||||
bounded.set(enabled);
|
||||
});
|
||||
client.clipboard.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
export const workbench = new Workbench();
|
||||
Reference in New Issue
Block a user