Remember last workspace or directory
This commit is contained in:
parent
ae43e2016f
commit
4ae2c81157
@ -445,6 +445,15 @@ export abstract class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface StartPath {
|
||||||
|
path?: string[] | string;
|
||||||
|
workspace?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings {
|
||||||
|
lastVisited?: StartPath;
|
||||||
|
}
|
||||||
|
|
||||||
export class MainServer extends Server {
|
export class MainServer extends Server {
|
||||||
public readonly _onDidClientConnect = new Emitter<ClientConnectionEvent>();
|
public readonly _onDidClientConnect = new Emitter<ClientConnectionEvent>();
|
||||||
public readonly onDidClientConnect = this._onDidClientConnect.event;
|
public readonly onDidClientConnect = this._onDidClientConnect.event;
|
||||||
@ -461,6 +470,8 @@ export class MainServer extends Server {
|
|||||||
private _proxyServer?: Promise<net.Server>;
|
private _proxyServer?: Promise<net.Server>;
|
||||||
private readonly proxyTimeout = 5000;
|
private readonly proxyTimeout = 5000;
|
||||||
|
|
||||||
|
private settings: Settings = {};
|
||||||
|
|
||||||
public constructor(options: ServerOptions, args: ParsedArgs) {
|
public constructor(options: ServerOptions, args: ParsedArgs) {
|
||||||
super(options);
|
super(options);
|
||||||
this.servicesPromise = this.initializeServices(args);
|
this.servicesPromise = this.initializeServices(args);
|
||||||
@ -528,44 +539,37 @@ export class MainServer extends Server {
|
|||||||
|
|
||||||
private async getRoot(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise<Response> {
|
private async getRoot(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise<Response> {
|
||||||
const filePath = path.join(this.rootPath, "out/vs/code/browser/workbench/workbench.html");
|
const filePath = path.join(this.rootPath, "out/vs/code/browser/workbench/workbench.html");
|
||||||
let [content] = await Promise.all([
|
let [content, startPath] = await Promise.all([
|
||||||
util.promisify(fs.readFile)(filePath, "utf8"),
|
util.promisify(fs.readFile)(filePath, "utf8"),
|
||||||
|
this.getFirstValidPath([
|
||||||
|
{ path: parsedUrl.query.workspace, workspace: true },
|
||||||
|
{ path: parsedUrl.query.folder },
|
||||||
|
(await this.readSettings()).lastVisited,
|
||||||
|
{ path: this.options.folderUri }
|
||||||
|
]),
|
||||||
this.servicesPromise,
|
this.servicesPromise,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if (startPath) {
|
||||||
|
this.writeSettings({
|
||||||
|
lastVisited: {
|
||||||
|
path: startPath.uri.fsPath,
|
||||||
|
workspace: startPath.workspace
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const logger = this.services.get(ILogService) as ILogService;
|
const logger = this.services.get(ILogService) as ILogService;
|
||||||
logger.info("request.url", `"${request.url}"`);
|
logger.info("request.url", `"${request.url}"`);
|
||||||
|
|
||||||
const cwd = process.env.VSCODE_CWD || process.cwd();
|
|
||||||
|
|
||||||
const remoteAuthority = request.headers.host as string;
|
const remoteAuthority = request.headers.host as string;
|
||||||
const transformer = getUriTransformer(remoteAuthority);
|
const transformer = getUriTransformer(remoteAuthority);
|
||||||
const validatePath = async (filePath: string[] | string | undefined, isDirectory: boolean, unsetFallback?: string): Promise<UriComponents | undefined> => {
|
|
||||||
if (!filePath || filePath.length === 0) {
|
|
||||||
if (!unsetFallback) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
filePath = unsetFallback;
|
|
||||||
} else if (Array.isArray(filePath)) {
|
|
||||||
filePath = filePath[0];
|
|
||||||
}
|
|
||||||
const uri = URI.file(sanitizeFilePath(filePath, cwd));
|
|
||||||
try {
|
|
||||||
const stat = await util.promisify(fs.stat)(uri.fsPath);
|
|
||||||
if (isDirectory !== stat.isDirectory()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return transformer.transformOutgoing(uri);
|
|
||||||
};
|
|
||||||
|
|
||||||
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
|
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
|
||||||
const options: Options = {
|
const options: Options = {
|
||||||
WORKBENCH_WEB_CONGIGURATION: {
|
WORKBENCH_WEB_CONGIGURATION: {
|
||||||
workspaceUri: await validatePath(parsedUrl.query.workspace, false),
|
workspaceUri: startPath && startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
|
||||||
folderUri: !parsedUrl.query.workspace ? await validatePath(parsedUrl.query.folder, true, this.options.folderUri) : undefined,
|
folderUri: startPath && !startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
|
||||||
remoteAuthority,
|
remoteAuthority,
|
||||||
productConfiguration: product,
|
productConfiguration: product,
|
||||||
},
|
},
|
||||||
@ -581,6 +585,34 @@ export class MainServer extends Server {
|
|||||||
return { content, filePath };
|
return { content, filePath };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose the first valid path.
|
||||||
|
*/
|
||||||
|
private async getFirstValidPath(startPaths: Array<StartPath | undefined>): Promise<{ uri: URI, workspace?: boolean} | undefined> {
|
||||||
|
const logger = this.services.get(ILogService) as ILogService;
|
||||||
|
const cwd = process.env.VSCODE_CWD || process.cwd();
|
||||||
|
for (let i = 0; i < startPaths.length; ++i) {
|
||||||
|
const startPath = startPaths[i];
|
||||||
|
if (!startPath) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const paths = typeof startPath.path === "string" ? [startPath.path] : (startPath.path || []);
|
||||||
|
for (let j = 0; j < paths.length; ++j) {
|
||||||
|
const uri = URI.file(sanitizeFilePath(paths[j], cwd));
|
||||||
|
try {
|
||||||
|
const stat = await util.promisify(fs.stat)(uri.fsPath);
|
||||||
|
// Workspace must be a file.
|
||||||
|
if (!!startPath.workspace !== stat.isDirectory()) {
|
||||||
|
return { uri, workspace: startPath.workspace };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private async connect(message: ConnectionTypeRequest, protocol: Protocol): Promise<void> {
|
private async connect(message: ConnectionTypeRequest, protocol: Protocol): Promise<void> {
|
||||||
if (product.commit && message.commit !== product.commit) {
|
if (product.commit && message.commit !== product.commit) {
|
||||||
throw new Error(`Version mismatch (${message.commit} instead of ${product.commit})`);
|
throw new Error(`Version mismatch (${message.commit} instead of ${product.commit})`);
|
||||||
@ -810,4 +842,41 @@ export class MainServer extends Server {
|
|||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file path for Coder settings.
|
||||||
|
*/
|
||||||
|
private get settingsPath(): string {
|
||||||
|
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
|
||||||
|
return path.join(environment.userDataPath, "coder.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read settings from the file. On a failure return last known settings and
|
||||||
|
* log a warning.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private async readSettings(): Promise<Settings> {
|
||||||
|
try {
|
||||||
|
const raw = (await util.promisify(fs.readFile)(this.settingsPath, "utf8")).trim();
|
||||||
|
this.settings = raw ? JSON.parse(raw) : {};
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== "ENOENT") {
|
||||||
|
(this.services.get(ILogService) as ILogService).warn(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write settings combined with current settings. On failure log a warning.
|
||||||
|
*/
|
||||||
|
private async writeSettings(newSettings: Partial<Settings>): Promise<void> {
|
||||||
|
this.settings = { ...this.settings, ...newSettings };
|
||||||
|
try {
|
||||||
|
await util.promisify(fs.writeFile)(this.settingsPath, JSON.stringify(this.settings));
|
||||||
|
} catch (error) {
|
||||||
|
(this.services.get(ILogService) as ILogService).warn(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user