提交 0c9dd09e 编写于 作者: A Alex Ross

Fix file picker backtracking when holding delete key

Fixes https://github.com/Microsoft/vscode-remote-release/issues/4
上级 a579bb36
......@@ -22,11 +22,11 @@ import { Schemas } from 'vs/base/common/network';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys';
import { equalsIgnoreCase, format } from 'vs/base/common/strings';
import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/strings';
import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
import { RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys';
interface FileQuickPickItem extends IQuickPickItem {
uri: URI;
......@@ -63,6 +63,7 @@ export class RemoteFileDialog {
private userHome: URI;
private badPath: string | undefined;
private remoteAgentEnvironment: IRemoteAgentEnvironment | null;
private separator: string;
constructor(
@IFileService private readonly fileService: IFileService,
......@@ -159,6 +160,7 @@ export class RemoteFileDialog {
private async pickResource(isSave: boolean = false): Promise<URI | undefined> {
this.allowFolderSelection = !!this.options.canSelectFolders;
this.allowFileSelection = !!this.options.canSelectFiles;
this.separator = this.labelService.getSeparator(this.scheme, this.remoteAuthority);
this.hidden = false;
let homedir: URI = this.options.defaultUri ? this.options.defaultUri : this.workspaceContextService.getWorkspace().folders[0].uri;
let stat: IFileStat | undefined;
......@@ -306,7 +308,7 @@ export class RemoteFileDialog {
this.filePickBox.show();
this.contextKey.set(true);
await this.updateItems(homedir, false, this.trailing);
await this.updateItems(homedir, true, this.trailing);
if (this.trailing) {
this.filePickBox.valueSelection = [this.filePickBox.value.length - this.trailing.length, this.filePickBox.value.length - ext.length];
} else {
......@@ -350,21 +352,36 @@ export class RemoteFileDialog {
}
private async onDidAccept(): Promise<URI | undefined> {
let updateString: string;
let updateUri: URI;
this.filePickBox.busy = true;
if (this.filePickBox.activeItems.length === 1) {
updateUri = this.filePickBox.selectedItems[0].uri;
updateString = this.pathFromUri(updateUri);
const item = this.filePickBox.selectedItems[0];
if (item.isFolder) {
if (this.trailing) {
await this.updateItems(item.uri, true, this.trailing);
} else {
// When possible, cause the update to happen by modifying the input box.
// This allows all input box updates to happen first, and uses the same code path as the user typing.
const newPath = this.pathFromUri(item.uri);
if (startsWithIgnoreCase(newPath, this.filePickBox.value)) {
const insertValue = newPath.substring(this.filePickBox.value.length, newPath.length);
this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length];
this.insertText(newPath, insertValue);
} else if ((item.label === '..') && startsWithIgnoreCase(this.filePickBox.value, newPath)) {
this.filePickBox.valueSelection = [newPath.length, this.filePickBox.value.length];
this.insertText(newPath, '');
} else {
await this.updateItems(item.uri, true);
}
}
return;
}
} else {
updateString = this.filePickBox.value;
updateUri = this.filePickBoxValue();
}
// If the items have updated, don't try to resolve
if ((await this.tryUpdateItems(updateString, updateUri)) !== UpdateResult.NotUpdated) {
return;
// If the items have updated, don't try to resolve
if ((await this.tryUpdateItems(this.filePickBox.value, this.filePickBoxValue())) !== UpdateResult.NotUpdated) {
return;
}
}
this.filePickBox.busy = true;
let resolveValue: URI | undefined;
// Find resolve value
if (this.filePickBox.activeItems.length === 0) {
......@@ -384,10 +401,7 @@ export class RemoteFileDialog {
}
private async tryUpdateItems(value: string, valueUri: URI): Promise<UpdateResult> {
if (this.filePickBox.busy) {
this.badPath = undefined;
return UpdateResult.Updating;
} else if ((value.length > 0) && ((value[value.length - 1] === '~') || (value[0] === '~'))) {
if ((value.length > 0) && ((value[value.length - 1] === '~') || (value[0] === '~'))) {
let newDir = this.userHome;
if ((value[0] === '~') && (value.length > 1)) {
newDir = resources.joinPath(newDir, value.substring(1));
......@@ -636,7 +650,7 @@ export class RemoteFileDialog {
return uri;
} else {
const dir = resources.dirname(uri);
const base = resources.basename(uri) + this.labelService.getSeparator(uri.scheme, uri.authority);
const base = resources.basename(uri) + this.separator;
return resources.joinPath(dir, base);
}
}
......@@ -646,24 +660,16 @@ export class RemoteFileDialog {
this.userEnteredPathSegment = trailing ? trailing : '';
this.autoCompletePathSegment = '';
const newValue = trailing ? this.pathFromUri(resources.joinPath(newFolder, trailing)) : this.pathFromUri(newFolder, true);
const oldFolder = this.currentFolder;
const newFolderPath = this.pathFromUri(newFolder, true);
this.currentFolder = this.ensureTrailingSeparator(newFolder);
return this.createItems(this.currentFolder).then(items => {
this.filePickBox.items = items;
if (this.allowFolderSelection) {
this.filePickBox.activeItems = [];
}
if (!equalsIgnoreCase(this.filePickBox.value, newValue)) {
// the user might have continued typing while we were updating. Only update the input box if it doesn't match the directory.
if (!equalsIgnoreCase(this.filePickBox.value.substring(0, newValue.length), newValue)) {
this.filePickBox.valueSelection = [0, this.filePickBox.value.length];
this.insertText(newValue, newValue);
} else if (force || equalsIgnoreCase(this.pathFromUri(resources.dirname(oldFolder), true), newFolderPath)) {
// This is the case where the user went up one dir or is clicking on dirs. We need to make sure that we remove the final dir.
this.filePickBox.valueSelection = [newFolderPath.length, this.filePickBox.value.length];
this.insertText(newValue, '');
}
// the user might have continued typing while we were updating. Only update the input box if it doesn't match the directory.
if (!equalsIgnoreCase(this.filePickBox.value, newValue) && force) {
this.filePickBox.valueSelection = [0, this.filePickBox.value.length];
this.insertText(newValue, newValue);
}
if (force && trailing) {
// Keep the cursor position in front of the save as name.
......@@ -676,15 +682,14 @@ export class RemoteFileDialog {
}
private pathFromUri(uri: URI, endWithSeparator: boolean = false): string {
const sep = this.labelService.getSeparator(uri.scheme, uri.authority);
let result: string = uri.fsPath.replace(/\n/g, '');
if (sep === '/') {
result = result.replace(/\\/g, sep);
if (this.separator === '/') {
result = result.replace(/\\/g, this.separator);
} else {
result = result.replace(/\//g, sep);
result = result.replace(/\//g, this.separator);
}
if (endWithSeparator && !this.endsWithSlash(result)) {
result = result + sep;
result = result + this.separator;
}
return result;
}
......@@ -692,7 +697,7 @@ export class RemoteFileDialog {
private pathAppend(uri: URI, additional: string): string {
if ((additional === '..') || (additional === '.')) {
const basePath = this.pathFromUri(uri);
return basePath + (this.endsWithSlash(basePath) ? '' : this.labelService.getSeparator(uri.scheme, uri.authority)) + additional;
return basePath + (this.endsWithSlash(basePath) ? '' : this.separator) + additional;
} else {
return this.pathFromUri(resources.joinPath(uri, additional));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册