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 {
|
||||
public readonly _onDidClientConnect = new Emitter<ClientConnectionEvent>();
|
||||
public readonly onDidClientConnect = this._onDidClientConnect.event;
|
||||
@ -461,6 +470,8 @@ export class MainServer extends Server {
|
||||
private _proxyServer?: Promise<net.Server>;
|
||||
private readonly proxyTimeout = 5000;
|
||||
|
||||
private settings: Settings = {};
|
||||
|
||||
public constructor(options: ServerOptions, args: ParsedArgs) {
|
||||
super(options);
|
||||
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> {
|
||||
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"),
|
||||
this.getFirstValidPath([
|
||||
{ path: parsedUrl.query.workspace, workspace: true },
|
||||
{ path: parsedUrl.query.folder },
|
||||
(await this.readSettings()).lastVisited,
|
||||
{ path: this.options.folderUri }
|
||||
]),
|
||||
this.servicesPromise,
|
||||
]);
|
||||
|
||||
if (startPath) {
|
||||
this.writeSettings({
|
||||
lastVisited: {
|
||||
path: startPath.uri.fsPath,
|
||||
workspace: startPath.workspace
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const logger = this.services.get(ILogService) as ILogService;
|
||||
logger.info("request.url", `"${request.url}"`);
|
||||
|
||||
const cwd = process.env.VSCODE_CWD || process.cwd();
|
||||
|
||||
const remoteAuthority = request.headers.host as string;
|
||||
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 options: Options = {
|
||||
WORKBENCH_WEB_CONGIGURATION: {
|
||||
workspaceUri: await validatePath(parsedUrl.query.workspace, false),
|
||||
folderUri: !parsedUrl.query.workspace ? await validatePath(parsedUrl.query.folder, true, this.options.folderUri) : undefined,
|
||||
workspaceUri: startPath && startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
|
||||
folderUri: startPath && !startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
|
||||
remoteAuthority,
|
||||
productConfiguration: product,
|
||||
},
|
||||
@ -581,6 +585,34 @@ export class MainServer extends Server {
|
||||
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> {
|
||||
if (product.commit && message.commit !== 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 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