Merge branch 'master' into 74-integration-with-bookmarks-core-plugin
# Conflicts: # src/custom-sort/custom-sort.ts
This commit is contained in:
commit
726b3089b7
|
@ -55,6 +55,7 @@ export interface CustomSortGroup {
|
||||||
regexPrefix?: RegExpSpec
|
regexPrefix?: RegExpSpec
|
||||||
exactSuffix?: string
|
exactSuffix?: string
|
||||||
regexSuffix?: RegExpSpec
|
regexSuffix?: RegExpSpec
|
||||||
|
overrideTitle?: boolean // instead of title, use a derived text for sorting (e.g. regexp matching group).
|
||||||
order?: CustomSortOrder
|
order?: CustomSortOrder
|
||||||
byMetadataField?: string // for 'by-metadata:' sorting if the order is by metadata alphabetical or reverse
|
byMetadataField?: string // for 'by-metadata:' sorting if the order is by metadata alphabetical or reverse
|
||||||
secondaryOrder?: CustomSortOrder
|
secondaryOrder?: CustomSortOrder
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
DEFAULT_FOLDER_MTIME,
|
DEFAULT_FOLDER_MTIME,
|
||||||
determineFolderDatesIfNeeded,
|
determineFolderDatesIfNeeded,
|
||||||
determineSortingGroup,
|
determineSortingGroup,
|
||||||
|
EQUAL_OR_UNCOMPARABLE,
|
||||||
FolderItemForSorting,
|
FolderItemForSorting,
|
||||||
matchGroupRegex,
|
matchGroupRegex,
|
||||||
sorterByBookmarkOrder,
|
sorterByBookmarkOrder,
|
||||||
|
@ -225,7 +226,6 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0, // Matched!
|
groupIdx: 0, // Matched!
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: "00000123////Part123:-icle.md",
|
sortString: "00000123////Part123:-icle.md",
|
||||||
matchGroup: '00000123//',
|
|
||||||
ctime: MOCK_TIMESTAMP + 555,
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
mtime: MOCK_TIMESTAMP + 666,
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
path: 'Some parent folder/Part123:-icle.md'
|
path: 'Some parent folder/Part123:-icle.md'
|
||||||
|
@ -288,6 +288,36 @@ describe('determineSortingGroup', () => {
|
||||||
path: 'Some parent folder/Part:123-icle.md'
|
path: 'Some parent folder/Part:123-icle.md'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should match head and tail, when simple regexp in head and tail, overrideTitle', () => {
|
||||||
|
// given
|
||||||
|
const file: TFile = mockTFile('Part:123-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
||||||
|
const sortSpec: CustomSortSpec = {
|
||||||
|
targetFoldersPaths: ['Some parent folder'],
|
||||||
|
groups: [{
|
||||||
|
type: CustomSortGroupType.ExactHeadAndTail,
|
||||||
|
regexPrefix: {
|
||||||
|
regex: /^Part:\d/i
|
||||||
|
},
|
||||||
|
regexSuffix: {
|
||||||
|
regex: /\d-icle$/i
|
||||||
|
},
|
||||||
|
overrideTitle: true // Should be ignored when no advanced regexp
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = determineSortingGroup(file, sortSpec)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
groupIdx: 0, // Matched!
|
||||||
|
isFolder: false,
|
||||||
|
sortString: "Part:123-icle.md",
|
||||||
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
|
path: 'Some parent folder/Part:123-icle.md'
|
||||||
|
});
|
||||||
|
});
|
||||||
it('should match head and tail, when simple regexp in head and and mixed in tail', () => {
|
it('should match head and tail, when simple regexp in head and and mixed in tail', () => {
|
||||||
// given
|
// given
|
||||||
const file: TFile = mockTFile('Part:1 1-23.456-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
const file: TFile = mockTFile('Part:1 1-23.456-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
||||||
|
@ -313,7 +343,37 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0, // Matched!
|
groupIdx: 0, // Matched!
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: "00000001|00000023////Part:1 1-23.456-icle.md",
|
sortString: "00000001|00000023////Part:1 1-23.456-icle.md",
|
||||||
matchGroup: '00000001|00000023//',
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
|
path: 'Some parent folder/Part:1 1-23.456-icle.md'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should match head and tail, when simple regexp in head and and mixed in tail, with overrideTitle', () => {
|
||||||
|
// given
|
||||||
|
const file: TFile = mockTFile('Part:1 1-23.456-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
||||||
|
const sortSpec: CustomSortSpec = {
|
||||||
|
targetFoldersPaths: ['Some parent folder'],
|
||||||
|
groups: [{
|
||||||
|
type: CustomSortGroupType.ExactHeadAndTail,
|
||||||
|
regexPrefix: {
|
||||||
|
regex: /^Part:\d/i
|
||||||
|
},
|
||||||
|
regexSuffix: {
|
||||||
|
regex: / *(\d+(?:-\d+)*).\d\d\d-icle$/i,
|
||||||
|
normalizerFn: CompoundDashNumberNormalizerFn
|
||||||
|
},
|
||||||
|
overrideTitle: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = determineSortingGroup(file, sortSpec)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
groupIdx: 0, // Matched!
|
||||||
|
isFolder: false,
|
||||||
|
sortString: "00000001|00000023//",
|
||||||
ctime: MOCK_TIMESTAMP + 555,
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
mtime: MOCK_TIMESTAMP + 666,
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
path: 'Some parent folder/Part:1 1-23.456-icle.md'
|
path: 'Some parent folder/Part:1 1-23.456-icle.md'
|
||||||
|
@ -342,12 +402,74 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0, // Matched!
|
groupIdx: 0, // Matched!
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: "00000123////Part:123-icle.md",
|
sortString: "00000123////Part:123-icle.md",
|
||||||
matchGroup: '00000123//',
|
|
||||||
ctime: MOCK_TIMESTAMP + 555,
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
mtime: MOCK_TIMESTAMP + 666,
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
path: 'Some parent folder/Part:123-icle.md'
|
path: 'Some parent folder/Part:123-icle.md'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should match head and tail, when advanced regexp in both, head and tail', () => {
|
||||||
|
// given
|
||||||
|
const file: TFile = mockTFile('Part 555-6 123-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
||||||
|
const sortSpec: CustomSortSpec = {
|
||||||
|
targetFoldersPaths: ['Some parent folder'],
|
||||||
|
groups: [{
|
||||||
|
type: CustomSortGroupType.ExactHeadAndTail,
|
||||||
|
regexPrefix: {
|
||||||
|
regex: /^Part *(\d+(?:-\d+)*)/i,
|
||||||
|
normalizerFn: CompoundDashNumberNormalizerFn
|
||||||
|
},
|
||||||
|
regexSuffix: {
|
||||||
|
regex: / *(\d+(?:-\d+)*)-icle$/i,
|
||||||
|
normalizerFn: CompoundDashNumberNormalizerFn
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = determineSortingGroup(file, sortSpec)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
groupIdx: 0, // Matched!
|
||||||
|
isFolder: false,
|
||||||
|
sortString: "00000555|00000006//00000123////Part 555-6 123-icle.md",
|
||||||
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
|
path: 'Some parent folder/Part 555-6 123-icle.md'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should match head and tail, when advanced regexp in both, head and tail, with overrideTitle', () => {
|
||||||
|
// given
|
||||||
|
const file: TFile = mockTFile('Part 555-6 123-icle', 'md', 444, MOCK_TIMESTAMP + 555, MOCK_TIMESTAMP + 666);
|
||||||
|
const sortSpec: CustomSortSpec = {
|
||||||
|
targetFoldersPaths: ['Some parent folder'],
|
||||||
|
groups: [{
|
||||||
|
type: CustomSortGroupType.ExactHeadAndTail,
|
||||||
|
regexPrefix: {
|
||||||
|
regex: /^Part *(\d+(?:-\d+)*)/i,
|
||||||
|
normalizerFn: CompoundDashNumberNormalizerFn
|
||||||
|
},
|
||||||
|
regexSuffix: {
|
||||||
|
regex: / *(\d+(?:-\d+)*)-icle$/i,
|
||||||
|
normalizerFn: CompoundDashNumberNormalizerFn
|
||||||
|
},
|
||||||
|
overrideTitle: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = determineSortingGroup(file, sortSpec)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
groupIdx: 0, // Matched!
|
||||||
|
isFolder: false,
|
||||||
|
sortString: "00000555|00000006//00000123//",
|
||||||
|
ctime: MOCK_TIMESTAMP + 555,
|
||||||
|
mtime: MOCK_TIMESTAMP + 666,
|
||||||
|
path: 'Some parent folder/Part 555-6 123-icle.md'
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
describe('CustomSortGroupType.ExactPrefix', () => {
|
describe('CustomSortGroupType.ExactPrefix', () => {
|
||||||
it('should correctly recognize exact prefix', () => {
|
it('should correctly recognize exact prefix', () => {
|
||||||
|
@ -422,7 +544,6 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0,
|
groupIdx: 0,
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
||||||
matchGroup: "00000001|00000030|00000006|00001900//",
|
|
||||||
ctime: MOCK_TIMESTAMP + 222,
|
ctime: MOCK_TIMESTAMP + 222,
|
||||||
mtime: MOCK_TIMESTAMP + 333,
|
mtime: MOCK_TIMESTAMP + 333,
|
||||||
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
||||||
|
@ -525,7 +646,6 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0,
|
groupIdx: 0,
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
||||||
matchGroup: "00000001|00000030|00000006|00001900//",
|
|
||||||
ctime: MOCK_TIMESTAMP + 222,
|
ctime: MOCK_TIMESTAMP + 222,
|
||||||
mtime: MOCK_TIMESTAMP + 333,
|
mtime: MOCK_TIMESTAMP + 333,
|
||||||
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
||||||
|
@ -653,7 +773,6 @@ describe('determineSortingGroup', () => {
|
||||||
groupIdx: 0,
|
groupIdx: 0,
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
sortString: '00000001|00000030|00000006|00001900////Reference i.xxx.vi.mcm.md',
|
||||||
matchGroup: "00000001|00000030|00000006|00001900//",
|
|
||||||
ctime: MOCK_TIMESTAMP + 222,
|
ctime: MOCK_TIMESTAMP + 222,
|
||||||
mtime: MOCK_TIMESTAMP + 333,
|
mtime: MOCK_TIMESTAMP + 333,
|
||||||
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
path: 'Some parent folder/Reference i.xxx.vi.mcm.md'
|
||||||
|
@ -2198,7 +2317,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
expect(result1).toBe(SORT_FIRST_GOES_EARLIER)
|
expect(result1).toBe(SORT_FIRST_GOES_EARLIER)
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_LATER)
|
expect(result2).toBe(SORT_FIRST_GOES_LATER)
|
||||||
})
|
})
|
||||||
it('should correctly fallback to alphabetical if no metadata on both items', () => {
|
it('should refuse comparison if no metadata on both items', () => {
|
||||||
// given
|
// given
|
||||||
const itemA: Partial<FolderItemForSorting> = {
|
const itemA: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'ccc'
|
sortString: 'ccc'
|
||||||
|
@ -2214,9 +2333,9 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
const result3: number = sorter(itemB as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result3: number = sorter(itemB as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result1).toBe(SORT_FIRST_GOES_EARLIER)
|
expect(result1).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_LATER)
|
expect(result2).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
expect(result3).toBe(SORT_ITEMS_ARE_EQUAL)
|
expect(result3).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2280,7 +2399,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
expect(result1).toBe(SORT_FIRST_GOES_LATER)
|
expect(result1).toBe(SORT_FIRST_GOES_LATER)
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_EARLIER)
|
expect(result2).toBe(SORT_FIRST_GOES_EARLIER)
|
||||||
})
|
})
|
||||||
it('should correctly fallback to alphabetical reverse if no metadata on both items', () => {
|
it('should refrain from comparing if no metadata on both items', () => {
|
||||||
// given
|
// given
|
||||||
const itemA: Partial<FolderItemForSorting> = {
|
const itemA: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'ccc'
|
sortString: 'ccc'
|
||||||
|
@ -2296,9 +2415,9 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
const result3: number = sorter(itemB as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result3: number = sorter(itemB as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result1).toBe(SORT_FIRST_GOES_LATER)
|
expect(result1).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_EARLIER)
|
expect(result2).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
expect(result3).toBe(SORT_ITEMS_ARE_EQUAL)
|
expect(result3).toBe(EQUAL_OR_UNCOMPARABLE)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2311,9 +2430,9 @@ describe('sorterByMetadataField', () => {
|
||||||
[true,'mmm','mmm',1, 'e', 'd'],
|
[true,'mmm','mmm',1, 'e', 'd'],
|
||||||
[true,'abc',undefined,-1, 'a','a'],
|
[true,'abc',undefined,-1, 'a','a'],
|
||||||
[true,undefined,'klm',1, 'b','b'],
|
[true,undefined,'klm',1, 'b','b'],
|
||||||
[true,undefined,undefined,0, 'a','a'],
|
[true,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'a','a'],
|
||||||
[true,undefined,undefined,-1, 'a','b'],
|
[true,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'a','b'],
|
||||||
[true,undefined,undefined,1, 'd','c'],
|
[true,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'd','c'],
|
||||||
[false,'abc','def',1, 'a', 'a'],
|
[false,'abc','def',1, 'a', 'a'],
|
||||||
[false,'xyz','klm',-1, 'b', 'b'],
|
[false,'xyz','klm',-1, 'b', 'b'],
|
||||||
[false,'mmm','mmm',0, 'c', 'c'],
|
[false,'mmm','mmm',0, 'c', 'c'],
|
||||||
|
@ -2321,9 +2440,9 @@ describe('sorterByMetadataField', () => {
|
||||||
[false,'mmm','mmm',-1, 'e', 'd'],
|
[false,'mmm','mmm',-1, 'e', 'd'],
|
||||||
[false,'abc',undefined,1, 'a','a'],
|
[false,'abc',undefined,1, 'a','a'],
|
||||||
[false,undefined,'klm',-1, 'b','b'],
|
[false,undefined,'klm',-1, 'b','b'],
|
||||||
[false,undefined,undefined,0, 'a','a'],
|
[false,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'a','a'],
|
||||||
[false,undefined,undefined,1, 'a','b'],
|
[false,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'a','b'],
|
||||||
[false,undefined,undefined,-1, 'd','c'],
|
[false,undefined,undefined,EQUAL_OR_UNCOMPARABLE, 'd','c'],
|
||||||
|
|
||||||
])('straight order %s, comparing %s and %s should return %s for sortStrings %s and %s',
|
])('straight order %s, comparing %s and %s should return %s for sortStrings %s and %s',
|
||||||
(straight: boolean, metadataA: string|undefined, metadataB: string|undefined, order: number, sortStringA: string, sortStringB) => {
|
(straight: boolean, metadataA: string|undefined, metadataB: string|undefined, order: number, sortStringA: string, sortStringB) => {
|
||||||
|
|
|
@ -59,7 +59,6 @@ export interface FolderItemForSorting {
|
||||||
groupIdx?: number // the index itself represents order for groups
|
groupIdx?: number // the index itself represents order for groups
|
||||||
sortString: string // fragment (or full name) to be used for sorting
|
sortString: string // fragment (or full name) to be used for sorting
|
||||||
metadataFieldValue?: string // relevant to metadata-based sorting only
|
metadataFieldValue?: string // relevant to metadata-based sorting only
|
||||||
matchGroup?: string // advanced - used for secondary sorting rule, to recognize 'same regex match'
|
|
||||||
ctime: number // for a file ctime is obvious, for a folder = ctime of the oldest child file
|
ctime: number // for a file ctime is obvious, for a folder = ctime of the oldest child file
|
||||||
mtime: number // for a file mtime is obvious, for a folder = date of most recently modified child file
|
mtime: number // for a file mtime is obvious, for a folder = date of most recently modified child file
|
||||||
isFolder: boolean
|
isFolder: boolean
|
||||||
|
@ -77,6 +76,8 @@ const TrueAlphabetical: boolean = true
|
||||||
const ReverseOrder: boolean = true
|
const ReverseOrder: boolean = true
|
||||||
const StraightOrder: boolean = false
|
const StraightOrder: boolean = false
|
||||||
|
|
||||||
|
export const EQUAL_OR_UNCOMPARABLE: number = 0
|
||||||
|
|
||||||
export const sorterByMetadataField:(reverseOrder?: boolean, trueAlphabetical?: boolean) => SorterFn = (reverseOrder: boolean, trueAlphabetical?: boolean) => {
|
export const sorterByMetadataField:(reverseOrder?: boolean, trueAlphabetical?: boolean) => SorterFn = (reverseOrder: boolean, trueAlphabetical?: boolean) => {
|
||||||
const collatorCompareFn: CollatorCompareFn = trueAlphabetical ? CollatorTrueAlphabeticalCompare : CollatorCompare
|
const collatorCompareFn: CollatorCompareFn = trueAlphabetical ? CollatorTrueAlphabeticalCompare : CollatorCompare
|
||||||
return (a: FolderItemForSorting, b: FolderItemForSorting) => {
|
return (a: FolderItemForSorting, b: FolderItemForSorting) => {
|
||||||
|
@ -95,8 +96,8 @@ export const sorterByMetadataField:(reverseOrder?: boolean, trueAlphabetical?: b
|
||||||
// Item with metadata goes before the w/o metadata
|
// Item with metadata goes before the w/o metadata
|
||||||
if (a.metadataFieldValue) return -1
|
if (a.metadataFieldValue) return -1
|
||||||
if (b.metadataFieldValue) return 1
|
if (b.metadataFieldValue) return 1
|
||||||
// Fallback -> requested sort by metadata, yet none of two items contain it, use alphabetical by name
|
|
||||||
return collatorCompareFn(a.sortString, b.sortString)
|
return EQUAL_OR_UNCOMPARABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,19 +211,25 @@ function getComparator(sortSpec: CustomSortSpec, currentUIselectedSorting?: stri
|
||||||
if (itA.groupIdx != undefined && itB.groupIdx != undefined) {
|
if (itA.groupIdx != undefined && itB.groupIdx != undefined) {
|
||||||
if (itA.groupIdx === itB.groupIdx) {
|
if (itA.groupIdx === itB.groupIdx) {
|
||||||
const group: CustomSortGroup | undefined = sortSpec.groups[itA.groupIdx]
|
const group: CustomSortGroup | undefined = sortSpec.groups[itA.groupIdx]
|
||||||
const matchingGroupPresentOnBothSidesAndEqual: boolean = itA.matchGroup !== undefined && itA.matchGroup === itB.matchGroup
|
const primary: number = group?.order ? getSorterFnFor(group.order, currentUIselectedSorting)(itA, itB) : EQUAL_OR_UNCOMPARABLE
|
||||||
if (matchingGroupPresentOnBothSidesAndEqual && group.secondaryOrder) {
|
if (primary !== EQUAL_OR_UNCOMPARABLE) return primary
|
||||||
return getSorterFnFor(group.secondaryOrder ?? CustomSortOrder.default, currentUIselectedSorting)(itA, itB)
|
const secondary: number = group?.secondaryOrder ? getSorterFnFor(group.secondaryOrder, currentUIselectedSorting)(itA, itB) : EQUAL_OR_UNCOMPARABLE
|
||||||
} else {
|
if (secondary !== EQUAL_OR_UNCOMPARABLE) return secondary
|
||||||
return getSorterFnFor(group?.order ?? CustomSortOrder.default, currentUIselectedSorting)(itA, itB)
|
const folderLevel: number = sortSpec.defaultOrder ? getSorterFnFor(sortSpec.defaultOrder, currentUIselectedSorting)(itA, itB) : EQUAL_OR_UNCOMPARABLE
|
||||||
}
|
if (folderLevel !== EQUAL_OR_UNCOMPARABLE) return folderLevel
|
||||||
|
const uiSelected: number = currentUIselectedSorting ? getSorterFnFor(CustomSortOrder.standardObsidian, currentUIselectedSorting)(itA, itB) : EQUAL_OR_UNCOMPARABLE
|
||||||
|
if (uiSelected !== EQUAL_OR_UNCOMPARABLE) return uiSelected
|
||||||
|
const lastResort: number = getSorterFnFor(CustomSortOrder.default)(itA, itB)
|
||||||
|
return lastResort
|
||||||
} else {
|
} else {
|
||||||
return itA.groupIdx - itB.groupIdx;
|
return itA.groupIdx - itB.groupIdx;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// should never happen - groupIdx is not known for at least one of items to compare.
|
// should never happen - groupIdx is not known for at least one of items to compare.
|
||||||
// The logic of determining the index always sets some idx
|
// The logic of determining the index always sets some idx
|
||||||
// Yet for sanity and to satisfy TS code analyzer a fallback to default behavior below
|
// Yet for sanity and to satisfy TS code analyzer some valid behavior below
|
||||||
|
if (itA.groupIdx !== undefined) return -1
|
||||||
|
if (itB.groupIdx !== undefined) return 1
|
||||||
return getSorterFnFor(CustomSortOrder.default, currentUIselectedSorting)(itA, itB)
|
return getSorterFnFor(CustomSortOrder.default, currentUIselectedSorting)(itA, itB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +270,7 @@ export const matchGroupRegex = (theRegex: RegExpSpec, nameForMatching: string):
|
||||||
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec, ctx?: ProcessingContext): FolderItemForSorting {
|
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec, ctx?: ProcessingContext): FolderItemForSorting {
|
||||||
let groupIdx: number
|
let groupIdx: number
|
||||||
let determined: boolean = false
|
let determined: boolean = false
|
||||||
let matchedGroup: string | null | undefined
|
let derivedText: string | null | undefined
|
||||||
let bookmarkedIdx: number | undefined
|
let bookmarkedIdx: number | undefined
|
||||||
let metadataValueToSortBy: string | undefined
|
let metadataValueToSortBy: string | undefined
|
||||||
const aFolder: boolean = isFolder(entry)
|
const aFolder: boolean = isFolder(entry)
|
||||||
|
@ -275,8 +282,8 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
// than the actual full set of defined groups, because the outsiders group are not
|
// than the actual full set of defined groups, because the outsiders group are not
|
||||||
// in the ordered list (aka priorityOrder array)
|
// in the ordered list (aka priorityOrder array)
|
||||||
const numOfGroupsToCheck: number = spec.priorityOrder ? spec.priorityOrder.length : spec.groups.length
|
const numOfGroupsToCheck: number = spec.priorityOrder ? spec.priorityOrder.length : spec.groups.length
|
||||||
for (let idx = 0; idx < numOfGroupsToCheck; idx++) {
|
for (let idx = 0; idx < numOfGroupsToCheck && !determined; idx++) {
|
||||||
matchedGroup = null
|
derivedText = null
|
||||||
groupIdx = spec.priorityOrder ? spec.priorityOrder[idx] : idx
|
groupIdx = spec.priorityOrder ? spec.priorityOrder[idx] : idx
|
||||||
const group: CustomSortGroup = spec.groupsShadow ? spec.groupsShadow[groupIdx] : spec.groups[groupIdx];
|
const group: CustomSortGroup = spec.groupsShadow ? spec.groupsShadow[groupIdx] : spec.groups[groupIdx];
|
||||||
if (group.foldersOnly && aFile) continue;
|
if (group.foldersOnly && aFile) continue;
|
||||||
|
@ -289,7 +296,9 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
determined = true;
|
determined = true;
|
||||||
}
|
}
|
||||||
} else { // regexp is involved
|
} else { // regexp is involved
|
||||||
[determined, matchedGroup] = matchGroupRegex(group.regexPrefix!, nameForMatching)
|
const [matched, matchedGroup] = matchGroupRegex(group.regexPrefix!, nameForMatching)
|
||||||
|
determined = matched
|
||||||
|
derivedText = matchedGroup ?? derivedText
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CustomSortGroupType.ExactSuffix:
|
case CustomSortGroupType.ExactSuffix:
|
||||||
|
@ -298,7 +307,9 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
determined = true;
|
determined = true;
|
||||||
}
|
}
|
||||||
} else { // regexp is involved
|
} else { // regexp is involved
|
||||||
[determined, matchedGroup] = matchGroupRegex(group.regexSuffix!, nameForMatching)
|
const [matched, matchedGroup] = matchGroupRegex(group.regexSuffix!, nameForMatching)
|
||||||
|
determined = matched
|
||||||
|
derivedText = matchedGroup ?? derivedText
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CustomSortGroupType.ExactHeadAndTail:
|
case CustomSortGroupType.ExactHeadAndTail:
|
||||||
|
@ -311,13 +322,12 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
} else if (group.exactPrefix || group.exactSuffix) { // regexp is involved as the prefix or as the suffix (not both)
|
} else if (group.exactPrefix || group.exactSuffix) { // regexp is involved as the prefix or as the suffix (not both)
|
||||||
if ((group.exactPrefix && nameForMatching.startsWith(group.exactPrefix)) ||
|
if ((group.exactPrefix && nameForMatching.startsWith(group.exactPrefix)) ||
|
||||||
(group.exactSuffix && nameForMatching.endsWith(group.exactSuffix))) {
|
(group.exactSuffix && nameForMatching.endsWith(group.exactSuffix))) {
|
||||||
let fullMatch: string | undefined
|
const [matched, matchedGroup, fullMatch] = matchGroupRegex(group.exactPrefix ? group.regexSuffix! : group.regexPrefix!, nameForMatching)
|
||||||
[determined, matchedGroup, fullMatch] = matchGroupRegex(group.exactPrefix ? group.regexSuffix! : group.regexPrefix!, nameForMatching)
|
if (matched) {
|
||||||
if (determined) {
|
|
||||||
// check for overlapping of prefix and suffix match (not allowed)
|
// check for overlapping of prefix and suffix match (not allowed)
|
||||||
if ((fullMatch!.length + (group.exactPrefix?.length ?? 0) + (group.exactSuffix?.length ?? 0)) > nameForMatching.length) {
|
if ((fullMatch!.length + (group.exactPrefix?.length ?? 0) + (group.exactSuffix?.length ?? 0)) <= nameForMatching.length) {
|
||||||
determined = false
|
determined = true
|
||||||
matchedGroup = null // if it falls into Outsiders group, let it use title to sort
|
derivedText = matchedGroup ?? derivedText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +338,9 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
// check for overlapping of prefix and suffix match (not allowed)
|
// check for overlapping of prefix and suffix match (not allowed)
|
||||||
if ((fullMatchLeft!.length + fullMatchRight!.length) <= nameForMatching.length) {
|
if ((fullMatchLeft!.length + fullMatchRight!.length) <= nameForMatching.length) {
|
||||||
determined = true
|
determined = true
|
||||||
matchedGroup = matchedGroupLeft ?? matchedGroupRight
|
if (matchedGroupLeft || matchedGroupRight) {
|
||||||
|
derivedText = ((matchedGroupLeft || '') + (matchedGroupRight || '')) || derivedText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +351,11 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
determined = true;
|
determined = true;
|
||||||
}
|
}
|
||||||
} else { // regexp is involved
|
} else { // regexp is involved
|
||||||
[determined, matchedGroup] = matchGroupRegex(group.regexPrefix!, nameForMatching)
|
const [matched, matchedGroup] = matchGroupRegex(group.regexPrefix!, nameForMatching)
|
||||||
|
if (matched) {
|
||||||
|
determined = true
|
||||||
|
derivedText = matchedGroup ?? derivedText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case CustomSortGroupType.HasMetadataField:
|
case CustomSortGroupType.HasMetadataField:
|
||||||
|
@ -388,8 +404,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
determined = true;
|
determined = true;
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (determined) {
|
if (determined && derivedText) {
|
||||||
break; // No need to check other sorting groups
|
if (!group.overrideTitle) {
|
||||||
|
derivedText = derivedText + '//' + entry.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,9 +476,8 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
return {
|
return {
|
||||||
// idx of the matched group or idx of Outsiders group or the largest index (= groups count+1)
|
// idx of the matched group or idx of Outsiders group or the largest index (= groups count+1)
|
||||||
groupIdx: determinedGroupIdx,
|
groupIdx: determinedGroupIdx,
|
||||||
sortString: matchedGroup ? (matchedGroup + '//' + entry.name) : entry.name,
|
sortString: derivedText ?? entry.name,
|
||||||
metadataFieldValue: metadataValueToSortBy,
|
metadataFieldValue: metadataValueToSortBy,
|
||||||
matchGroup: matchedGroup ?? undefined,
|
|
||||||
isFolder: aFolder,
|
isFolder: aFolder,
|
||||||
folder: aFolder ? (entry as TFolder) : undefined,
|
folder: aFolder ? (entry as TFolder) : undefined,
|
||||||
path: entry.path,
|
path: entry.path,
|
||||||
|
|
Loading…
Reference in New Issue