Skip to content

Commit a2a808e

Browse files
committed
Two experimental features + version bump before release
- `aaa-z` and `a-zzz` sort orders (uppercase first, alphanumeric order and lowercase first, alphanumeric) - `vsc-unicode` sort order, which is equivalent to what VS Code refers to as 'unicode' sorting (which name is arbitrary and confusing, yet familar to VS Code users)
1 parent fe98a27 commit a2a808e

File tree

7 files changed

+127
-19
lines changed

7 files changed

+127
-19
lines changed

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "custom-sort",
33
"name": "Custom File Explorer sorting",
4-
"version": "2.1.4",
4+
"version": "2.1.5",
55
"minAppVersion": "0.16.2",
66
"description": "Allows for manual and automatic, config-driven reordering and sorting of files and folders in File Explorer",
77
"author": "SebastianMC",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "obsidian-custom-sort",
3-
"version": "2.1.4",
3+
"version": "2.1.5",
44
"description": "Custom Sort plugin for Obsidian (https://obsidian.md)",
55
"main": "main.js",
66
"scripts": {

src/custom-sort/custom-sort-types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ export enum CustomSortGroupType {
1313

1414
export enum CustomSortOrder {
1515
alphabetical = 1, // = 1 to allow: if (customSortOrder) { ...
16+
alphabeticalLowerFirst,
17+
alphabeticalUpperFirst,
1618
alphabeticalWithFileExt,
1719
trueAlphabetical,
1820
trueAlphabeticalWithFileExt,
1921
alphabeticalReverse,
22+
alphabeticalLowerFirstReverse,
23+
alphabeticalUpperFirstReverse,
2024
alphabeticalReverseWithFileExt,
2125
trueAlphabeticalReverse,
2226
trueAlphabeticalReverseWithFileExt,
@@ -38,7 +42,9 @@ export enum CustomSortOrder {
3842
fileFirst,
3943
folderFirst,
4044
alphabeticalWithFilesPreferred, // When the (base)names are equal, the file has precedence over a folder
41-
alphabeticalWithFoldersPreferred, // When the (base)names are equal, the file has precedence over a folder
45+
alphabeticalWithFoldersPreferred, // When the (base)names are equal, the file has precedence over a folder,
46+
vscUnicode, // the Visual Studio Code lexicographic order named 'unicode' (which is very misleading, at the same time familiar to VS Code users
47+
vscUnicodeReverse, // ... see compareFilesUnicode function https://github.com/microsoft/vscode/blob/a19b2d5fb0202e00fb930dc850d2695ec512e495/src/vs/base/common/comparers.ts#L80
4248
default = alphabeticalWithFilesPreferred
4349
}
4450

src/custom-sort/custom-sort.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ export const CollatorCompare = new Intl.Collator(undefined, {
4949
numeric: true,
5050
}).compare;
5151

52+
export const CollatorCompareUpperFirst = new Intl.Collator(undefined, {
53+
usage: "sort",
54+
sensitivity: "base",
55+
numeric: true,
56+
caseFirst: "upper"
57+
}).compare;
58+
59+
export const CollatorCompareLowerFirst = new Intl.Collator(undefined, {
60+
usage: "sort",
61+
sensitivity: "base",
62+
numeric: true,
63+
caseFirst: "lower"
64+
}).compare;
65+
5266
export const CollatorTrueAlphabeticalCompare = new Intl.Collator(undefined, {
5367
usage: "sort",
5468
sensitivity: "base",
@@ -178,32 +192,38 @@ const folderGoesFirstWhenSameBasenameAsFolder = (stringCompareResult: number, a:
178192
(!!stringCompareResult) ? stringCompareResult : (a.isFolder === b.isFolder ? EQUAL_OR_UNCOMPARABLE : (a.isFolder ? -1 : 1) );
179193

180194
const Sorters: { [key in CustomSortOrder]: SorterFn } = {
181-
[CustomSortOrder.alphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(a.sortString, b.sortString),
195+
[CustomSortOrder.alphabetical]: (a: FIFS, b: FIFS) => CollatorCompare(a.sortString, b.sortString),
196+
[CustomSortOrder.alphabeticalLowerFirst]: (a: FIFS, b: FIFS) => CollatorCompareLowerFirst(a.sortString, b.sortString),
197+
[CustomSortOrder.alphabeticalUpperFirst]: (a: FIFS, b: FIFS) => CollatorCompareUpperFirst(a.sortString, b.sortString),
182198
[CustomSortOrder.alphabeticalWithFilesPreferred]: (a: FIFS, b: FIFS) => fileGoesFirstWhenSameBasenameAsFolder(CollatorCompare(a.sortString, b.sortString),a,b),
183199
[CustomSortOrder.alphabeticalWithFoldersPreferred]: (a: FIFS, b: FIFS) => fileGoesFirstWhenSameBasenameAsFolder(CollatorCompare(a.sortString, b.sortString),a,b),
184-
[CustomSortOrder.alphabeticalWithFileExt]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(a.sortStringWithExt, b.sortStringWithExt),
185-
[CustomSortOrder.trueAlphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(a.sortString, b.sortString),
186-
[CustomSortOrder.trueAlphabeticalWithFileExt]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(a.sortStringWithExt, b.sortStringWithExt),
187-
[CustomSortOrder.alphabeticalReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(b.sortString, a.sortString),
188-
[CustomSortOrder.alphabeticalReverseWithFileExt]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(b.sortStringWithExt, a.sortStringWithExt),
189-
[CustomSortOrder.trueAlphabeticalReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(b.sortString, a.sortString),
190-
[CustomSortOrder.trueAlphabeticalReverseWithFileExt]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(b.sortStringWithExt, a.sortStringWithExt),
191-
[CustomSortOrder.byModifiedTime]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.mtime - b.mtime),
200+
[CustomSortOrder.alphabeticalWithFileExt]: (a: FIFS, b: FIFS) => CollatorCompare(a.sortStringWithExt, b.sortStringWithExt),
201+
[CustomSortOrder.trueAlphabetical]: (a: FIFS, b: FIFS) => CollatorTrueAlphabeticalCompare(a.sortString, b.sortString),
202+
[CustomSortOrder.trueAlphabeticalWithFileExt]: (a: FIFS, b: FIFS) => CollatorTrueAlphabeticalCompare(a.sortStringWithExt, b.sortStringWithExt),
203+
[CustomSortOrder.alphabeticalReverse]: (a: FIFS, b: FIFS) => CollatorCompare(b.sortString, a.sortString),
204+
[CustomSortOrder.alphabeticalLowerFirstReverse]: (a: FIFS, b: FIFS) => CollatorCompareLowerFirst(b.sortString, a.sortString),
205+
[CustomSortOrder.alphabeticalUpperFirstReverse]: (a: FIFS, b: FIFS) => CollatorCompareUpperFirst(b.sortString, a.sortString),
206+
[CustomSortOrder.alphabeticalReverseWithFileExt]: (a: FIFS, b: FIFS) => CollatorCompare(b.sortStringWithExt, a.sortStringWithExt),
207+
[CustomSortOrder.trueAlphabeticalReverse]: (a: FIFS, b: FIFS) => CollatorTrueAlphabeticalCompare(b.sortString, a.sortString),
208+
[CustomSortOrder.trueAlphabeticalReverseWithFileExt]: (a: FIFS, b: FIFS) => CollatorTrueAlphabeticalCompare(b.sortStringWithExt, a.sortStringWithExt),
209+
[CustomSortOrder.byModifiedTime]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.mtime - b.mtime),
192210
[CustomSortOrder.byModifiedTimeAdvanced]: sorterByFolderMDate(),
193-
[CustomSortOrder.byModifiedTimeReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.mtime - a.mtime),
211+
[CustomSortOrder.byModifiedTimeReverse]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.mtime - a.mtime),
194212
[CustomSortOrder.byModifiedTimeReverseAdvanced]: sorterByFolderMDate(true),
195-
[CustomSortOrder.byCreatedTime]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.ctime - b.ctime),
213+
[CustomSortOrder.byCreatedTime]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.ctime - b.ctime),
196214
[CustomSortOrder.byCreatedTimeAdvanced]: sorterByFolderCDate(),
197-
[CustomSortOrder.byCreatedTimeReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.ctime - a.ctime),
215+
[CustomSortOrder.byCreatedTimeReverse]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.ctime - a.ctime),
198216
[CustomSortOrder.byCreatedTimeReverseAdvanced]: sorterByFolderCDate(true),
199217
[CustomSortOrder.byMetadataFieldAlphabetical]: sorterByMetadataField(StraightOrder, !TrueAlphabetical, SortingLevelId.forPrimary),
200218
[CustomSortOrder.byMetadataFieldTrueAlphabetical]: sorterByMetadataField(StraightOrder, TrueAlphabetical, SortingLevelId.forPrimary),
201219
[CustomSortOrder.byMetadataFieldAlphabeticalReverse]: sorterByMetadataField(ReverseOrder, !TrueAlphabetical, SortingLevelId.forPrimary),
202220
[CustomSortOrder.byMetadataFieldTrueAlphabeticalReverse]: sorterByMetadataField(ReverseOrder, TrueAlphabetical, SortingLevelId.forPrimary),
203221
[CustomSortOrder.byBookmarkOrder]: sorterByBookmarkOrder(StraightOrder),
204222
[CustomSortOrder.byBookmarkOrderReverse]: sorterByBookmarkOrder(ReverseOrder),
205-
[CustomSortOrder.fileFirst]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder === b.isFolder) ? EQUAL_OR_UNCOMPARABLE : (a.isFolder ? 1 : -1),
206-
[CustomSortOrder.folderFirst]: (a: FolderItemForSorting, b: FolderItemForSorting) => (a.isFolder === b.isFolder) ? EQUAL_OR_UNCOMPARABLE : (a.isFolder ? -1 : 1),
223+
[CustomSortOrder.fileFirst]: (a: FIFS, b: FIFS) => (a.isFolder === b.isFolder) ? EQUAL_OR_UNCOMPARABLE : (a.isFolder ? 1 : -1),
224+
[CustomSortOrder.folderFirst]: (a: FIFS, b: FIFS) => (a.isFolder === b.isFolder) ? EQUAL_OR_UNCOMPARABLE : (a.isFolder ? -1 : 1),
225+
[CustomSortOrder.vscUnicode]: (a: FIFS, b: FIFS) => (a.sortString === b.sortString) ? EQUAL_OR_UNCOMPARABLE : (a.sortString < b.sortString ? -1 : 1),
226+
[CustomSortOrder.vscUnicodeReverse]: (a: FIFS, b: FIFS) => (a.sortString === b.sortString) ? EQUAL_OR_UNCOMPARABLE : (b.sortString < a.sortString ? -1 : 1),
207227

208228
// A fallback entry which should not be used - the getSorterFor() function below should protect against it
209229
[CustomSortOrder.standardObsidian]: (a: FIFS, b: FIFS) => CollatorCompare(a.sortString, b.sortString),

src/custom-sort/sorting-spec-processor.spec.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,84 @@ describe('SortingSpecProcessor', () => {
711711
})
712712
})
713713

714+
const txtInputExoticExperimentalSortAttr: string = `
715+
target-folder: upper first
716+
< aaa-z
717+
target-folder: upper first Rev
718+
> aaa-z
719+
target-folder: lower first
720+
< a-zzz
721+
target-folder: lower first Rev
722+
> a-zzz
723+
target-folder: VS Code unicode lexicographic
724+
< vsc-unicode
725+
target-folder: VS Code unicode lexicographic reverse
726+
> vsc-unicode
727+
`
728+
729+
const expectedSortSpecForExoticExperimentalSorting: { [key: string]: CustomSortSpec } = {
730+
"upper first": {
731+
defaultOrder: CustomSortOrder.alphabeticalUpperFirst,
732+
groups: [{
733+
type: CustomSortGroupType.Outsiders
734+
}],
735+
outsidersGroupIdx: 0,
736+
targetFoldersPaths: ['upper first']
737+
},
738+
"upper first Rev": {
739+
defaultOrder: CustomSortOrder.alphabeticalUpperFirstReverse,
740+
groups: [{
741+
type: CustomSortGroupType.Outsiders
742+
}],
743+
outsidersGroupIdx: 0,
744+
targetFoldersPaths: ['upper first Rev']
745+
},
746+
"lower first": {
747+
defaultOrder: CustomSortOrder.alphabeticalLowerFirst,
748+
groups: [{
749+
type: CustomSortGroupType.Outsiders
750+
}],
751+
outsidersGroupIdx: 0,
752+
targetFoldersPaths: ['lower first']
753+
},
754+
"lower first Rev": {
755+
defaultOrder: CustomSortOrder.alphabeticalLowerFirstReverse,
756+
groups: [{
757+
type: CustomSortGroupType.Outsiders
758+
}],
759+
outsidersGroupIdx: 0,
760+
targetFoldersPaths: ['lower first Rev']
761+
},
762+
"VS Code unicode lexicographic": {
763+
defaultOrder: CustomSortOrder.vscUnicode,
764+
groups: [{
765+
type: CustomSortGroupType.Outsiders
766+
}],
767+
outsidersGroupIdx: 0,
768+
targetFoldersPaths: ['VS Code unicode lexicographic']
769+
},
770+
"VS Code unicode lexicographic reverse": {
771+
defaultOrder: CustomSortOrder.vscUnicodeReverse,
772+
groups: [{
773+
type: CustomSortGroupType.Outsiders
774+
}],
775+
outsidersGroupIdx: 0,
776+
targetFoldersPaths: ['VS Code unicode lexicographic reverse']
777+
}
778+
}
779+
780+
describe('SortingSpecProcessor', () => {
781+
let processor: SortingSpecProcessor;
782+
beforeEach(() => {
783+
processor = new SortingSpecProcessor();
784+
});
785+
it('should recognize the exotic experimental sorting attribute for a folder', () => {
786+
const inputTxtArr: Array<string> = txtInputExoticExperimentalSortAttr.split('\n')
787+
const result = processor.parseSortSpecFromText(inputTxtArr, 'mock-folder', 'custom-name-note.md')
788+
expect(result?.sortSpecByPath).toEqual(expectedSortSpecForExoticExperimentalSorting)
789+
})
790+
})
791+
714792
const txtInputSimplistic1: string = `
715793
target-folder: /*
716794
/:files

src/custom-sort/sorting-spec-processor.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ const MAX_SORT_LEVEL: number = 1
116116

117117
// remember about .toLowerCase() before comparison!
118118
const OrderLiterals: { [key: string]: CustomSortOrderAscDescPair } = {
119+
'a-zzz': {asc: CustomSortOrder.alphabeticalLowerFirst, desc: CustomSortOrder.alphabeticalLowerFirstReverse},
119120
'a-z.': {asc: CustomSortOrder.alphabeticalWithFileExt, desc: CustomSortOrder.alphabeticalReverseWithFileExt},
120121
'a-z': {asc: CustomSortOrder.alphabetical, desc: CustomSortOrder.alphabeticalReverse},
122+
'aaa-z': {asc: CustomSortOrder.alphabeticalUpperFirst, desc: CustomSortOrder.alphabeticalUpperFirstReverse},
121123
'true a-z.': {asc: CustomSortOrder.trueAlphabeticalWithFileExt, desc: CustomSortOrder.trueAlphabeticalReverseWithFileExt},
122124
'true a-z': {asc: CustomSortOrder.trueAlphabetical, desc: CustomSortOrder.trueAlphabeticalReverse},
123125
'created': {asc: CustomSortOrder.byCreatedTime, desc: CustomSortOrder.byCreatedTimeReverse},
@@ -128,7 +130,8 @@ const OrderLiterals: { [key: string]: CustomSortOrderAscDescPair } = {
128130
'ui selected': {asc: CustomSortOrder.standardObsidian, desc: CustomSortOrder.standardObsidian},
129131
'by-bookmarks-order': {asc: CustomSortOrder.byBookmarkOrder, desc: CustomSortOrder.byBookmarkOrderReverse},
130132
'files-first': {asc: CustomSortOrder.fileFirst, desc: CustomSortOrder.fileFirst},
131-
'folders-first': {asc: CustomSortOrder.folderFirst, desc: CustomSortOrder.folderFirst}
133+
'folders-first': {asc: CustomSortOrder.folderFirst, desc: CustomSortOrder.folderFirst},
134+
'vsc-unicode': {asc: CustomSortOrder.vscUnicode, desc: CustomSortOrder.vscUnicodeReverse}
132135
}
133136

134137
const OrderByMetadataLexeme: string = 'by-metadata:'

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@
3838
"2.1.1": "0.16.2",
3939
"2.1.2": "0.16.2",
4040
"2.1.3": "0.16.2",
41-
"2.1.4": "0.16.2"
41+
"2.1.4": "0.16.2",
42+
"2.1.5": "0.16.2"
4243
}

0 commit comments

Comments
 (0)