提交 ef13c350 编写于 作者: A Alex Ross

Fix more remote file picker edge cases

Fixes #71963
上级 4cce7c07
......@@ -135,7 +135,7 @@ export class RemoteFileDialog {
private remoteUriFrom(path: string): URI {
path = path.replace(/\\/g, '/');
return URI.from({ scheme: this.scheme, authority: this.remoteAuthority, path });
return resources.toLocalResource(URI.from({ scheme: this.scheme, path }), this.remoteAuthority);
}
private getScheme(defaultUri: URI | undefined, available: string[] | undefined): string {
......@@ -188,6 +188,8 @@ export class RemoteFileDialog {
let isResolving = false;
let isAcceptHandled = false;
this.currentFolder = homedir;
this.userEnteredPathSegment = '';
this.autoCompletePathSegment = '';
this.filePickBox.buttons = [this.acceptButton];
this.filePickBox.onDidTriggerButton(_ => {
// accept button
......@@ -362,12 +364,12 @@ export class RemoteFileDialog {
} catch (e) {
// do nothing
}
if (stat && stat.isDirectory && (resources.basename(valueUri) !== '.')) {
if (stat && stat.isDirectory && (resources.basename(valueUri) !== '.') && this.endsWithSlash(value)) {
await this.updateItems(valueUri);
return true;
} else {
const inputUriDirname = resources.dirname(valueUri);
if (!resources.isEqual(this.currentFolder, inputUriDirname, true)) {
if (!resources.isEqual(this.remoteUriFrom(this.trimTrailingSlash(this.pathFromUri(this.currentFolder))), inputUriDirname, true)) {
let statWithoutTrailing: IFileStat | undefined;
try {
statWithoutTrailing = await this.fileService.resolve(inputUriDirname);
......@@ -386,8 +388,9 @@ export class RemoteFileDialog {
private setActiveItems(value: string) {
const inputBasename = resources.basename(this.remoteUriFrom(value));
if ((value !== this.constructFullUserPath().substring(0, value.length))
&& resources.isEqual(resources.dirname(this.remoteUriFrom(this.filePickBox.value)), this.currentFolder, true)) {
// Make sure that the folder whose children we are currently viewing matches the path in the input
const userPath = this.constructFullUserPath();
if (userPath === value.substring(0, userPath.length)) {
let hasMatch = false;
for (let i = 0; i < this.filePickBox.items.length; i++) {
const item = <FileQuickPickItem>this.filePickBox.items[i];
......@@ -402,40 +405,42 @@ export class RemoteFileDialog {
this.filePickBox.activeItems = [];
}
} else {
this.userEnteredPathSegment = inputBasename;
if (inputBasename !== resources.basename(this.currentFolder)) {
this.userEnteredPathSegment = inputBasename;
} else {
this.userEnteredPathSegment = '';
}
this.autoCompletePathSegment = '';
}
}
private setAutoComplete(startingValue: string, startingBasename: string, quickPickItem: FileQuickPickItem, force: boolean = false): boolean {
const itemBasename = (quickPickItem.label === '..') ? quickPickItem.label : resources.basename(quickPickItem.uri);
const itemPathLabel = (itemBasename === '..') ? this.pathAppend(this.currentFolder, itemBasename) : this.pathFromUri(quickPickItem.uri);
if (!equalsIgnoreCase(this.trimTrailingSlash(this.filePickBox.value), itemPathLabel)) {
// Either force the autocomplete, or the old value should be one smaller than the new value and match the new value.
if (!force && (itemBasename.length >= startingBasename.length + 1) && equalsIgnoreCase(itemBasename.substr(0, startingBasename.length), startingBasename)) {
this.userEnteredPathSegment = startingBasename;
this.activeItem = quickPickItem;
// Changing the active items will trigger the onDidActiveItemsChanged. Clear the autocomplete first, then set it after.
this.autoCompletePathSegment = '';
this.filePickBox.activeItems = [quickPickItem];
this.autoCompletePathSegment = itemBasename.substr(startingBasename.length);
this.insertText(startingValue + this.autoCompletePathSegment, this.autoCompletePathSegment);
this.filePickBox.valueSelection = [startingValue.length, this.filePickBox.value.length];
return true;
} else if (force && (quickPickItem.label !== (this.userEnteredPathSegment + this.autoCompletePathSegment))) {
this.userEnteredPathSegment = '';
this.autoCompletePathSegment = itemBasename;
this.activeItem = quickPickItem;
this.filePickBox.valueSelection = [this.pathFromUri(this.currentFolder, true).length, this.filePickBox.value.length];
// use insert text to preserve undo buffer
this.insertText(this.pathAppend(this.currentFolder, itemBasename), itemBasename);
this.filePickBox.valueSelection = [this.filePickBox.value.length - itemBasename.length, this.filePickBox.value.length];
return true;
}
// Either force the autocomplete, or the old value should be one smaller than the new value and match the new value.
if (!force && (itemBasename.length >= startingBasename.length) && equalsIgnoreCase(itemBasename.substr(0, startingBasename.length), startingBasename)) {
this.userEnteredPathSegment = startingBasename;
this.activeItem = quickPickItem;
// Changing the active items will trigger the onDidActiveItemsChanged. Clear the autocomplete first, then set it after.
this.autoCompletePathSegment = '';
this.filePickBox.activeItems = [quickPickItem];
this.autoCompletePathSegment = itemBasename.substr(startingBasename.length);
this.insertText(startingValue + this.autoCompletePathSegment, this.autoCompletePathSegment);
this.filePickBox.valueSelection = [startingValue.length, this.filePickBox.value.length];
return true;
} else if (force && (quickPickItem.label !== (this.userEnteredPathSegment + this.autoCompletePathSegment))) {
this.userEnteredPathSegment = '';
this.autoCompletePathSegment = itemBasename;
this.activeItem = quickPickItem;
this.filePickBox.valueSelection = [this.pathFromUri(this.currentFolder, true).length, this.filePickBox.value.length];
// use insert text to preserve undo buffer
this.insertText(this.pathAppend(this.currentFolder, itemBasename), itemBasename);
this.filePickBox.valueSelection = [this.filePickBox.value.length - itemBasename.length, this.filePickBox.value.length];
return true;
} else {
this.userEnteredPathSegment = startingBasename;
this.autoCompletePathSegment = '';
return false;
}
this.userEnteredPathSegment = startingBasename;
this.autoCompletePathSegment = '';
return false;
}
private insertText(wholeValue: string, insertText: string) {
......@@ -554,11 +559,11 @@ export class RemoteFileDialog {
}
private async updateItems(newFolder: URI, trailing?: string) {
this.currentFolder = newFolder;
this.userEnteredPathSegment = trailing ? trailing : '';
this.autoCompletePathSegment = '';
this.filePickBox.valueSelection = [0, this.filePickBox.value.length];
const newValue = trailing ? this.pathFromUri(resources.joinPath(newFolder, trailing)) : this.pathFromUri(newFolder, true);
this.currentFolder = this.remoteUriFrom(this.pathFromUri(newFolder, true));
this.insertText(newValue, newValue);
this.filePickBox.busy = true;
return this.createItems(this.currentFolder).then(items => {
......@@ -586,7 +591,8 @@ export class RemoteFileDialog {
private pathAppend(uri: URI, additional: string): string {
if ((additional === '..') || (additional === '.')) {
return this.pathFromUri(uri) + this.labelService.getSeparator(uri.scheme, uri.authority) + additional;
const basePath = this.pathFromUri(uri);
return basePath + (this.endsWithSlash(basePath) ? '' : this.labelService.getSeparator(uri.scheme, uri.authority)) + 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.
先完成此消息的编辑!
想要评论请 注册