remote - allow to open files from user home with tilde syntax (#83213)

This commit is contained in:
Benjamin Pasero 2020-01-14 10:15:58 +01:00
parent 2d1e215598
commit 5dfa261ced
5 changed files with 34 additions and 36 deletions

View file

@ -21,7 +21,6 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import * as nls from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILabelService } from 'vs/platform/label/common/label';
@ -121,11 +120,10 @@ export class OpenFileHandler extends QuickOpenHandler {
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@ISearchService private readonly searchService: ISearchService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IRemotePathService private readonly remotePathService: IRemotePathService,
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
@IFileService private readonly fileService: IFileService,
@ILabelService private readonly labelService: ILabelService,
@IRemotePathService private readonly remotePathService: IRemotePathService,
@ILabelService private readonly labelService: ILabelService
) {
super();
@ -187,11 +185,12 @@ export class OpenFileHandler extends QuickOpenHandler {
}
private async getAbsolutePathResult(query: IPreparedQuery): Promise<URI | undefined> {
const detildifiedQuery = untildify(query.original, this.environmentService.userHome);
const detildifiedQuery = untildify(query.original, (await this.remotePathService.userHome).path);
if ((await this.remotePathService.path).isAbsolute(detildifiedQuery)) {
const resource = toLocalResource(
await this.remotePathService.fileURI(detildifiedQuery),
this.workbenchEnvironmentService.configuration.remoteAuthority);
this.workbenchEnvironmentService.configuration.remoteAuthority
);
try {
const stat = await this.fileService.resolve(resource);

View file

@ -70,7 +70,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
import { RunAutomaticTasks } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
import { format } from 'vs/base/common/jsonFormatter';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { applyEdits } from 'vs/base/common/jsonEdit';
@ -256,7 +256,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@ITerminalInstanceService private readonly terminalInstanceService: ITerminalInstanceService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IRemotePathService private readonly remotePathService: IRemotePathService,
@ITextModelService private readonly textModelResolverService: ITextModelService,
@IPreferencesService private readonly preferencesService: IPreferencesService
) {
@ -1316,7 +1316,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
this.modelService, this.configurationResolverService, this.telemetryService,
this.contextService, this.environmentService,
AbstractTaskService.OutputChannelId, this.fileService, this.terminalInstanceService,
this.remoteAgentService,
this.remotePathService,
(workspaceFolder: IWorkspaceFolder) => {
if (!workspaceFolder) {
return undefined;

View file

@ -43,7 +43,7 @@ import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { Schemas } from 'vs/base/common/network';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
import { env as processEnv, cwd as processCwd } from 'vs/base/common/process';
interface TerminalData {
@ -176,7 +176,7 @@ export class TerminalTaskSystem implements ITaskSystem {
private outputChannelId: string,
private fileService: IFileService,
private terminalInstanceService: ITerminalInstanceService,
private remoteAgentService: IRemoteAgentService,
private remotePathService: IRemotePathService,
taskSystemInfoResolver: TaskSystemInfoResolver,
) {
@ -829,14 +829,6 @@ export class TerminalTaskSystem implements ITaskSystem {
return nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', needsFolderQualification ? task.getQualifiedLabel() : task.configurationProperties.name);
}
private async getUserHome(): Promise<URI> {
const env = await this.remoteAgentService.getEnvironment();
if (env) {
return env.userHome;
}
return URI.from({ scheme: Schemas.file, path: this.environmentService.userHome });
}
private async createShellLaunchConfig(task: CustomTask | ContributedTask, workspaceFolder: IWorkspaceFolder | undefined, variableResolver: VariableResolver, platform: Platform.Platform, options: CommandOptions, command: CommandString, args: CommandString[], waitOnExit: boolean | string): Promise<IShellLaunchConfig | undefined> {
let shellLaunchConfig: IShellLaunchConfig;
let isShellCommand = task.command.runtime === RuntimeType.Shell;
@ -867,7 +859,7 @@ export class TerminalTaskSystem implements ITaskSystem {
windowsShellArgs = true;
let basename = path.basename(shellLaunchConfig.executable!).toLowerCase();
// If we don't have a cwd, then the terminal uses the home dir.
const userHome = await this.getUserHome();
const userHome = await this.remotePathService.userHome;
if (basename === 'cmd.exe' && ((options.cwd && isUNC(options.cwd)) || (!options.cwd && isUNC(userHome.fsPath)))) {
return undefined;
}

View file

@ -35,6 +35,7 @@ import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { normalizeDriveLetter } from 'vs/base/common/labels';
import { SaveReason } from 'vs/workbench/common/editor';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
export namespace OpenLocalFileCommand {
export const ID = 'workbench.action.files.openLocalFile';
@ -134,6 +135,7 @@ export class SimpleFileDialog {
@IModeService private readonly modeService: IModeService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IRemotePathService private readonly remotePathService: IRemotePathService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
@ -154,8 +156,8 @@ export class SimpleFileDialog {
public async showOpenDialog(options: IOpenDialogOptions = {}): Promise<URI | undefined> {
this.scheme = this.getScheme(options.availableFileSystems, options.defaultUri);
this.userHome = await this.getUserHome();
const newOptions = await this.getOptions(options);
this.userHome = await this.remotePathService.userHome;
const newOptions = this.getOptions(options);
if (!newOptions) {
return Promise.resolve(undefined);
}
@ -165,9 +167,9 @@ export class SimpleFileDialog {
public async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {
this.scheme = this.getScheme(options.availableFileSystems, options.defaultUri);
this.userHome = await this.getUserHome();
this.userHome = await this.remotePathService.userHome;
this.requiresTrailing = true;
const newOptions = await this.getOptions(options, true);
const newOptions = this.getOptions(options, true);
if (!newOptions) {
return Promise.resolve(undefined);
}
@ -229,16 +231,6 @@ export class SimpleFileDialog {
return this.remoteAgentEnvironment;
}
private async getUserHome(): Promise<URI> {
if (this.scheme !== Schemas.file) {
const env = await this.getRemoteAgentEnvironment();
if (env) {
return env.userHome;
}
}
return URI.from({ scheme: this.scheme, path: this.environmentService.userHome });
}
private async pickResource(isSave: boolean = false): Promise<URI | undefined> {
this.allowFolderSelection = !!this.options.canSelectFolders;
this.allowFileSelection = !!this.options.canSelectFiles;

View file

@ -9,6 +9,8 @@ import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { Schemas } from 'vs/base/common/network';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
const REMOTE_PATH_SERVICE_ID = 'remotePath';
export const IRemotePathService = createDecorator<IRemotePathService>(REMOTE_PATH_SERVICE_ID);
@ -16,8 +18,10 @@ export const IRemotePathService = createDecorator<IRemotePathService>(REMOTE_PAT
export interface IRemotePathService {
_serviceBrand: undefined;
path: Promise<path.IPath>;
readonly path: Promise<path.IPath>;
fileURI(path: string): Promise<URI>;
readonly userHome: Promise<URI>;
}
/**
@ -29,7 +33,8 @@ export class RemotePathService implements IRemotePathService {
private _extHostOS: Promise<platform.OperatingSystem>;
constructor(
@IRemoteAgentService readonly remoteAgentService: IRemoteAgentService
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
this._extHostOS = remoteAgentService.getEnvironment().then(remoteEnvironment => {
return remoteEnvironment ? remoteEnvironment.os : platform.OS;
@ -76,6 +81,16 @@ export class RemotePathService implements IRemotePathService {
fragment: ''
});
}
get userHome(): Promise<URI> {
return this.remoteAgentService.getEnvironment().then(env => {
if (env) {
return env.userHome;
}
return URI.from({ scheme: Schemas.file, path: this.environmentService.userHome });
});
}
}
registerSingleton(IRemotePathService, RemotePathService, true);