未验证 提交 2f1c4b0f 编写于 作者: I Isidor Nikolic 提交者: GitHub

Merge pull request #104528 from relmify/compare-full-filenames

Compare full filenames
......@@ -33,8 +33,7 @@ const intlFileNameCollatorNumericCaseInsenstive: IdleValue<{ collator: Intl.Coll
return {
collator: collator
};
});
});/** Compares filenames without distinguishing the name from the extension. Disambiguates by unicode comparison. */
export function compareFileNames(one: string | null, other: string | null, caseSensitive = false): number {
const a = one || '';
const b = other || '';
......@@ -49,36 +48,16 @@ export function compareFileNames(one: string | null, other: string | null, caseS
return result;
}
/** Compares filenames by name then extension, sorting numbers numerically instead of alphabetically. */
export function compareFileNamesNumeric(one: string | null, other: string | null): number {
const [oneName, oneExtension] = extractNameAndExtension(one, true);
const [otherName, otherExtension] = extractNameAndExtension(other, true);
/** Compares filenames without distinguishing the name from the extension. Disambiguates by length, not unicode comparison. */
export function compareFileNamesDefault(one: string | null, other: string | null): number {
const collatorNumeric = intlFileNameCollatorNumeric.value.collator;
const collatorNumericCaseInsensitive = intlFileNameCollatorNumericCaseInsenstive.value.collator;
let result;
// Check for name differences, comparing numbers numerically instead of alphabetically.
result = compareAndDisambiguateByLength(collatorNumeric, oneName, otherName);
if (result !== 0) {
return result;
}
one = one || '';
other = other || '';
// Check for case insensitive extension differences, comparing numbers numerically instead of alphabetically.
result = compareAndDisambiguateByLength(collatorNumericCaseInsensitive, oneExtension, otherExtension);
if (result !== 0) {
return result;
}
// Disambiguate the extension case if needed.
if (oneExtension !== otherExtension) {
return collatorNumeric.compare(oneExtension, otherExtension);
}
return 0;
// Compare the entire filename - both name and extension - and disambiguate by length if needed
return compareAndDisambiguateByLength(collatorNumeric, one, other);
}
const FileNameMatch = /^(.*?)(\.([^.]*))?$/;
export function noIntlCompareFileNames(one: string | null, other: string | null, caseSensitive = false): number {
if (!caseSensitive) {
one = one && one.toLowerCase();
......@@ -123,10 +102,12 @@ export function compareFileExtensions(one: string | null, other: string | null):
return result;
}
/** Compares filenames by extenson, then by name. Sorts numbers numerically, not alphabetically. */
export function compareFileExtensionsNumeric(one: string | null, other: string | null): number {
const [oneName, oneExtension] = extractNameAndExtension(one, true);
const [otherName, otherExtension] = extractNameAndExtension(other, true);
/** Compares filenames by extenson, then by full filename */
export function compareFileExtensionsDefault(one: string | null, other: string | null): number {
one = one || '';
other = other || '';
const oneExtension = extractExtension(one);
const otherExtension = extractExtension(other);
const collatorNumeric = intlFileNameCollatorNumeric.value.collator;
const collatorNumericCaseInsensitive = intlFileNameCollatorNumericCaseInsenstive.value.collator;
let result;
......@@ -137,20 +118,12 @@ export function compareFileExtensionsNumeric(one: string | null, other: string |
return result;
}
// Compare names.
result = compareAndDisambiguateByLength(collatorNumeric, oneName, otherName);
if (result !== 0) {
return result;
}
// Disambiguate extension case if needed.
if (oneExtension !== otherExtension) {
return collatorNumeric.compare(oneExtension, otherExtension);
}
return 0;
// Compare full filenames
return compareAndDisambiguateByLength(collatorNumeric, one, other);
}
const FileNameMatch = /^(.*?)(\.([^.]*))?$/;
/** Extracts the name and extension from a full filename, with optional special handling for dotfiles */
function extractNameAndExtension(str?: string | null, dotfilesAsNames = false): [string, string] {
const match = str ? FileNameMatch.exec(str) as Array<string> : ([] as Array<string>);
......@@ -166,6 +139,13 @@ function extractNameAndExtension(str?: string | null, dotfilesAsNames = false):
return result;
}
/** Extracts the extension from a full filename. Treats dotfiles as names, not extensions. */
function extractExtension(str?: string | null): string {
const match = str ? FileNameMatch.exec(str) as Array<string> : ([] as Array<string>);
return (match && match[1] && match[1].charAt(0) !== '.' && match[3]) || '';
}
function compareAndDisambiguateByLength(collator: Intl.Collator, one: string, other: string) {
// Check for differences
let result = collator.compare(one, other);
......
......@@ -29,7 +29,7 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { equals, deepClone } from 'vs/base/common/objects';
import * as path from 'vs/base/common/path';
import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
import { compareFileExtensionsNumeric, compareFileNamesNumeric } from 'vs/base/common/comparers';
import { compareFileNamesDefault, compareFileExtensionsDefault } from 'vs/base/common/comparers';
import { fillResourceDataTransfers, CodeDataTransfers, extractResources, containsDragType } from 'vs/workbench/browser/dnd';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IDragAndDropData, DataTransfers } from 'vs/base/browser/dnd';
......@@ -665,7 +665,7 @@ export class FileSorter implements ITreeSorter<ExplorerItem> {
}
if (statA.isDirectory && statB.isDirectory) {
return compareFileNamesNumeric(statA.name, statB.name);
return compareFileNamesDefault(statA.name, statB.name);
}
break;
......@@ -699,17 +699,17 @@ export class FileSorter implements ITreeSorter<ExplorerItem> {
// Sort Files
switch (sortOrder) {
case 'type':
return compareFileExtensionsNumeric(statA.name, statB.name);
return compareFileExtensionsDefault(statA.name, statB.name);
case 'modified':
if (statA.mtime !== statB.mtime) {
return (statA.mtime && statB.mtime && statA.mtime < statB.mtime) ? 1 : -1;
}
return compareFileNamesNumeric(statA.name, statB.name);
return compareFileNamesDefault(statA.name, statB.name);
default: /* 'default', 'mixed', 'filesFirst' */
return compareFileNamesNumeric(statA.name, statB.name);
return compareFileNamesDefault(statA.name, statB.name);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册