Skip to content

Commit

Permalink
Remote: still use settings and configuration from the local user dir
Browse files Browse the repository at this point in the history
Signed-off-by: Jonah Iden <[email protected]>
  • Loading branch information
jonah-iden committed Nov 28, 2024
1 parent 99f24f5 commit cf0fb9a
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@theia/core": "1.55.0",
"@theia/filesystem": "1.55.0",
"@theia/userstorage": "1.55.0",
"archiver": "^5.3.1",
"decompress": "^4.2.1",
"decompress-tar": "^4.0.0",
Expand Down
31 changes: 31 additions & 0 deletions packages/remote/src/electron-browser/local-backend-services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// *****************************************************************************
// Copyright (C) 2024 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { RpcProxy } from '@theia/core';
import { inject, injectable } from '@theia/core/shared/inversify';
import { RemoteFileSystemProvider, RemoteFileSystemServer } from '@theia/filesystem/lib/common/remote-file-system-provider';

export const LocalEnvVariablesServer = Symbol('LocalEnviromentVariableServer');
export const LocalRemoteFileSytemServer = Symbol('LocalRemoteFileSytemServer');

/**
* provide file access to local files while connected to a remote workspace or dev container.
*/
@injectable()
export class LocalRemoteFileSystemProvider extends RemoteFileSystemProvider {
@inject(LocalRemoteFileSytemServer)
protected override readonly server: RpcProxy<RemoteFileSystemServer>;
}
20 changes: 20 additions & 0 deletions packages/remote/src/electron-browser/remote-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ import { PortForwardingService } from './port-forwarding/port-forwarding-service
import { RemotePortForwardingProvider, RemoteRemotePortForwardingProviderPath } from '../electron-common/remote-port-forwarding-provider';
import { ServiceConnectionProvider } from '@theia/core/lib/browser/messaging/service-connection-provider';
import '../../src/electron-browser/style/port-forwarding-widget.css';
import { UserStorageContribution } from '@theia/userstorage/lib/browser/user-storage-contribution';
import { RemoteUserStorageContribution } from './remote-user-storage-provider';
import { remoteFileSystemPath, RemoteFileSystemProxyFactory, RemoteFileSystemServer } from '@theia/filesystem/lib/common/remote-file-system-provider';
import { LocalEnvVariablesServer, LocalRemoteFileSystemProvider, LocalRemoteFileSytemServer } from './local-backend-services';
import { envVariablesPath, EnvVariablesServer } from '@theia/core/lib/common/env-variables';

export default new ContainerModule((bind, _, __, rebind) => {
bind(RemoteFrontendContribution).toSelf().inSingletonScope();
Expand Down Expand Up @@ -65,4 +70,19 @@ export default new ContainerModule((bind, _, __, rebind) => {
bind(RemotePortForwardingProvider).toDynamicValue(ctx =>
ServiceConnectionProvider.createLocalProxy<RemotePortForwardingProvider>(ctx.container, RemoteRemotePortForwardingProviderPath)).inSingletonScope();

bind(LocalRemoteFileSytemServer).toDynamicValue(ctx =>
isRemoteConnection() ?
ServiceConnectionProvider.createLocalProxy(ctx.container, remoteFileSystemPath, new RemoteFileSystemProxyFactory()) :
ctx.container.get(RemoteFileSystemServer));
bind(LocalEnvVariablesServer).toDynamicValue(ctx =>
isRemoteConnection() ?
ServiceConnectionProvider.createLocalProxy<EnvVariablesServer>(ctx.container, envVariablesPath) :
ctx.container.get(EnvVariablesServer));
bind(LocalRemoteFileSystemProvider).toSelf().inSingletonScope();
rebind(UserStorageContribution).to(RemoteUserStorageContribution);

});

function isRemoteConnection(): boolean {
return !!new URLSearchParams(window.location.search).get('localPort');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// *****************************************************************************
// Copyright (C) 2024 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { FileSystemProvider } from '@theia/filesystem/lib/common/files';
import { UserStorageContribution } from '@theia/userstorage/lib/browser/user-storage-contribution';
import { RemoteStatusService } from '../electron-common/remote-status-service';
import { LocalEnvVariablesServer, LocalRemoteFileSystemProvider } from './local-backend-services';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { URI } from '@theia/core';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';

/**
* This overide is to have remote connections still use settings, keymaps, etc. from the local machine.
*/
@injectable()
export class RemoteUserStorageContribution extends UserStorageContribution {
@inject(RemoteStatusService)
protected readonly remoteStatusService: RemoteStatusService;

@inject(LocalRemoteFileSystemProvider)
protected readonly localRemoteFileSystemProvider: LocalRemoteFileSystemProvider;

@inject(LocalEnvVariablesServer)
protected readonly localEnvironments: EnvVariablesServer;

isRemoteConnection: Deferred<boolean> = new Deferred();

@postConstruct()
protected init(): void {
const port = new URLSearchParams(location.search).get('port');
if (port) {
this.remoteStatusService.getStatus(Number(port)).then(status => this.isRemoteConnection.resolve(status.alive));
}
}

protected override async getDelegate(service: FileService): Promise<FileSystemProvider> {
return await this.isRemoteConnection.promise ?
this.localRemoteFileSystemProvider
: service.activateProvider('file');
}

protected override async getCongigDirUri(): Promise<URI> {
return await this.isRemoteConnection.promise ?
new URI(await this.localEnvironments.getConfigDirUri())
: super.getCongigDirUri();
}

}
3 changes: 3 additions & 0 deletions packages/remote/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
},
{
"path": "../filesystem"
},
{
"path": "../userstorage"
}
]
}
13 changes: 11 additions & 2 deletions packages/userstorage/src/browser/user-storage-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { FileSystemProvider } from '@theia/filesystem/lib/common/files';
import { FileService, FileServiceContribution } from '@theia/filesystem/lib/browser/file-service';
import { DelegatingFileSystemProvider } from '@theia/filesystem/lib/common/delegating-file-system-provider';
import { UserStorageUri } from './user-storage-uri';
import { MaybePromise } from '@theia/core';

@injectable()
export class UserStorageContribution implements FileServiceContribution {
Expand All @@ -40,9 +41,17 @@ export class UserStorageContribution implements FileServiceContribution {
});
}

protected getDelegate(service: FileService): MaybePromise<FileSystemProvider> {
return service.activateProvider('file');
}

protected async getCongigDirUri(): Promise<URI> {
return new URI(await this.environments.getConfigDirUri());
}

protected async createProvider(service: FileService): Promise<FileSystemProvider> {
const delegate = await service.activateProvider('file');
const configDirUri = new URI(await this.environments.getConfigDirUri());
const delegate = await this.getDelegate(service);
const configDirUri = await this.getCongigDirUri();
return new DelegatingFileSystemProvider(delegate, {
uriConverter: {
to: resource => {
Expand Down

0 comments on commit cf0fb9a

Please sign in to comment.